例如我有两个豆子:
class Bean1 {
private SomeService service1;
private SomeService servive2;
private Bean2 bean2;
public void doStuff() {
service1.doActualStuff();
}
public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
public Bean2 getBean2() { return this.bean2 }
}
class Bean2 {
private Bean1 bean1;
private SomeService3 service3;
public void init() {
bean1.doStuff();
}
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
}
}
现在,如果我尝试按照以下方式在春季配置它们:
<bean id="service1" class="SomeService">
...
</bean>
<bean id="bean1" class="Bean1">
<property name="bean2" ref="bean2"/>
<property name="service1" ref="service1"/>
...
</bean>
<bean id="bean2" class="Bean2" init-method="init">
<property name="bean1" ref="bean1"/>
...
</bean>
执行bean2的init方法。 Bean2已注入bean1,但bean1本身未完全初始化,因此调用service1.doActualStuff()的bean1.doStuff()将返回NPE。为什么bean1没有完全初始化?
答案 0 :(得分:5)
Spring将未完全初始化状态的单例bean缓存到可能无法解析的循环引用的位置。在您的情况下,初始化顺序将是这样的:
考虑重新思考你的设计,以解开bean1和bean2之间的依赖关系。
答案 1 :(得分:0)
如果以编程方式注入第一个bean,那该怎么样:
class Bean2 {
private Bean1 bean1;
private SomeService3 service3;
public void init() {
bean1.doStuff();
}
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
//HERE
this.bean1.setBean2(this);
}
}
从spring xml中删除第一次注射:
<bean id="service1" class="SomeService">
...
</bean>
<bean id="bean1" class="Bean1">
<!-- NOT NEEDED ANYMORE <property name="bean2" ref="bean2"/> -->
<property name="service1" ref="service1"/>
...
</bean>
<bean id="bean2" class="Bean2" init-method="init">
<property name="bean1" ref="bean1"/>
...
</bean>