PropertySourcesPlaceholderConfigurer 未在 SpringBoot 项目中注册环境 [英] PropertySourcesPlaceholderConfigurer not registering with Environment in a SpringBoot Project

查看:24
本文介绍了PropertySourcesPlaceholderConfigurer 未在 SpringBoot 项目中注册环境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一个工作项目从使用 SpringBoot 命令行参数转移到从文件中读取属性.以下是 @Configuration 类的相关部分:

I am moving a working project from using SpringBoot command line arguments to reading properties from a file. Here are the involved portions of the @Configuration class:

@Configuration
class RemoteCommunication {

    @Inject
    StandardServletEnvironment env


    @Bean
    static PropertySourcesPlaceholderConfigurer placeholderConfigurer () {
        // VERIFIED this is executing...
        PropertySourcesPlaceholderConfigurer target = new PropertySourcesPlaceholderConfigurer()
        // VERIFIED this files exists, is readable, is a valid properties file
        target.setLocation (new FileSystemResource ('/Users/me/Desktop/mess.properties'))
        // A Debugger does NOT show this property source in the inject Environment
        target
    }


    @Bean  // There are many of these for different services, only one shown here.
    MedicalSorIdService medicalSorIdService () {
        serviceInstantiator (MedicalSorIdService_EpicSoap, 'uri.sor.id.lookup.internal')
    }


    // HELPER METHODS...


    private <T> T serviceInstantiator (final Class<T> classToInstantiate, final String propertyKeyPrimary) {
        def value = retrieveSpringPropertyFromConfigurationParameter (propertyKeyPrimary)
        classToInstantiate.newInstance (value)
    }


    private def retrieveSpringPropertyFromConfigurationParameter (String propertyKeyPrimary) {
        // PROBLEM: the property is not found in the Environment
        def value = env.getProperty (propertyKeyPrimary, '')
        if (value.isEmpty ()) throw new IllegalStateException ('Missing configuration parameter: ' + ""$propertyKeyPrimary"")
        value
    }

使用@Value 注入属性确实有效,但是如果可能的话,我宁愿直接使用Environment.如果设置不在 Environment 中,那么我不确定 @Value 在哪里提取它们...

Using @Value to inject the properties does work, however I'd rather work with the Environment directly if at all possible. If the settings are not in the Environment then I am not exactly sure where @Value is pulling them from...

env.getProperty() 在我传入指定属性的命令行参数时继续正常工作.

env.getProperty() continues to work well when I pass in command line arguments specifying the properties though.

欢迎提出任何建议!

推荐答案

这里的问题是 PropertySourcesPlaceholderConfigurerStandardServletEnvironmentEnvironment 之间的区别> 为简单起见.

The issue here is the distinction between PropertySourcesPlaceholderConfigurer and StandardServletEnvironment, or Environment for simplicity.

Environment 是一个对象,它支持整个 ApplicationContext 并且可以解析一堆属性(Environment 接口扩展了 PropertyResolver).ConfigurableEnvironment 有一个 MutablePropertySources 对象,您可以通过 getPropertySources() 检索该对象.这个 MutablePropertySources 包含一个 PropertySource 对象的 LinkedList,这些对象被检查以解析请求的属性.

The Environment is an object that backs the whole ApplicationContext and can resolve a bunch of properties (the Environment interface extends PropertyResolver). A ConfigurableEnvironment has a MutablePropertySources object which you can retrieve through getPropertySources(). This MutablePropertySources holds a LinkedList of PropertySource objects which are checked in order to resolve a requested property.

PropertySourcesPlaceholderConfigurer 是一个具有自己状态的独立对象.它拥有自己的 MutablePropertySources 对象,用于解析属性占位符.PropertySourcesPlaceholderConfigurer 实现了 EnvironmentAware,所以当 ApplicationContext 得到它时,它会给它它的 Environment 对象.PropertySourcesPlaceholderConfigurer 将这个 EnvironmentMutablePropertySources 添加到它自己的.然后,它还添加您使用 setLocation() 指定的各种 Resource 对象作为附加属性.这些Resource 对象没有添加到EnvironmentMutablePropertySources 中,因此不能用于env.getProperty(字符串).

PropertySourcesPlaceholderConfigurer is a separate object with its own state. It holds its own MutablePropertySources object for resolving property placeholders. PropertySourcesPlaceholderConfigurer implements EnvironmentAware so when the ApplicationContext gets hold of it, it gives it its Environment object. The PropertySourcesPlaceholderConfigurer adds this Environment's MutablePropertySources to its own. It then also adds the various Resource objects you specified with setLocation() as additional properties. These Resource objects are not added to the Environment's MutablePropertySources and therefore aren't available with env.getProperty(String).

因此您无法将PropertySourcesPlaceholderConfigurer 加载的属性直接放入Environment.你可以做的是直接添加到EnvironmentMutablePropertySouces.一种方法是使用

So you cannot get the properties loaded by the PropertySourcesPlaceholderConfigurer into the Environment directly. What you can do instead is add directly to the Environment's MutablePropertySouces. One way is with

@PostConstruct
public void setup() throws IOException {
    Resource resource = new FileSystemResource("spring.properties"); // your file
    Properties result = new Properties();
    PropertiesLoaderUtils.fillProperties(result, resource);
    env.getPropertySources().addLast(new PropertiesPropertySource("custom", result));
}

或者简单地(感谢@M.Deinum)

or simply (thanks @M.Deinum)

@PostConstruct
public void setup() throws IOException {
    env.getPropertySources().addLast(new ResourcePropertySource("custom", "file:spring.properties")); // the name 'custom' can come from anywhere
}

请注意,添加一个 @PropertySource 具有相同的效果,即.直接添加到 Environment,但您是静态而不是动态添加.

Note that adding a @PropertySource has the same effect, ie. adding directly to the Environment, but you're doing it statically rather than dynamically.

这篇关于PropertySourcesPlaceholderConfigurer 未在 SpringBoot 项目中注册环境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆