Spring AOP自定义注解对实现接口的Bean不生效问题排查
问题原因分析
当类实现接口时,Spring默认采用JDK动态代理,而JDK代理仅会代理接口中声明的方法。你的DummyInterface是空接口,duplicate方法并未在接口中定义,因此JDK代理对象不会包含该方法的代理逻辑。当你通过TestDummyServiceEvent类型的引用调用duplicate时,实际是直接调用了原始目标对象的方法,绕过了代理,导致切面无法拦截。
即使设置proxyTargetClass=true,若存在配置冲突(如其他配置覆盖该设置),或Spring未正确切换到CGLIB代理,也会导致问题无法解决。
解决方案
方案1:将目标方法添加到接口中
修改DummyInterface,把duplicate方法声明到接口内,让JDK代理能覆盖该方法:
public interface DummyInterface { String duplicate(String x); }
方案2:强制使用CGLIB代理
- 明确配置
@EnableAspectJAutoProxy启用CGLIB代理:
@EnableAspectJAutoProxy(proxyTargetClass = true) @Configuration public class AspectJConfig { }
- 全局配置增强CGLIB代理优先级,在
application.properties中添加:
spring.aop.proxy-target-class=true
CGLIB基于类继承生成代理,会覆盖目标类所有public方法,无论是否实现接口,切面都能正常拦截。
方案3:调整切面切点表达式
将切点表达式改为更明确的形式,避免注解匹配歧义:
@Around("execution(* *(..)) && @annotation(com.yourpackage.ServiceEvent)") public Object handleMethodCall(ProceedingJoinPoint joinPoint) throws Throwable { try { log.info("Service event called"); return joinPoint.proceed(); } catch (Exception ex) { log.error(ex.getMessage(), ex); throw ex; } }
注意替换com.yourpackage为ServiceEvent注解实际所在的包路径。
验证
重启应用后调用接口,检查日志是否两次输出Service event called,同时在IntelliJ中重新关联切面与注解方法,确认实现接口的类方法能被识别关联。
内容的提问来源于stack exchange,提问作者dcg
相关产品推荐
相关产品推荐

