Ответ Nándor правильный, поскольку он описывает ошибку компилятора, которую вы видите. Я хочу пойти немного дальше, а также объяснить, почему вы получите эту ошибку:
Прежде всего, эта проблема напрямую не связанную с AspectJ, а скорее как Java реализует дженерики. Перед тем, как продолжить чтение, ознакомьтесь с феноменом type erasure.
Ну, потому что тип стирание является JVM реальность и потому target()
и this()
разрешается во время выполнения, а не во время компиляции - вы можете косвенно заключить это из-за того, что оба getTarget()
и getThis()
являются методами JoinPoint
, а не JoinPoint.StaticPart
- то, что вы хотите сделать, не может работать и, следовательно, приводит к ошибке компилятора AspectJ. Единственное, что вы можете сделать, это использовать instanceof
, чтобы динамически определять, что добавляется в целевой список. Самый изящный способ сделать это - выражение pointcut.
Вот некоторые примеры кода:
Драйвер приложения:
Так, чтобы сделать вещи немного более интересным, мы используем два типа списков, а также два типа add(..)
вызовов. Цель должна заключаться в том, чтобы только перехватывать целые числа, которые должны быть добавлены в соответствующий список, независимо от того, какая подпись имеет метод add(..)
.
package de.scrum_master.app;
import java.util.ArrayList;
import java.util.List;
public class Application {
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>();
integers.add(11);
integers.add(0, 22);
integers.add(33);
List<String> strings = new ArrayList<>();
strings.add("foo");
strings.add(0, "bar");
strings.add("zot");
}
}
Формат:
package de.scrum_master.aspect;
import java.util.List;
@SuppressWarnings({"rawtypes", "unchecked"})
public aspect GenericsAspect {
pointcut addPointCut(List list, Object newElement) :
!within(GenericsAspect) && // avoid stack overflow due to recursion
call(* List.add(..)) && // intercept all calls to List.add
args(.., newElement) && // capture last method parameter
if(newElement instanceof Integer) && // only capture added int/Integer elements
target(list); // target is a List
before(List list, Object newElement) :
addPointCut(list, newElement)
{
System.out.println(thisJoinPoint + " -> new element = " + newElement);
for(Object i : list)
System.out.println(" " + i);
// Type erasure in action:
// During runtime there is no such thing as List<Integer>, only a raw List.
// Thus, we can easily add a String to a list declared as List<Integer>.
list.add("#" + newElement + "#");
}
}
консоли журнала:
call(boolean java.util.List.add(Object)) -> new element = 11
call(void java.util.List.add(int, Object)) -> new element = 22
#11#
11
call(boolean java.util.List.add(Object)) -> new element = 33
22
#11#
11
#22#
Любые дополнительные вопросы?