Spring单例初始化完成后如何运行方法?

时间:2012-02-02 02:08:10

标签: java spring dependency-injection initialization

使用Spring 3.0.x,我遇到了一个运行Bean init方法的问题,并且其中一部分提取了一些信息,然后在另一个线程中(原始init()线程在其他线程上等待)完成)尝试根据该信息检索获得一个或多个Bean。问题是,这些其他豆类也是单身,尚未初始化。在getSingleton()方法的DefaultSingletonBeanRegistry中有一个synchronized()块。

问题出现了,我正在尝试获取/初始化Bean,而我正在初始化Bean,所以我在init()方法中遇到主线程,另一个线程试图获取另一个单例Bean ,因为第一个线程有锁定而被阻止。

所以,我看到它的方式,我有两个选择:

1)获取Spring以在完全创建单例之后运行方法,该单例执行实际的数据获取和处理 2)提出消息传递给主线程,然后将数据全部处理,因为它已经有监视器锁

思考?想法?我怎样才能让#1工作?

4 个答案:

答案 0 :(得分:5)

您是否尝试过实施InitializingBean界面

class MyBean implements InitializingBean{

    @Override
    public void afterPropertiesSet(){
       // fetch information, etc
    }
}

根据文件:

  

要由所有属性都需要响应的bean实现的接口>由BeanFactory设置:例如,执行自定义初始化...

答案 1 :(得分:2)

您可以实施Lifecycle界面。在AbstractApplicationContext的封闭子类上调用start()/stop()时会发生生命周期回调,这在所有单例bean已初始化(注入依赖项,调用init方法)之后发生。生命周期回调也遵循依赖顺序,就像初始化一样。

答案 2 :(得分:1)

您没有提到您正在使用的配置类型(基于注释或基于XML),但在XML bean配置中,您可以使用depends-on属性来确保您需要实例化的bean序列是按正确的顺序完成的。

例如,如果您有两个bean:

<bean id="bean1" class="my.package.class" />
<bean id="bean2" class="my.package.class2" />
<bean id="bean3" class="my.package.class3" depends-on"bean1, bean2" />

在这种情况下,bean1和bean2将以未确认的顺序实例化。 Spring尝试根据XML文件的顺序进行实例化,但不能保证这一点。但是,保证bean3在bean1和bean2被实例化之前不被实例化。

我不知道这是否会纠正你的竞争状况,但希望它能有所帮助。

最糟糕的情况是,您始终可以实例化所有bean,并且一旦实例化,您可以使用FactoryMethodInvokingBean在实例化bean之后调用静态方法。再一次,确保使用depends-on确保在实例化单例bean后调用FactoryMethodInvokingBean。

答案 3 :(得分:0)

如果有人正在寻找一个与特定框架(如Spring)无关的更新的答案,那么Java提供@PostConstruct注释来完成同样的事情。使用Spring的基于注释的配置将识别此注释,并在初始化托管bean之后执行使用@PostConstruct注释的方法。

Perks包括:

  • 您正在从班级中删除Spring依赖项
  • 您可以根据需要为方法命名

Why use @PostConstruct?

Some practical examples