spring循环注入怎么解决

spring循环注入怎么解决_第1张图片

构造器循环依赖

spring容器将每一个正在创建的Bean标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保持在这个池中,因此在创建Bean过程中发现自己已经在“当前创建Bean池”里时将抛出BeanCurrentlylnCreationException异常表示循环依赖;对于创建完毕的Bean将从“当前创建Bean池”中清除掉。

配置文件:

<bean id="circleA" class="cn.javass.spring.chapter3.bean.CircleA">
<constructor-arg index="0" ref="circleB"/>
bean>
<bean id="circleB" class="cn.javass.spring.chapter3.bean.CircleB">
<constructor-arg index="0" ref="circleC"/>
bean>
<bean id="circleC" class="cn.javass.spring.chapter3.bean.CircleC">
<constructor-arg index="0" ref="circleA"/>
bean>

过程:

  1. Spring容器创建“circleA” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续准备其需要的构造器参数“circleB”,并将“circleA” 标识符放到“当前创建Bean池”;
  2. Spring容器创建“circleB” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续准备其需要的构造器参数“circleC”,并将“circleB” 标识符放到“当前创建Bean池”;
  3. Spring容器创建“circleC” Bean,首先去“当前创建Bean池”查找是否当前Bean正在创建,如果没发现,则继续准备其需要的构造器参数“circleA”,并将“circleC” 标识符放到“当前创建Bean池”;
  4. 到此为止Spring容器要去创建“circleA”Bean,发现该Bean 标识符在“当前创建Bean池”中,因为表示循环依赖,抛出BeanCurrentlyInCreationException。

setter循环依赖:

表示通过setter注入方式构成的循环依赖

步骤:

  1. Spring容器创建单例“circleA” Bean,首先根据无参构造器创建Bean,并暴露一个“ObjectFactory ”用于返回一个提前暴露一个创建中的Bean,并将“circleA” 标识符放到“当前创建Bean池”;然后进行setter注入“circleB”;
  2. Spring容器创建单例“circleB” Bean,首先根据无参构造器创建Bean,并暴露一个“ObjectFactory”用于返回一个提前暴露一个创建中的Bean,并将“circleB” 标识符放到“当前创建Bean池”,然后进行setter注入“circleC”;
  3. Spring容器创建单例“circleC” Bean,首先根据无参构造器创建Bean,并暴露一个“ObjectFactory ”用于返回一个提前暴露一个创建中的Bean,并将“circleC” 标识符放到“当前创建Bean池”,然后进行setter注入“circleA”;进行注入“circleA”时由于提前暴露了“ObjectFactory”工厂从而使用它返回提前暴露一个创建中的Bean;
  4. 最后在依赖注入“circleB”和“circleA”,完成setter注入。

对于“prototype”作用域Bean,Spring容器无法完成依赖注入,因为“prototype”作用域的Bean,Spring容器不进行缓存,因此无法提前暴露一个创建中的Bean。

对于“singleton”作用域Bean,可以通过“setAllowCircularReferences(false);”来禁用循环引用:

你可能感兴趣的:(【JAVA】)