我有一个名为ApplicationProperties
的对象。该对象具有私有字段和公共getter方法。很琐碎。
if (properties == null) {
properties = new ApplicationProperties();
SettingsLoader settingsLoader = new SettingsLoader(properties);
settingsLoader.loadApplicationSettings();
}
return properties;
我也有Spring Beans,其中一些依赖于ApplicationProperties
读取某些路径等。这在很长一段时间内都能正常工作。 JDK是Oracle JDK 1.6
。但最近我部署在OpenJDK 1.7 ICEDTEA
我得到了一些NullPointerException
,因为spring bean使用的应用程序属性有空字段(未完全初始化)。
可以在Open JDK(不确定)的情况下完成并行类加载。
如何确保所有spring bean(数量超过200个 - 以及许多注释)仅在ApplicationProperties
完全准备好后才会实例化?
答案 0 :(得分:0)
将属性对象作为构造函数依赖项注入所有需要它的bean。
答案 1 :(得分:0)
类ApplicationProperties
是一个非bean,它不受Spring IoC的控制。出于某些原因,代码在Oracle JDK 1.6
及更高版本上正常运行但在Open JDK 1.7 ICEDTEA
上无效,而我得到了一些NullPointerException
。
作为参考,我将解决方案作为答案发布。
由于非bean类属性需要在创建bean之前完全加载,我将加载部分委托给一个单独的线程,它对我来说很好。
public class SettingsLoader implements Runnable {
//Other methods go here
@Override
public void run() {
loadApplicationSettings();
}
}
在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);
}
}
这样,当前线程一直等到线程loader
完成设置应用程序属性字段的工作。