Aspectj: метод перехвата из внешней банки
Я использую X.jar и добавляю к моему проекту AspectJ (в eclipse). Я написал pointcut и совет для метода myMethod() внутри X.jar.
Но aspectj не перехватывает вызов этого метода.
Как я могу передать aspectj для перехвата вызовов метода на внешних баночках. Или это невозможно?
Спасибо
Ответы
Ответ 1
Есть два варианта:
a) скомпилируйте аспекты в JAR
б) использовать время загрузки во времени (я бы пошел с этим)
Оба эти являются расширенными темами, я бы предложил вам прочитать AspectJ в действии (2-е изд.) Рамниваса Лэддада, чтобы узнать больше.
Чтобы уточнить: существуют различные типы pointcut. Если ваш код вызывает методы библиотеки, вы можете, конечно, перехватить эти вызовы, как это происходит в вашем коде. Таким образом, pointtuts call()
будут работать, но execute()
(и многие другие) pointcut не будут, потому что они меняют метод выполнения, который не находится в вашей базе кода. Поэтому вам нужно либо изменить байтовый код библиотеки (опция a), либо изменить способ ее загрузки в ваше приложение (вариант b).
Ответ 2
Вот простой пример с AspectJ Load-Time Weaving на GitHub https://github.com/medvedev1088/aspectj-ltw-example
Он использует библиотеку времени Joda, чтобы продемонстрировать, как перехватить вызовы метода DateTime # toString().
Аспект:
@Aspect
public class DateTimeToStringAspect {
public static final String TO_STRING_RESULT = "test";
@Pointcut("execution(* org.joda.time.base.AbstractDateTime.toString())")
public void dateTimeToString() {
}
@Around("dateTimeToString()")
public Object toLowerCase(ProceedingJoinPoint joinPoint) throws Throwable {
Object ignoredToStringResult = joinPoint.proceed();
System.out.println("DateTime#toString() has been invoked: " + ignoredToStringResult);
return TO_STRING_RESULT;
}
}
aop.xml
<aspectj>
<aspects>
<!-- Aspects -->
<aspect name="com.example.aspectj.DateTimeToStringAspect"/>
</aspects>
<weaver options="-verbose -showWeaveInfo">
<include within="org.joda.time.base.AbstractDateTime"/>
</weaver>
</aspectj>
Тест:
public class DateTimeToStringAspectTest {
@Test
public void testDateTimeToString() throws Exception {
assertThat(new DateTime().toString(), is(DateTimeToStringAspect.TO_STRING_RESULT));
}
}
Конфигурация плагина Surefire из pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>-XX:-UseSplitVerifier</argLine>
<argLine>-javaagent:${user.home}/.m2/repository/org/aspectj/aspectjweaver/${aspectjweaver.version}/aspectjweaver-${aspectjweaver.version}.jar</argLine>
</configuration>
</plugin>