Spring Boot 3.1.12中@Autowired/构造注入致AOP触发两次问题
问题分析与解决方案
核心原因
你的切面被重复注册了两次:
- 一方面通过
AspectConfig中的@ComponentScan("com.monitor"),Spring会自动扫描并创建MonitorMethodAspect的实例 - 另一方面又通过
Aspects.aspectOf(MonitorMethodAspect.class)获取AspectJ的单例切面,并注册为Spring Bean
两个切面实例都会监听目标方法,导致AOP通知触发两次。日志中连接点参数格式的差异,正是两个不同切面实例输出的(一个是Spring代理生成的连接点,一个是AspectJ织入的连接点)。
Spring Boot 3.1.12及3.2.2版本的AOP逻辑调整,使得这两个重复实例的通知都能被执行;而3.1.11及之前的版本可能存在隐式去重机制,掩盖了这个配置错误。
修复方案(二选一即可)
方案1:移除组件扫描,手动管理切面Bean
修改AspectConfig,去掉@ComponentScan注解,只保留手动注册的切面Bean:
@Configuration public class AspectConfig { @Bean public MonitorMethodAspect theAspect() { MonitorMethodAspect aspect = Aspects.aspectOf(MonitorMethodAspect.class); return aspect; } }
方案2:依赖Spring组件扫描管理切面
- 给
MonitorMethodAspect添加@Component注解:
@Aspect @Component public class MonitorMethodAspect { @Autowired MonitorService monitorService; @AfterReturning(pointcut = "execution(* com.controller.KnowledgeBaseController.test(..))", returning = "result") public void test(JoinPoint joinPoint, String result){ log.info(joinPoint+" "+result); } }
- 删除
AspectConfig中的theAspect()Bean定义,或直接移除整个AspectConfig类(若无其他配置):
@Configuration @ComponentScan("com.monitor") public class AspectConfig { // 移除切面Bean的手动注册代码 }
验证建议
修复后重启服务,调用目标接口,检查日志是否仅输出一次AOP通知,确认问题解决。
内容的提问来源于stack exchange,提问作者Earny Huang
相关产品推荐
相关产品推荐

