H__D  

一、参考资料  

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 }

  

 

posted on 2021-04-20 23:27  H__D  阅读(202)  评论(0编辑  收藏  举报