如何在设置Object的属性后加载Spring Beans?

时间:2015-11-10 02:58:00

标签: java spring spring-mvc java-7

我有一个名为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完全准备好后才会实例化?

2 个答案:

答案 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完成设置应用程序属性字段的工作。