3.27 EnableAspectJAutoProxy的exposeProxy属性

戴着假发的程序员出品  抖音ID:戴着假发的程序员  欢迎关注

[查看视频教程]

前面我们以及解释完了AOP的所有配置和使用方式。

现在我们来看看下面的案例:

我们准备一个业务类:在业务类中我们有两个方法showMessage和formartMsg。我们再showMessage中调用formartMsg方法:

 1 /**
 2  * @author 戴着假发的程序员
 3  * 
 4  * @description
 5  */
 6 @Component
 7 public class MessageService {
 8     public String showMessage(String info) {
 9         System.out.println("OtherInfoServcie-showMessage展示信息:"+info);
10         this.formartMsg(info);
11         return null;
12     }
13     public String formartMsg(String info){
14         System.out.println("OtherInfoServcie-formartMsg对象消息"+info+"进行格式化");
15         return  info;
16     }
17 }

添加一个Aspect类,在其中增加一个前置通知:

 1 /**
 2  * @author 戴着假发的程序员
 3  * 
 4  * @description
 5  */
 6 @Component
 7 @Aspect
 8 public class DKAspect1 {
 9     @Pointcut("this(com.st.dk.demo8.service.MessageService)")
10     public void pointcut1(){}
11 
12     @Before("pointcut1()")
13     public void before(JoinPoint joinPoint){
14         System.out.println("前置通知,被增强的方法是:"+joinPoint.toString());
15     }
16 }

测试:

1 ApplicationContext ac =
2         new AnnotationConfigApplicationContext(AppConfig.class);
3 MessageService bean = ac.getBean(MessageService.class);
4 bean.showMessage("戴着假发的程序员");

结果:

3.27 EnableAspectJAutoProxy的exposeProxy属性

这是我们会发现,shwoMessage方法被拦截了,但是formartMsg方法并没有被拦截。

这是什么原因,其实spring官方已经给了明确的解释,解释的内容有点繁杂,我就不在这里截图。

我简答解释一下,就是我们使用AOP,必然会生成一个MessageService的代理对象。所以我们调用showMessage方法就是调用了代理对象的showMessage方法,必然会被增强,但是在shwoMessage中使用的this并非代理对象,而是我们的原生对象,所以this.formartMsg必然不会被增强。

如果解决呢?

方案1:

我们在我们的业务类中注入一个自己本身,然后把this替换为注入的对象,就可以解决问题。

3.27 EnableAspectJAutoProxy的exposeProxy属性

这种方式很显然,非常的不优雅。

所以spring 提供了其他的解决方案。

方案二:

修改EnableAspectJAutoProxy的属性exposeProxy为true,这是我们的代理对象接口会被暴漏在ThreadLocal中,我们就可以直接获取了。

1 @EnableAspectJAutoProxy(exposeProxy=true)

使用 方式:

 1 /**
 2  * @author 戴着假发的程序员
 3  * 
 4  * @description
 5  */
 6 @Component
 7 public class MessageService {
 8     public String showMessage(String info) {
 9         System.out.println("OtherInfoServcie-showMessage展示信息:"+info);
10         //使用AopContext的静态方法获取当前的代理对象
11         ((MessageService)AopContext.currentProxy()).formartMsg(info);
12         return null;
13     }
14     public String formartMsg(String info){
15         System.out.println("OtherInfoServcie-formartMsg对象消息"+info+"进行格式化");
16         return  info;
17     }
18 }

在测试:

3.27 EnableAspectJAutoProxy的exposeProxy属性

3.27 EnableAspectJAutoProxy的exposeProxy属性

上一篇:Request.ServerVariables["HTTP_SEC_FETCH_DEST"]


下一篇:打印报表工具,web报表工具对比