[英]How to load Spring Beans only after an Object's properties are set?
I have an object called ApplicationProperties
. 我有一个名为
ApplicationProperties
的对象。 The object has private fields and public getter methods. 该对象具有私有字段和公共获取方法。 Very trivial.
非常琐碎。
if (properties == null) {
properties = new ApplicationProperties();
SettingsLoader settingsLoader = new SettingsLoader(properties);
settingsLoader.loadApplicationSettings();
}
return properties;
I also have Spring Beans, some of which depend on ApplicationProperties
for reading some path etc. This is working fine for a long period of time. 我也有Spring Bean,其中一些依赖于
ApplicationProperties
来读取某些路径等。这在很长一段时间内都可以正常工作。 The JDK is Oracle JDK 1.6
. JDK是
Oracle JDK 1.6
。 But recently when I deployed in OpenJDK 1.7 ICEDTEA
I got some NullPointerException
as the application properties being used by a spring bean has null fields(Not initialized fully). 但是最近,当我在
OpenJDK 1.7 ICEDTEA
部署时,由于Spring bean使用的应用程序属性具有空字段(未完全初始化),我得到了一些NullPointerException
。
May be parallel class loading is done in case of Open JDK(Not sure about it). 如果是Open JDK,则可能是并行类加载完成(不确定)。
How do I ensure that all spring beans(more than 200 in number - and many through annotations) are instantiated only after the ApplicationProperties
is fully ready? 如何确保仅在
ApplicationProperties
完全准备好后实例化所有spring bean(数量超过200个,并且通过批注进行实例化)?
将属性对象作为构造函数依赖项注入到需要它的所有Bean。
The class ApplicationProperties
is a non-bean which was not under the control of the Spring IoC. 类
ApplicationProperties
是一个非bean,不受Spring IoC的控制。 For some reasons the code which was working fine on Oracle JDK 1.6
and higher versions but did not work on Open JDK 1.7 ICEDTEA
and I was getting some NullPointerException
. 由于某些原因,该代码在
Oracle JDK 1.6
和更高版本上可以正常工作,但在Open JDK 1.7 ICEDTEA
上却无法工作,我得到了一些NullPointerException
。
For reference I am posting the solution as answer. 供参考,我将解决方案作为答案。
As the non-bean class properties need to be loaded completely before beans are created, I delegated the loading part to a separate thread and it worked fine for me. 由于在创建bean之前需要完全加载非bean类的属性,因此我将加载部分委托给了一个单独的线程,它对我来说很好用。
public class SettingsLoader implements Runnable {
//Other methods go here
@Override
public void run() {
loadApplicationSettings();
}
}
And inside the constructor of the ApplicationProperties
并在
ApplicationProperties
的构造函数中
private ApplicationProperties() {
SettingsLoader settingsLoader = new SettingsLoader(this);
Thread loader = new Thread(settingsLoader);
loader.setName("Settings Loader");
logger.info("Settings Loader is initiated. Loading application settings.");
loader.setPriority(Thread.MAX_PRIORITY);
try {
loader.start();
loader.join();
} catch (InterruptedException ex) {
logger.error("Application settings loader is interrupted. Exception is", ex);
}
}
With this the current thread waits until the thread loader
has done its job of setting application properties fields. 这样,当前线程将等到线程
loader
完成设置应用程序属性字段的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.