使用Spring 3.0.x,我遇到了一个运行Bean init方法的问题,并且其中一部分提取了一些信息,然后在另一个线程中(原始init()线程在其他线程上等待)完成)尝试根据该信息检索获得一个或多个Bean。问题是,这些其他豆类也是单身,尚未初始化。在getSingleton()方法的DefaultSingletonBeanRegistry中有一个synchronized()块。
问题出现了,我正在尝试获取/初始化Bean,而我正在初始化Bean,所以我在init()方法中遇到主线程,另一个线程试图获取另一个单例Bean ,因为第一个线程有锁定而被阻止。
所以,我看到它的方式,我有两个选择:
1)获取Spring以在完全创建单例之后运行方法,该单例执行实际的数据获取和处理 2)提出消息传递给主线程,然后将数据全部处理,因为它已经有监视器锁
思考?想法?我怎样才能让#1工作?
答案 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包括: