当前位置: 首页 > 分布式架构, 程序代码 > 正文

Spring AOP之AspectJ

目 录
 [ 隐藏 ]

1. Spring AOP实现方式 — 动态代理 

Spring AOP 可以有两种风格的 aop配置, 
a) 方式1: 
<aop:config proxy-target-class=”true”> 
    <!– other beans defined here… –> 
</aop:config> 
使用这种方式配置,xml中使用<aop:before>等手工配置比较繁琐 

b) 方式2:使用AspectJ的方式配置 
<aop:aspectj-autoproxy proxy-target-class=”true”/>,支持 @AspectJ 注解风格的配置 

Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。(建议优先使用JDK的动态代理) 
如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。 
若该目标对象没有实现任何接口,则创建一个CGLIB代理。 
如果你希望强制使用CGLIB代理,(例如:希望代理目标对象的所有方法,而不只是实现自接口的方法) 那也可以。 
但是需要考虑以下问题: 

  • 无法通知(advise)Final方法,因为他们不能被覆写。 
  • 你需要将CGLIB 2二进制发行包放在classpath下面,与之相较JDK本身就提供了动态代理。 
  • 当需要CGLIB而在classpath下又没有找到CGLIB类库的话,Spring会自动提醒。 
  • 代理对象的构造器会被调用两次。这是很自然的结果因为在CGLIB代理模式下每一个代理对象都会 产生一个子类。 
  • 每一个代理实例会生成两个对象:实际代理对象和它的一个实现了通知的子类实例 而是用JDK代理时不会出现这样的行为。 

通常情况下,调用代理类型的构造器两次并不是问题, 因为除了会发生指派外没有任何真正的逻辑被实现。 

强制使用CGLIB代理需要将<aop:config>的proxy-target-class 属性设为true: 

当使用@AspectJ自动代理时要强制使用CGLIB,请将<aop:aspectj-autoproxy> 的proxy-target-class属性设置为true: 
<aop:aspectj-autoproxy proxy-target-class=”true”/> 

以上两种方式都是使用动态代理的方式配置AOP的,这种方式的缺点: 
JDK使用动态代理时,被代理的对象必须至少实现了一个接口 
使用CGLIB创建动态代理时,因为CGLIB会在内存中自动创建一个被代理类的子类,实际上是一种继承机制,因此无法在使用final修饰的bean上应用横切关注点(final的bean无法被继承)。 
与此相似,在private, static和final方法上应用横切关注点也是无法做到的。 

2. 使用 AspectJ框架的 compiler/weaver 来代替Spring AOP或者作为它的补充, 使用加载时织入(Loading Time Wave)方法,完美实现AOP。 

2.1 依赖 

2.2 需要在 JVM的启动参数中配置

-javaagent:C:\Users\your_username\.m2\repository\org\springframework\spring-instrument\4.0.9.RELEASE\spring-instrument-4.0.9.RELEASE.jar 
以便在加载时织入AOP代码 

2.3 AspectJ AOP配置 

在classpath的META-INF/aop.xml, 
其中 waver中的 <include within=”foo.*”/>配置哪些类需要被织入AOP代码, 
aspects 中配置切面类,需要被@Aspect注解修饰,然后根据需要在方法中配置@Before,@After,@Around等增强处理器 

2.4 Spring配置文件:

参考: http://www.shouce.ren/api/spring2.5/ch06s08.html 

打个赏呗

   微信打赏  支付宝打赏


本文固定链接: https://www.jack-yin.com/coding/2663.html | 边城网事

该日志由 边城网事 于2017年12月17日发表在 分布式架构, 程序代码 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Spring AOP之AspectJ | 边城网事

Spring AOP之AspectJ 暂无评论

发表评论

快捷键:Ctrl+Enter