【问题标题】:How to load Spring Beans only after an Object's properties are set?仅在设置对象的属性后如何加载 Spring Bean?
【发布时间】:2015-11-10 02:58:00
【问题描述】:

我有一个名为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 的情况下可能会进行并行类加载(不确定)。

我如何确保只有在 ApplicationProperties 完全准备好之后才实例化所有 spring bean(数量超过 200 个 - 并且许多通过注释)?

【问题讨论】:

    标签: java spring spring-mvc java-7


    【解决方案1】:

    将属性对象作为构造函数依赖注入到所有需要它的bean。

    【讨论】:

    • 实际上,一些 bean 具有使用一些非 bean 类(使用应用程序属性)设置的静态字段。这使事情变得复杂。
    • 还有其他方法吗?谢谢。
    【解决方案2】:

    ApplicationProperties 类是不受 Spring IoC 控制的非 bean。由于某些原因,代码在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 完成设置应用程序属性字段的工作。

    【讨论】:

      最近更新 更多