当前位置:首页 > 科技  > 软件

严重!Spring AOP Bug导致切面重复执行

来源: 责编: 时间:2024-06-11 17:52:52 40观看
导读环境:Spring6.1.71. 问题复现为了提高代码的复用性和维护性,我们设计了一个通用的抽象的切面父类。这个父类封装了通用的切面逻辑,如日志记录、性能监控、异常处理等。通过继承这个抽象父类,具体的业务切面可以轻松地扩展

环境:Spring6.1.7JxJ28资讯网——每日最新资讯28at.com

1. 问题复现

为了提高代码的复用性和维护性,我们设计了一个通用的抽象的切面父类。这个父类封装了通用的切面逻辑,如日志记录、性能监控、异常处理等。通过继承这个抽象父类,具体的业务切面可以轻松地扩展或定制这些通用功能,而无需从零开始编写切面逻辑。如下示例:JxJ28资讯网——每日最新资讯28at.com

public abstract class CommonAspect {  @Pointcut("execution(public * com.pack..*.*(..))")  private void commonPointcut() {}  @Before("bean(*Service)")  protected void beforeLog(JoinPoint jp) {    System.out.println("通用日志记录...") ;  }  @Around("@annotation(monitor)")  protected Object monitorRun(ProceedingJoinPoint pjp, Monitor monitor) throws Throwable {    Object ret = null ;    // TODO    ret = pjp.proceed() ;    // TODO    return ret ;  }  // other}

具体切面子类

@Component@Aspectpublic class LogAspect extends CommonAspect {  @Override  public void beforeLog(JoinPoint jp) {    System.out.println("重写日志记录功能") ;  }}

当项目运行时出现诡异的问题,既然打印了2次日志信息。JxJ28资讯网——每日最新资讯28at.com

// 测试代码AnnotationConfigApplicationContext context = ... ;PersonService ps = context.getBean(PersonService.class) ;ps.queryById(1L) ;

执行结果

重写日志记录功能重写日志记录功能查询Person对象

虽然执行了我们重写的方法,但是日志确输出了2遍。JxJ28资讯网——每日最新资讯28at.com

通过debug分析

容器在启动初始化解析@Aspect切面时,在获取切面类中的所有方法时,会得到两个方法(父类及子类重写的)JxJ28资讯网——每日最新资讯28at.com

图片图片JxJ28资讯网——每日最新资讯28at.com

在这里的getAdvisorMethods方法返回了3个方法,其中2个是父类中的一个是子类重写的方法JxJ28资讯网——每日最新资讯28at.com

图片图片JxJ28资讯网——每日最新资讯28at.com

那么接下来根据这2个方法就会生成对应的Advisor对象。JxJ28资讯网——每日最新资讯28at.com

图片图片JxJ28资讯网——每日最新资讯28at.com

这也就是为什么重复的原因了。Spring并没有判断我当前的这个通知是否是重写父类的方法。JxJ28资讯网——每日最新资讯28at.com

注:在Spring中@Aspect定义的切面最终都会转换为Advisor对象,当代理类在执行时会遍历所有符合添加的Advisor然后从中取出对应的Advice(MethodInterceptor)对象。JxJ28资讯网——每日最新资讯28at.com

既然知道了问题出现的原因,接下来就进行解决该问题。JxJ28资讯网——每日最新资讯28at.com

2. 解决问题

2.1 解决办法1

我们可以在子类重写的方法上再加上通知类型,将切入点设置的不匹配任何方法即可JxJ28资讯网——每日最新资讯28at.com

@Before("execution(public * xxxooo())")@Overridepublic void beforeLog(JoinPoint jp) {  System.out.println("重写日志记录功能") ;}

在这里重写的方法上,将切入点重新写,该切入点不会匹配任何的方法,这样修改以后再次执行JxJ28资讯网——每日最新资讯28at.com

重写日志记录功能查询Person对象

正常执行,没有重复输出日志。JxJ28资讯网——每日最新资讯28at.com

2.2 解决办法2

该方法需要将Spring版本升级到6.1.8,在该版本中解决了该问题。来看看在该版本中是如何解决的。JxJ28资讯网——每日最新资讯28at.com

6.1.8版本

核心方法还是在上面debug是看到的getAdvisors方法中JxJ28资讯网——每日最新资讯28at.com

public class ReflectiveAspectJAdvisorFactory {  public List<Advisor> getAdvisors(...) {    List<Advisor> advisors = new ArrayList<>();    for (Method method : getAdvisorMethods(aspectClass)) {      // 在这里加入了判断(当前方法是否与当前切面中的方法相同)      // 当遍历到这里的Method是父类中的方法时,这里的getMostSpecificMethod      // 方法就会判断根据方法的名称再从当前切面类中获取方法(那当然就不同了)      if (method.equals(ClassUtils.getMostSpecificMethod(method, aspectClass))) {        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);        if (advisor != null) {          advisors.add(advisor);        }      }    }  }}

图片图片JxJ28资讯网——每日最新资讯28at.com

在6.1.8版本中通过这种方式就排除了父类的方法。JxJ28资讯网——每日最新资讯28at.com

其它版本

图片图片JxJ28资讯网——每日最新资讯28at.com

低于6.1.8版本,都没有相应的判断。JxJ28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-93092-0.html严重!Spring AOP Bug导致切面重复执行

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: PHP 服务实现性能剖析、跟踪和可观察性14444444444444】=102102102102102102102102102102102102102102102102实践

下一篇: 多线程编程在 C# 中的基础概念与实现

标签:
  • 热门焦点
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • Rust中的高吞吐量流处理

    Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 虚拟键盘 API 的妙用

    虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 得物宠物生意「狂飙」,发力“它经济”

    得物宠物生意「狂飙」,发力“它经济”

    作者|花花小萌主近日,得物宣布正式上线宠物鉴别,通过得物App内的&ldquo;在线鉴别&rdquo;,可找到鉴别宠物的选项。通过上传自家宠物的部位细节,就能收获拥有专业资质认证的得物鉴
  • 猿辅导与新东方的两种“归途”

    猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对&ldquo;势&rdquo;的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 8月见!小米MIX Fold 3获得3C认证:支持67W快充

    8月见!小米MIX Fold 3获得3C认证:支持67W快充

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 华为Mate60标准版细节曝光:经典星环相机模组回归

    华为Mate60标准版细节曝光:经典星环相机模组回归

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • 国行版三星Galaxy Z Fold5/Z Flip5发布 售价7499元起

    国行版三星Galaxy Z Fold5/Z Flip5发布 售价7499元起

    2023年8月3日,三星电子举行Galaxy新品中国发布会,正式在国内推出了新一代折叠屏智能手机三星Galaxy Z Fold5与Galaxy Z Flip5,以及三星Galaxy Tab S9
  • 三星电子Q2营收60万亿韩元 存储业务营收同比仍下滑超过50%

    三星电子Q2营收60万亿韩元 存储业务营收同比仍下滑超过50%

    7月27日消息,据外媒报道,从三星电子所发布的财报来看,他们主要利润来源的存储芯片业务在今年二季度仍不乐观,营收同比仍在大幅下滑,所在的设备解决方案
Top