Использование обобщений с AspectJ - PullRequest
0 голосов
/ 23 ноября 2011

Я экспериментирую с использованием AspectJ в коде моей команды, чтобы добавить отслеживание статистики, не мешая основной реализации, но сталкиваюсь с некоторыми проблемами.То, что я пытаюсь сделать, это окружить все вызовы метода на определенном интерфейсе, чтобы быть окруженным моей пользовательской логикой.В целях экспериментов я собрал некоторый код без использования обобщенных символов:

public interface Dummy {
    public void setState(String state);
    public String getState();
}
public class DummyImpl implements Dummy {
    private String state;
    public DummyImpl() { state = "default"; }
    public void setState(String state) { this.state = state; }
    public String getState() { return state; }

    public static void main(String[] args) {
        DummyImpl dummy = new DummyImpl();
        dummy.setState("One");
        dummy.setState("Another");
        dummy.setState("OneMore");
        System.out.printf("Current state is %s.\n", dummy.getState());
    }
}
public aspect BoundDummy {
    void around(Dummy d): execution(void Dummy.setState(String)) && target(d) {
        String oldState = d.getState();
        proceed(d);
        System.err.printf("State has changed from \"%s\" to \"%s\".\n", oldState, d.getState());
    }
}

Это дает желаемый эффект, дающий результат, аналогичный: Текущее состояние - OneMore.Состояние изменилось с «по умолчанию» на «Один».Состояние изменилось с «Один» на «Другой».Состояние изменилось с «Another» на «OneMore».

Теперь я пытаюсь представить обобщение, которое является простым для интерфейса и реализации, но оказывается более сложным для аспекта, так как я больше не могу использовать цель"и должен сделать это абстрактным (если я не получаю сообщение об ошибке:" Только абстрактные аспекты могут иметь параметры типа "):

public interface Dummy<T> {
    public void setState(T state);
    public T getState();
}
public class DummyImpl<T> implements Dummy<T> {
    private T state;
    public DummyImpl(T state) { this.state = state; }
    public void setState(T state) { this.state = state; }
    public T getState() { return state; }

    public static void main(String[] args) {
        DummyImpl<String> dummy = new DummyImpl<String>("default");
        dummy.setState("One");
        dummy.setState("Another");
        dummy.setState("OneMore");
        System.out.printf("Current state is %s.\n", dummy.getState());
    }
}
public abstract aspect BoundDummy<T> {
    void around(Dummy<T> d): execution(void Dummy.setState(T)) && target(d) { // <-- doesn't compile due to erasure
        T oldState = d.getState();
        proceed(d);
        System.err.printf("State has changed from \"%s\" to \"%s\".\n", oldState, d.getState());
    }
}

Есть ли что-то глупое, что я здесь делаю?Может кто-нибудь объяснить мне, что я должен изменить, чтобы заставить код функционировать так, как это было до введения дженериков?

1 Ответ

0 голосов
/ 23 ноября 2011

Ну, вы можете покончить с дженериками в своем аспекте. Компилятор выдает предупреждение, но все равно работает (я проверял):

public aspect BoundDummy {
    void around(Dummy d): execution(void Dummy.setState(*)) && target(d) {
        Object oldState = d.getState();
        proceed(d);
        System.err.printf("State has changed from \"%s\" to \"%s\".\n", oldState, d.getState());
    }
}
...