简体   繁体   English

仅在设置对象的属性后如何加载Spring Bean?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM