经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
解决SpringAop内部调用时不经过代理类的问题
来源:jb51  时间:2022/1/3 12:31:22  对本文有异议

SpringAop

AOP代理织入时期

  • 编译时织入 - aspectj框架
  • 类加载时织入 - aspectj框架
  • 运行时织入 - spring-aop

动态代理方式

  • JDK - 被代理对象必须需要实现接口
  • CGLIB - 采用继承被代理对象方式实现代理功能

解决SpringAop内部调用时不经过代理类(而是通过this)

方案一

通过编译时织入或者类加载时织入代码

方案二

通过当前代理类调用目标方法

getOne()方法中直接调用getAll()时是通过this对象,这时候getAll()方法上的@AopLog就不会被AOP扫描到

  1. @Service
  2. @Slf4j
  3. public class ServiceImpl implements IService {
  4. ? ? @Override
  5. ? ? @AopLog("value=getOne")
  6. ? ? public void getOne() {
  7. ? ? ? ? log.info("getOne running");
  8. ? ? ? ? // 直接调用getAll()方法 = this.getAll()
  9. ? ? ? ? getAll();
  10. ? ? }
  11. ? ? @Override
  12. ? ? @AopLog("value=getAll")
  13. ? ? public void getAll() {
  14. ? ? ? ? log.info("getAll running");
  15. ? ? }
  16. }

修改getOne()方法,通过AopContext.currentProxy()方法获取当前代理类,通过代理类来调用getAll()方法,这时候就是通过代理类调用的

  1. @Service
  2. @Slf4j
  3. public class ServiceImpl implements IService {
  4. ? ? @Override
  5. ? ? @AopLog("value=getOne")
  6. ? ? public void getOne() {
  7. ? ? ? ? log.info("getOne running");
  8. ? ? ? ? // 获取当前代理类,通过代理类来调用getAll()方法
  9. ? ? ? ? ((IService) AopContext.currentProxy()).getAll();
  10. ? ? }
  11. ? ? @Override
  12. ? ? @AopLog("value=getAll")
  13. ? ? public void getAll() {
  14. ? ? ? ? log.info("getAll running");
  15. ? ? }
  16. ? ? @AopLog("value=getById")
  17. ? ? private void getById() {
  18. ? ? ? ? log.info("getById running");
  19. ? ? }
  20. }

this使得SpringAop失效之谜

问题描述

类Demo被AOP扫描到,其中有A和B两个方法,A方法中调用了B方法,执行A方法时,B方法的代理没有生效

问题剖析

我们知道AOP底层使用JDK动态代理和cglib动态代理想结合,通过判断去创建对应的代理对象。

而不管是那种方法,最终执行完代理后,都会执行目标方法:method.invoke(target,agrs)-->传入目标对象

所以执行A方法的代理后,执行A的目标方法,此时执行的对象是目标对象,所以目标对象执行A方法是A中隐藏的this

指的就是目标对象,即执行B方法的不再是代理对象而是目标对象,故B方法不会被代理

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号