Я экспериментирую с использованием 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());
}
}
Есть ли что-то глупое, что я здесь делаю?Может кто-нибудь объяснить мне, что я должен изменить, чтобы заставить код функционировать так, как это было до введения дженериков?