1、什么是循环依赖?
循环依赖会发生在Bean A中需要使用Bean B,同时Bean B中需要使用Bean A。
像这种形式: Bean A -> Bean B -> Bean A
2、产生循环依赖时,Spring中发生了什么?
当Spring comtext 加载所有bean时,会尝试按需求顺序创建,如果不存在循环依赖的情况下,例如如下形式:
Bean A -> Bean B -> Bean C
Spring会首先创建Bean C,接着创建Bean B(并将bean C注入),最后创建Bean A(将bean B注入)。但是,在存在循环依赖的情况下,Spring决定不了优先创建哪个Bean,因为每个bean都依赖另一个。这种情况下Spring会抛出异常BeanCurrentlyInCreationException while loading context。
但这种异常会发生在使用constructor injection时,如果使用其他类型注入,则不会出现这个问题。因为依赖项会在需要时注入,而不是在加载上下文时注入。
但是我在项目中使用的是@Autowired自动注入,springboot仍启动失败The dependencies of some of the beans in the application context form a cycle:
3、解决方案
3.1 代码重构
存在循环依赖问题一定是代码设计问题,最根本的方案就是重构代码,将循环解构。但是大多情况下这是一项比较复杂的工作。
4.2 使用@Lazy
通过使用@Lazy在Spring初始化Bean的时候进行懒加载。这种情况下Spring不会完全初始化bean,而是创建一个代理注入到另一个bean中,被注入的bean只有在第一次真正使用时才会被创建。
4.3 使用Setter/Field Injection
4.4 使用@PostConstruct
4.5Implement ApplicationContextAware and InitializingBean
无奈的是,上面的方法对我遇到的问题都不管用!
我是这样解决的:在application配置文件中加入spring.main.lazy-initialization="true".问题得以成功解决。