我正在使用 X.jar 并添加到我的 AspectJ 项目(在 Eclipse 中)。我已经为 X.jar 中的 myMethod() 方法编写了切入点和建议。
但是 aspectj 并没有拦截这个方法调用。
我怎样才能告诉aspectj拦截外部罐子上的方法调用。或者不可能吗?
谢谢
我正在使用 X.jar 并添加到我的 AspectJ 项目(在 Eclipse 中)。我已经为 X.jar 中的 myMethod() 方法编写了切入点和建议。
但是 aspectj 并没有拦截这个方法调用。
我怎样才能告诉aspectj拦截外部罐子上的方法调用。或者不可能吗?
谢谢
有两种选择:
a) 将方面编译到 JAR
b) 使用加载时间编织(我会使用那个)
这两个都是高级主题,我建议您阅读Ramnivas Laddad 的 AspectJ in Action (2nd Ed)以了解更多信息。
澄清一下:有不同类型的切入点。如果您的代码调用库的方法,您当然可以拦截这些调用,因为它们发生在您的代码中。所以call()
切入点会起作用,但是execute()
(和许多其他的)切入点不会,因为它们会改变执行方法,这不在您的代码库中。因此,您必须更改库的字节码(选项 a)或更改将其加载到应用程序中的方式(选项 b)。
这是 GitHub 上 AspectJ Load-Time Weaving 的简单示例https://github.com/medvedev1088/aspectj-ltw-example
它使用 Joda Time 库来演示如何拦截 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));
}
}
来自 pom.xml 的 Surefire 插件配置:
<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>