必须显式引入aspectjweaver依赖并替换包路径,否则AOP静默失效;Spring Boot 3.1需用jakarta.*命名空间,@Aspect类须加@Component且切入点包名须匹配主启动类扫描范围。

要在Spring Boot 3.1项目中快速启用AOP能力,实现日志、权限、耗时统计等横切逻辑与业务代码彻底解耦,必须避开Spring Boot 2.x旧版配置惯性,尤其注意Jakarta EE 9+命名空间迁移和代理机制变更。
确认依赖与兼容性
Spring Boot 3.1默认使用Spring Framework 6.0+,底层已全面切换至Jakarta EE 9+命名空间(javax.* → jakarta.*),且【spring-boot-starter-aop不再隐式拉取aspectjweaver】。若未显式引入,@Aspect注解类将被Spring完全忽略,切面不会注册。
在pom.xml中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
注意:aspectjweaver必须显式声明,否则编译通过但运行时无任何织入行为,且控制台零报错——这是3.1版本最易踩的静默失效陷阱。
编写切面类
创建一个普通Java类,用@Component和@Aspect双注解标识:
@Component
@Aspect
public class TraceAspect {
// 切入点表达式必须明确指定包路径,3.1默认不扫描非本模块包
@Pointcut("execution(* com.yourpackage..*Controller.*(..))")
public void controllerMethod() {}
@Around("controllerMethod()")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
String methodName = joinPoint.getSignature().toShortString();
System.out.println(methodName + " 执行耗时:" + (end - start) + "ms");
return result;
}
}
这一步操作起来很简单,直接把文件拖进去就行。但【切入点表达式中的com.yourpackage必须替换成你实际的根包名】,否则切面永远不生效——Spring Boot 3.1默认只扫描主启动类所在包及其子包,跨包需显式配置或调整包结构。
验证AOP是否生效
方法一:启动应用后观察控制台日志
① 启动Spring Boot应用;
② 发起一次HTTP请求调用任意Controller接口;
③ 查看控制台是否输出形如“com.example.demo.controller.UserController.list(..) 执行耗时:123ms”的日志行。
方法二:检查Bean注册状态
在任意@Service类中注入ApplicationContext:
private final ApplicationContext context;
然后打印所有切面Bean:
context.getBeansOfType(Aspect.class).keySet().forEach(System.out::println);
如果输出为空,说明切面类未被识别——大概率是@Component缺失、包扫描路径错误或aspectjweaver未引入。
方法三:调试代理对象
在Controller方法内打个断点,执行时查看this对象的Class名。若为类似UserController$$EnhancerBySpringCGLIB$xxx,则AOP代理已生效;若仍为原始UserController,则代理未织入。


















