Spring IoC - 确保在@ PostConstruct / afterProperiesSet之前创建所有bean

时间:2011-02-21 00:34:24

标签: java spring

我有一个使用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吗?

谢谢,

约瑟夫。

3 个答案:

答案 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。