Точки соединения AspectJ рекомендуют только граничные выполнения и вызовы

1) Можно ли перехватывать выполнение (или, возможно, вызовы) в направлении (извне внутрь) набора классов (или, возможно, пакета, но не подпакетов) и внешних вызовов (из этих классов за пределами этой группы классов) , но не «внутренние» выполнения/вызовы (из любого класса этой группы в любой класс той же группы) с использованием только определений pointcut (т.е. без дополнительного кода Java внутри советов)? 2) Можно ли указать эту группу во внешнем файле для загрузки во время выполнения (Load Time Weaving)?

Я хочу написать инструмент для применения данного аспекта во время выполнения, но где разработчик может указать набор классов при запуске JVM (командная строка или текстовый файл).

Мне удалось реализовать пункт 1 с дополнительным кодом отражения Java в советах, но это не идеально (медленно), и я не уверен, что смогу загрузить имена классов/пакетов из внешнего файла и применить их с помощью AspectJ:

private static final String PACKAGE_REGEX = "com.advisethispackage..*";
private static final String BEFORE_EXECUTION_AND_NEW_INVOCATION_FILTER = "((execution(* *(..))) || (execution(*.new(..)))) && within(" + PACKAGE_REGEX + ")";
private static final String CALL_INVOCATION_FILTER = "((call(* *(..))) || (call(*.new(..)))) && within(" + PACKAGE_REGEX + ")";

Я пытался использовать внутренний код (который я, по-видимому, не очень понял) или исключить вызов таким образом...

private static final String CALL_INVOCATION_FILTER = "((call(* *(..))) || (call(*.new(..)))) && (!call(* " + WITHIN_REGEX + "(..))) && (!call(" + WITHIN_REGEX + ".new(..))) && within(" + WITHIN_REGEX + ")";

... но не удалось исключить некоторые вызовы одного класса. Любые идеи?

Мой файл aop.xml выглядит так:

<aspectj>
  <aspects>
    <aspect name="org.my.aspects.RecordingAspect"/>
    <include within="org..*"/>
  </aspects>

  <weaver options="-verbose -debug -showWeaveInfo">
    <include within="com.advisethispackage..*"/>
    <include within="org.my.aspects..*"/>
  </weaver>
</aspectj>

Я новичок в АОП и знаю только AspectJ и использовал только аннотации, а не компилятор AspectJ или AJDT. Я использую аспект j-1.8.6 с Java 8.


Пример: у меня есть 4 класса (A, B, C, D). A вызывает метод B, а C вызывает D. Классы B и C я хочу порекомендовать (com.advisethispackage.B, com.advisethispackage.C), но A и D нет (com.dontadvisethispackage.A). , com.dontadvisethispackage.D). Мой совет RecordingAspect просто распечатывает «Вызываемый метод для класса« X »или« Вызов метода из класса« X »в класс« Y »».

При записи я хочу вывести:

Invoked method on class 'B'
Invoking method from class 'C' to class 'D'

Ничего больше. Я также записываю моменты "после", которые напечатают...

Returning from invocation of method on class 'D' called by class 'C'
Returning from invocation of method on class 'B'

... но я полагаю, что определение pointcut должно быть таким же.

Спасибо


person Marco    schedule 12.09.2015    source источник


Ответы (1)


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

@Pointcut("call(* com.advisethispackage..*.*(..)) && !withincode(* com.advisethispackage..*.*(..))")
public void callFromOutsideToInside() {}

@Before("call(* (!com.advisethispackage..*).*(..)) && withincode(* com.advisethispackage..*.*(..))")
public void callFromInsideToOutside() {}

И если вы хотите также сопоставить конструкторы:

@Pointcut("call(com.advisethispackage..*.new(..)) && !withincode(* com.advisethispackage..*.*(..))")
public void callFromOutsideToInside() {}

@Before("call((!com.advisethispackage..*).new(..)) && withincode(* com.advisethispackage..*.*(..))")
public void callFromInsideToOutside() {}
person XGouchet    schedule 27.07.2016