与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
<aop:aspectj-autoproxy proxy-target-class="true" ></aop:aspectj-autoproxy> 设置spring aop代理的方式 。当proxy-target-class="true"时就是cglib代理模式(类代理) ,当proxy-target-class="true"时就是jdk的代理模式(接口代理)
@EnableAspectJAutoProxy(proxyTargetClass = true)(注解的方式)
可以强制的将spring aop代理模式写成cglib的代理模式(类代理)
踩坑点:Spring AOP不支持代理类内部方法调用的拦截,比如类中a方法调用b方法,切面拦截b方法会失败的
AspectJ在编译时就增强了目标对象,Spring AOP的动态代理则是在每次运行时动态的增强,生成AOP代理对象,区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理
网友评论