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

Spring Boot AOP自定义注解不生效,求助排查方案

Spring Boot AOP 不生效问题的原因及解决办法

问题根源

Spring AOP 是基于代理机制实现的,仅对 Spring 容器管理的 Bean 生效。你通过 new AppHomeFeatureEnabler(properties) 创建的对象并非 Spring 容器托管的 Bean,因此切面无法拦截其方法调用;而 @RestController 中的调用正常,是因为 Controller 本身是 Spring Bean,它依赖注入的 AppHomeFeatureEnabler 是 Spring 生成的代理对象。

解决方案

方案一:改用 Spring 容器管理对象(推荐)

放弃手动 new 对象的方式,让 AppHomeFeatureEnabler 完全由 Spring 托管,通过依赖注入获取实例:

  1. 确保 AppHomeFeatureEnabler 上的 @Component 注解生效(所在包在 @SpringBootApplication 的扫描范围内)。
  2. 在需要调用 isEnabled() 的类中,通过构造注入或字段注入获取实例,而非手动 new:
@Component
public class YourCallerClass {
    private final AppHomeFeatureEnabler featureEnabler;

    // Spring 4.3+ 支持无 @Autowired 的构造注入
    public YourCallerClass(AppHomeFeatureEnabler featureEnabler) {
        this.featureEnabler = featureEnabler;
    }

    public void businessMethod() {
        // 此处调用的是代理对象的方法,切面会正常拦截
        boolean enabled = featureEnabler.isEnabled();
    }
}
  1. 可移除 Guice 的 @Inject 注解,改用 Spring 原生的依赖注入逻辑(若项目无需兼容 Guice)。

方案二:使用 AspectJ 加载时织入(LTW)

若必须保留手动创建对象的逻辑,可改用 AspectJ 直接修改字节码实现织入,无需依赖 Spring 代理:

  1. 保留已引入的 aspectjweaver 依赖,在 src/main/resources/META-INF 下创建 aop.xml:
<!DOCTYPE aspectj PUBLIC
        "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver>
        <!-- 指定需要织入切面的包路径 -->
        <include within="com.example..*"/>
    </weaver>
    <aspects>
        <!-- 指定你的切面类全限定名 -->
        <aspect name="com.example.CheckFeatureEnabledAspect"/>
    </aspects>
</aspectj>
  1. 启动应用时添加 JVM 参数,指定 AspectJ 代理:
    -javaagent:/path/to/aspectjweaver.jar
    
    若使用 Spring Boot Maven 插件,可在 pom.xml 中配置:
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>
                        -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
                    </jvmArguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
  2. 在启动类上添加 @EnableLoadTimeWeaving 注解,替代 @EnableAspectJAutoProxy。

补充说明

你测试 @Deprecated 时出现的异常,是因为 Spring 初始化容器内的 Bean 时,扫描到标注了 @Deprecated 的方法触发了切面,但切面逻辑未适配该场景;带 execution 表达式的切点无效,同样是因为目标对象不是 Spring 托管的 Bean,无法生成代理。

内容的提问来源于stack exchange,提问作者trever

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:57:33