一、参考资料
0、Spring AOP系列
https://www.jianshu.com/u/51eae3937c54?order_by=top
1、Spring AOP (一) 简介
https://www.jianshu.com/p/7f4f2429552f
2、Spring AOP (二) JDK 动态代理
https://www.jianshu.com/p/9d5557b5c8d0
3、Spring AOP (三) CGLIB 动态代理
https://www.jianshu.com/p/7700a48811e0
4、Spring AOP (四) 多重代理和责任链模式
https://www.jianshu.com/p/36508cd6decd
5、Spring AOP(五)切入点和通知
https://www.jianshu.com/p/602906fa4742
6、Spring AOP(六)细究 JdkDynamicAopProxy 类
https://www.jianshu.com/p/df6bd74db9c5#comments
代理模式参考:【设计模式】代理模式
二、AOP 的使用
使用xml配置AOP参考:【Java】Spring之面向方面编程(AOP)(五)
使用注解配置AOP参考:【Spring】基于@Aspect的AOP配置
三、AOP的图
1、AOP有关的类图
2、AOP 图
四、@EnableAspectJAutoProxy 注解
1、源码
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Import(AspectJAutoProxyRegistrar.class) 5 public @interface EnableAspectJAutoProxy { 6 7 /** 8 * 是否是代理目标类,这个属性为true时,目标类本身被代理而不是目标类的接口 9 * true 的话使用CGLIB代理, 10 * false 的话使用JDK的动态代理,默认为false 11 */ 12 boolean proxyTargetClass() default false; 13 14 /** 15 16 /** 17 * 解决内部调用不能使用代理的场景 默认为false表示不处理 18 * true则表示这个代理对象的副本就可以通过AopContext.currentProxy()获得(ThreadLocal里面), 19 * 从而我们可以很方便得在Spring框架上下文中拿到当前代理对象(处理事务时很方便) 20 */ 21 boolean exposeProxy() default false; 22 23 }
2、 配置强制使用cglib代理,在注解中添加属性proxyTargetClass = true,如下:
@EnableAspectJAutoProxy(proxyTargetClass = true)
3、内部调用不能拦截问题(exposeProxy暴露代理对象),配置 exposeProxy=true,如下:
@EnableAspectJAutoProxy(exposeProxy = true)
- 使用如下:
1 public class Target implements TargetInterface { 2 3 4 /** 5 * AopContext.currentProxy(); 获取线程中的代理对象, 6 * 需要@EnableAspectJAutoProxy(exposeProxy = true) 7 */ 8 @Override 9 public void targetMethod() { 10 System.out.println("---Target#targetMethod()---"); 11 Object o = AopContext.currentProxy(); 12 if(o instanceof TargetInterface) { 13 // 此处能获得代理,继续调用内部方法 14 // 调用内部方法也会被拦截 15 TargetInterface proxy = (TargetInterface)o; 16 proxy.targetMethod2(); 17 } 18 } 19 20 @Override 21 public void targetMethod2() { 22 System.out.println("---Target#targetMethod2()---"); 23 } 24 }