同为原型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 进行处理