问题描述
在代码中,取得一个在 spring 容器中注册的类有两种方法:
1) AppContext.getBean
2) 在 applicationContext-Service.xml 中配置好类之间引用关系,在对应的类代码中加入 get 和 set 方法。
如果在 spring 容器中注册过的类中,出现 AppContext.getBean 的代码,例如:
public class Fsj1{
public Fsj1(){
System.out.println("111");
}
}
public class Fsj2 {
Fsj1 fsj1 = (Fsj1) AppContext.getBean("service1");
public Fsj2(){
System.out.println("222");
}
}
applicationContext-service.xml 中配置如下:
<bean id="service1" class="cn.ac.iscas.share.cus.service.Fsj1"/>
<bean id="service2" class="cn.ac.iscas.share.cus.service.Fsj2"/>
那么在程序启动的时候就会 报错:
java.lang.NullPointerException
at cn.ac.intec.entity.orm.AppContext.getBean(AppContext.java:146)
问题分析
我们来看一下 AppContext 类代码:
public class AppContext{
private static BeanFactory factory = null;
public static Object getBean(String name) {
return factory.getBean(name);
}
}
空指针的错误正是由于 factory 为 null 引起的,这是因为在程序启动时, BeanFactory 尚未对所有的对象创建完毕,也就是说 factory 实例还没有初始化完毕。在这个过程中又去调用 factory.getBean 当然会出现空指针错误。
当程序启动完毕后, factory 就初始化完毕了,这时候在程序的运行中(最常见的就是在 action 中)调用 AppContext.getBean 就不会出错了。
问题解决
对于两个都在 spring 中注册的类,互相之间的依赖关系应该在配置文件中写好,即使是循环依赖, spring 也可以很好的解决这个问题。例如:
public class Fsj1 {
Fsj2 service2;
public Fsj1(){
System.out.println("111");
}
public Fsj2 getService2() {
return service2;
}
public void setService2(Fsj2 service2) {
this. service2= service2;
}
}
public class Fsj2 {
Fsj1 service1;
public Fsj2(){
System.out.println("222");
}
public Fsj1 getService1() {
return service1;
}
public void setService1(Fsj1 service1) {
this.service1 = service1;
}
}
applicationContext-service.xml 中配置如下:
<bean id="service1" class="cn.ac.iscas.share.cus.service.Fsj1">
<property name="service2" ref="service2" />
</bean>
<bean id="service2" class="cn.ac.iscas.share.cus.service.Fsj2">
<property name="service1" ref="service1" />
</bean>