我有一个使用Spring IoC进行依赖注入的项目,我试图通过一个中心位置来访问我的大部分bean来略微简化我的模型。
我使用@PostConstruct
机制遇到问题,或者在实现InitializingBean
接口时遇到问题。虽然可能已经解决了该特定bean中的所有依赖项,但注入Bean中的依赖项可能不是。例如,我有:
public class A {
public void doSomething() {};
}
public class B {
private A objectA;
@Required
public void setObjectA(A objectA) {
this.objectA = objectA;
}
public A getObjectA() {
return objectA;
}
}
public class C implements InitializingBean {
private B objectB;
@Required
public void setObjectB(B objectB) {
this.objectB = objectB;
}
public void afterPropertiesSet() throws Exception {
objectB.getObjectA().doSomething();
}
}
我的context.xml文件定义了这三个bean并注入了相应的属性,但是当C类的对象被实例化并调用NullPointerException
方法时,我得到afterPropertiesSet
,调试显示我对getObjectA()
的调用会返回null
。如果我将对象A直接注入C类,我就不会有错误。
我可以使用一种机制来确保在我的afterPropertiesSet
方法/使用@PostConstruct
注释的任何方法之前完全实例化所有bean吗?
谢谢,
约瑟夫。
答案 0 :(得分:5)
对于注入依赖项的方法调用onPropertiesSet()为时尚早。实际上,在调用afterPropertiesSet()然后调用BeanPostProcessors的postProcessAfterInitialization()之后调用init方法(如果你有XML格式)。你有@Required注释,因此,当然,执行RequiredAnnotationBeanPostProcessor。
生命周期回调方法就是它们:它们告诉您生命周期事件,它们的目的不是让您劫持Spring正在执行的任务。 (虽然你可以像在C-中直接注射物体A时那样做,但不建议这样做。)
如果你想在C类中使用对象A(或任何其他的spring bean),那么我建议使用ApplicationContextAware(或BeanFactoryAware,视情况而定)并使用getBean()方法来完全烘焙并准备为豆子服务!
答案 1 :(得分:5)
实现ApplicationListener [ContextRefreshedEvent]并在onApplicationEvent()中完成您的工作。注意事项 - ContextRefreshedEvent有时会多次发布,因此您可能希望在第一次设置标志后忽略其他事件。
答案 2 :(得分:0)
使用@DependsOn确保在C之前实例化A。