为什么@PreDestroy标注方法上的Spring AOP切面不生效?
@PreDestroy方法切面未触发的核心原因
1. 生命周期回调调用直接绕过AOP代理入口
Spring的CommonAnnotationBeanPostProcessor处理@PreDestroy注解的时机,是在Bean实例创建完成、AOP代理生成之前的初始化阶段。此时处理器会扫描原始Bean类的@PreDestroy方法,并且直接保存原始目标Bean实例的方法引用,而非后续生成的代理对象的方法引用。
等到容器销毁阶段触发回调时,Spring会直接通过反射调用原始对象的对应方法,不会走CGLIB代理的方法拦截链路,因此切面逻辑完全不会被触发。
2. 生命周期回调方法的增强优先级限制
即使你观测到当前实例是CGLIB代理生成的子类实例,Spring对于@PreDestroy这类容器生命周期回调方法,默认也不会走代理的增强逻辑:Spring在执行销毁回调时,会优先调用目标类原生的生命周期方法,而非代理子类重写的增强版本,避免代理逻辑干扰容器本身的生命周期管理流程。
而你使用@EventListener监听ContextClosedEvent的方案可以正常触发切面,是因为事件监听方法属于普通的业务方法调用,Spring事件发布机制是通过代理对象的public方法入口发起调用,会正常经过AOP拦截链,因此可以被切面捕获。
内容的提问来源于stack exchange,提问作者Nikita Glukhov
相关产品推荐
相关产品推荐

