You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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代理

  1. 明确配置@EnableAspectJAutoProxy启用CGLIB代理:
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Configuration
public class AspectJConfig {
}
  1. 全局配置增强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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:20:16