手动实例化Bean后Spring切面失效问题咨询
问题分析与解决方案
这问题其实是Spring AOP的核心特性导致的——Spring切面仅对由Spring容器管理的Bean实例生效,你手动new AppConfig()创建的对象根本不在Spring的管控范围内,自然不会被切面代理拦截。
下面给你具体的解决步骤和代码调整方案:
步骤1:让AppConfig成为Spring托管Bean
给AppConfig类添加@Component注解,这样Spring组件扫描时会把它纳入容器管理:
import org.springframework.stereotype.Component; @Component public class AppConfig { private Integer num; private String text; public Integer getNum() { return num; } @PersistentOperation public void setNum(Integer num) { this.num = num; } public String getText() { return text; } @PersistentOperation public void setText(String text) { this.text = text; } }
步骤2:确保切面类被Spring识别并开启AOP支持
给PersistentAspect添加@Component注解,让Spring能扫描到这个切面;同时在你的Spring配置类(或者启动类)上添加@EnableAspectJAutoProxy注解,开启AspectJ风格的AOP代理:
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class PersistentAspect { @AfterReturning("@annotation(org.aspect.PersistentOperation)") public void log(JoinPoint jp) { System.out.println("aspect call"); } }
配置类示例:
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "你的实际包路径") // 替换成项目对应的包名 @EnableAspectJAutoProxy public class SpringConfig { }
步骤3:从Spring容器获取Bean实例,而非手动new
之后你需要从Spring应用上下文里获取AppConfig的实例,而不是自己手动创建:
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); AppConfig appConfig = context.getBean(AppConfig.class); // 调用方法,切面会正常生效 appConfig.setNum(100); appConfig.setText("test content"); } }
特殊场景补充
如果因为业务限制必须手动创建对象,还可以通过AspectJ的编译时/加载时织入(CTW/LTW)来实现切面拦截,但这种方式配置复杂度更高,除非必要,优先推荐上面的Spring容器托管方案。
内容的提问来源于stack exchange,提问作者Tarun Lalwani
相关产品推荐
相关产品推荐

