如何在AspectJ加载时织入场景下实现Spring Bean注入?
核心结论
可以在AspectJ加载时织入(LTW)场景下使用Spring Bean注入,问题出在配置逻辑上——你当前让AspectJ自己实例化了切面,而非让Spring管理切面实例并完成依赖注入。
问题根源
你的aop.xml中直接通过<aspect name="..."/>声明了切面,这会触发AspectJ自行实例化切面类。但AspectJ的实例化流程不会经过Spring的依赖注入环节,导致errorLogMap处于未初始化状态,切面执行时发生隐性错误(可能被底层吞掉),表现为切面"未执行"。
具体调整步骤
修改
aop.xml,移除手动声明的切面
只保留织入范围配置,让Spring管理切面实例并注册给AspectJ:<aspectj> <weaver options="-verbose -showWeaveInfo"> <include within="com.example.helloworld..*"/> </weaver> </aspectj>保留Spring对切面的管理配置
切面类上的@Aspect、@Component、@AllArgsConstructor无需修改,确保Spring组件扫描能覆盖到该切面所在包。保留
@EnableLoadTimeWeavingAspectConfig中的@EnableLoadTimeWeaving是关键,它会让Spring将自身管理的切面Bean注册到AspectJ织入器中,实现LTW与Spring依赖注入的结合。简化启动参数(可选)
Spring Boot场景下通常仅需aspectjweaver的javaagent即可,可尝试去掉spring-instrument:-javaagent:/Users/debrajmanna/.m2/repository/org/aspectj/aspectjweaver/1.9.20/aspectjweaver-1.9.20.jar
验证逻辑
调整后,Spring会先创建DaoExceptionHandler的Bean并完成errorLogMap的注入,再通过@EnableLoadTimeWeaving将这个已注入依赖的切面Bean交给AspectJ织入器。当目标方法触发切点时,执行的是Spring管理的切面实例,依赖已正常初始化,切面就能按预期工作。
内容的提问来源于stack exchange,提问作者tuk

