跳到主要内容

AspectJ织入方法

本文相关代码(来自官方源码spring-test模块)请参见spring-framework org.springframework.mylearntest包下。

两种织入Aspect方法

假如我们有一个目标对象Foo,有两种方式将Aspect定义织入这个目标对象类,实现对其符合Pointcut定义的Joinpoint进行拦截。

Foo
public class Foo {
public void method1() {
System.out.println("method1 executed");
}

public void method2() {
System.out.println("method2 executed");
}
}

编程方式织入

通过AspectJProxyFactory实现
public class Test4AspectJProxyFactory {
public static void main(String[] args) {
AspectJProxyFactory weaver = new AspectJProxyFactory();
weaver.setProxyTargetClass(true);
weaver.setTarget(new Foo());
weaver.addAspect(PerformanceTraceAspect.class);
Object proxy = weaver.getProxy();
((Foo)proxy).method1();
((Foo)proxy).method2();
}
}

通过自动代理织入

针对@AspectJ风格的AOP,Spring AOP专门提供了一个AutoProxyCreator实现类进行自动代理,以免去过多的编码和配置工作,它是在AbstractAdvisorAutoProxyCreator基础上的一个扩展类。

与AutoProxyCreator一样,我们需要在IoC容器的配置文件中注册一下AnnotationAwareAspectJAutoProxyCreator就可以了。

xml 配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 等同于上面一行-->
<!--<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
<property name="proxyTargetClass" value="true"/>
</bean>-->

<bean id="performanceAspect" class="org.springframework.mylearntest.aop2.aspectj.PerformanceTraceAspect"/>

<bean id="target" class="org.springframework.mylearntest.aop2.aspectj.Foo"/>
</beans>
TestAutoAspectJ
public class Test4AutoAspectJ {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("annotationawareaspectJautoproxycreator\\annotationawareaspectJautoproxycreator.xml");
Object proxy = context.getBean("target");
((Foo)proxy).method1();
((Foo)proxy).method2();
}
}

如果把target作为依赖对象注入其他的bean定义,那么依赖的主体对象在持有的也是被代理过的目标对象。

Tip

在使用@AspectJ形式的AOP的时候,应该尽量使用容器内的自动代理支持,通常,只有处于测试目的才会使用编程的方式直接织入操作,在使用过程中,你会发现,实际上这两种方式是有差异的,一些行为并不统一。

使用@Aspect形式的AOP,需要引入aspectjweaver.jar和aspectjrt.jar。

协议
本作品代码部分采用Apache 2.0协议 进行许可。遵循许可的前提下,你可以自由地对代码进行修改,再发布,可以将代码用作商业用途。但要求你:
  • 署名:在原有代码和衍生代码中,保留原作者署名及代码来源信息。
  • 保留许可证:在原有代码和衍生代码中,保留Apache 2.0协议文件。
本作品文档部分采用知识共享署名 4.0 国际许可协议 进行许可。遵循许可的前提下,你可以自由地共享,包括在任何媒介上以任何形式复制、发行本作品,亦可以自由地演绎、修改、转换或以本作品为基础进行二次创作。但要求你:
  • 署名:应在使用本文档的全部或部分内容时候,注明原作者及来源信息。
  • 非商业性使用:不得用于商业出版或其他任何带有商业性质的行为。如需商业使用,请联系作者。
  • 相同方式共享的条件:在本文档基础上演绎、修改的作品,应当继续以知识共享署名 4.0国际许可协议进行许可。