Spring AOP 在什么场景下会失效?
Spring AOP 基于动态代理实现(JDK 动态代理:针对接口;CGLIB 动态代理:针对类),当代理逻辑无法生效时,AOP 会失效,常见场景:
1. 非 Spring 容器管理的 Bean:AOP 仅对 Spring IOC 容器中的 Bean 生效。若通过
new关键字手动创建对象(如UserService service = new UserService()),而非@Autowired注入,Spring 无法为其生成代理对象,AOP 切面逻辑不执行。2. 同一 Bean 内部方法调用:若 Bean 中的方法 A 调用同一 Bean 中的方法 B(如
this.methodB()),由于this指向原始对象(非代理对象),代理逻辑无法拦截方法 B 的调用,AOP 失效。
示
@Service
public class UserService {
public void methodA() {
this.methodB(); // this是原始对象,AOP不生效
}
@LogAspect // 切面注解
public void methodB() {}
}
2
3
4
5
6
7
8
解决:通过
ApplicationContext
获取代理对象(
((UserService)applicationContext.getBean("userService")).methodB()
),或用
@Autowired
注入自身(需注意循环依赖,但 Spring 支持)。
3. 静态方法、final 方法、private 方法:
- 静态方法:JDK 动态代理和 CGLIB 均无法代理静态方法(静态方法属于类,而非实例);
- final 方法:CGLIB 通过继承生成代理类,final 方法无法被重写,代理逻辑无法植入;
- private 方法:private 方法仅在类内部可见,代理类无法访问,无法植入切面逻辑。
4. AOP 切面表达式错误:若
@Pointcut表达式写错(如包名、方法名错误),无法匹配目标方法,AOP 不生效。例如:目标方法是com.example.service.UserService.methodB(),切面表达式写为execution(* com.example.service.User.methodB(..))(包名少了service)。5. 事务切面与自定义切面的优先级冲突:若自定义切面的优先级低于事务切面(通过
@Order指定,值越大优先级越低),且自定义切面抛出异常未处理,可能导致事务切面无法生效(需确保异常被正确捕获或事务切面优先级更高)。6. 代理模式配置错误:Spring AOP 默认对实现接口的 Bean 用 JDK 动态代理,对未实现接口的 Bean 用 CGLIB;若手动配置
proxy-target-class="false"(强制用 JDK 动态代理),但目标 Bean 未实现接口,会导致代理创建失败,AOP 失效。