spring循环依赖下几种报错的写法
同为原型bean情况下的循环依赖,例如:
@Component @Scope("prototype") //原型bean (多例)情况 public class ServletA { @Autowired ServletB servletB; @Override public String toString() { return "this servletA"; } }
@Component @Scope("prototype") //原型bean (多例)情况 public class ServletB { @Autowired ServletA servletA; @Override public String toString() { return "this servletB"; } }
构造方法导致的循环依赖:这个比较好理解,由于都是构造函数注入参数,导致构造函数都无法完成
@Component public class UserA { UserB userB; /** * 构造函数的依赖注入 * */ public UserA(UserB userB) { this.userB = userB; } @Override public String toString() { return "UserA{}"; } }
@Component public class UserB { UserA userA; /** * 构造函数的依赖注入 * */ public UserB(UserA userA) { this.userA = userA; } @Override public String toString() { return "UserB{}"; } }
@Async情况下的循环依赖解析
前提你已经在配置文件了 @EnableAsync 并且 context.getBean("userA", UserA.class) 保证 userA 优先被调用
@Component public class UserA { @Autowired //可以通过添加@Lazy解决。本质是因为@Lazy 会注入userB的代理类。参考 AutowiredAnnotationBeanPostProcessor 的自动注入过程 //@Lazy UserB userB; /** * 注意是顺序问题,是先调用的UserA,而UserA依赖注入了UserB, * 这样在 UserA 的 a() 方法添加 @Async 注解导致报错 */ @Async public void a() { System.out.println("aaaaaaa"); } @Override public String toString() { return "UserA{}"; } }
@Component public class UserB { @Autowired UserA userA; /** * 注意是顺序问题,是先调用的UserA,而UserA依赖注入了UserB, * 这样在 UserB 的 b() 方法添加 @Async 注解是不会报错的 */ //@Async //public void b(){ // System.out.println("bbbbbbb"); //} @Override public String toString() { return "UserB{}"; } }
关于@Lazy 生成代理的源码
关于@Async会使循环依赖失败的问题,是因为 @EnableAsync 引入了 AsyncAnnotationBeanPostProcessor 导致了如下
而同样 @Transactional 并不会引起此以上的循环依赖的问题,因为 @Transactional 并没有引入 BeanPostProcessor 进行处理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!