java Spring 3.1 环境不适用于用户属性文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14169834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:20:29  来源:igfitidea点击:

Spring 3.1 Environment does not work with user property files

javaspring

提问by endless

I am doing this..

我在做这个..

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context);
xmlReader
        .loadBeanDefinitions(new ClassPathResource("SpringConfig.xml"));
PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
propertyHolder.setLocation(new ClassPathResource(
        "SpringConfig.properties"));
context.addBeanFactoryPostProcessor(propertyHolder);

    ......

context.refresh();

Now in my @Configuration files, the properties present in my SpringConfig.properties are not getting picked up if I do this...

现在在我的@Configuration 文件中,如果我这样做,我的 SpringConfig.properties 中存在的属性不会被拾取......

@Autowired
private Environment env
.....
env.getProperty("my.property")

But I get that property if I use

但如果我使用,我会得到那个属性

@Value("${my.property}")
private String myProperty;

I even tried adding couple of more lines like this, but of no use.

我什至尝试添加更多这样的行,但没有用。

ConfigurableEnvironment env = new StandardEnvironment();
propertyHolder.setEnvironment(env);

Does anybody know why my properties are not loaded into Environment? Thanks.

有人知道为什么我的属性没有加载到环境中吗?谢谢。

采纳答案by Boris Treukhov

PropertySourcesPlaceholderConfigurer reads property files directly(as it was done by PropertyPlaceholderConfigurer in Spring 3.0 times), it's just a postprocessor which does not change the way properties are used in the Spring context - in this case properties are only available as bean definition placeholders.

PropertySourcesPlaceholderConfigurer 直接读取属性文件(就像在 Spring 3.0 时代由 PropertyPlaceholderConfigurer 完成的那样),它只是一个后处理器,不会改变在 Spring 上下文中使用属性的方式 - 在这种情况下,属性仅可用作 bean 定义占位符。

It's the PropertySourcesPlaceholderConfigurer who uses Environment and not vice versa.

使用 Environment 的是 PropertySourcesPlaceholderConfigurer,反之亦然。

Property sources framework works on the application context level, while property placeholder configurers only provide the functionality to process placeholders in the bean definitions. To use property source abstraction you should use @PropertySourceannotation i.e. decorate your configuration class with something like @PropertySource("classpath:SpringConfig.properties")

属性源框架在应用程序上下文级别工作,而属性占位符配置器仅提供处理 bean 定义中的占位符的功能。要使用属性源抽象,您应该使用@PropertySource注释,即用类似的东西装饰您的配置类 @PropertySource("classpath:SpringConfig.properties")

I believe that you can do the same thing programmatically, i.e. you can get the container's ConfigurableEnvironment before the context was refreshed, modify its MutablePropertySources(you need first to get AbstractApplicationContextenvironmentproperty via context.getEnvironment()) via getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties")));but it's unlikely what you want to do - if you already have a @Configurationannotated class, decorating it with @PropertySource("classpath:SpringConfig.properties")is much simpler.

我相信你可以以编程方式做同样的事情,即你可以在刷新上下文之前获得容器的 ConfigurableEnvironment,修改它的 MutablePropertySources(你需要首先AbstractApplicationContextenvironment通过context.getEnvironment())通过getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties")));但它不太可能你想要做什么 - 如果你已经有了一个带@Configuration注释的类,用它装饰它@PropertySource("classpath:SpringConfig.properties")要简单得多。

As for the PropertySourcesPlaceholderConfigurerinstance - it will fetch property sources automatically(as it implements EnvironmentAware) from its application context so you need just to register a default instance of it.

至于PropertySourcesPlaceholderConfigurer实例 - 它将从其应用程序上下文中自动获取属性源(因为它实现了 EnvironmentAware),因此您只需要注册它的默认实例。

For the examples of custom property source implementation see http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

有关自定义属性源实现的示例,请参阅http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

回答by axtavt

Adding localproperties to PropertySourcesPlaceholderConfigurer(with setProperties()or setLocation()) doesn't make them available in the Environment.

本地属性添加到PropertySourcesPlaceholderConfigurer(withsetProperties()setLocation()) 不会使它们在Environment.

Actually it works in the opposite way - Environmentacts as a primary source of properties (see ConfigurableEnvironment), and PropertySourcesPlaceholderConfigurercan make properties from the Environmentavailable using ${...}syntax.

实际上,它以相反的方式工作 -Environment作为属性的主要来源(请参阅 参考资料ConfigurableEnvironment),并且PropertySourcesPlaceholderConfigurer可以从Environment可用 using${...}语法中生成属性。

回答by endless

I did this per @Boris suggestion..

我按照@Boris 的建议做了这个..

    PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
    ConfigurableEnvironment env = new StandardEnvironment();
    env.getPropertySources().addFirst(
            new ResourcePropertySource(new ClassPathResource(
                    "SpringConfig.properties")));
    propertyHolder.setEnvironment(env);
    context.addBeanFactoryPostProcessor(propertyHolder);
            context.register(SpringConfig.class);
            context.refresh();

Now in @Configuration classes all properties (including my own and system properties) can be resolved using @Value.

现在在@Configuration 类中,所有属性(包括我自己的和系统属性)都可以使用 @Value 解析。

But the Environment that gets @Autowired into @Configuration class has only system properties in it, not SpringConfig.properties I set as above. But clearly, before calling context.refresh()above, the ConfigurableEnvironmenthas my properties also. But once context.refresh()is called, my properties are removed from the Environment that gets autowired into @Configuration.

但是将@Autowired 放入@Configuration 类的环境中只有系统属性,而不是我如上设置的 SpringConfig.properties。但很明显,在调用context.refresh()上面之前,ConfigurableEnvironment也有我的属性。但是一旦context.refresh()被调用,我的属性就会从自动连接到@Configuration 的环境中删除。

I want to be able to use the better syntax, env.getProperty("my.property"). Does anybody know why that is the case?

我希望能够使用更好的语法 env.getProperty("my.property")。有谁知道为什么会这样?

回答by Jan Tharali

I am loading 2 types of properties one is the Environment property and the other is the context which you usually get from lets say servletContext.getServletContext(). My environment property is defined as : MOD_CONFIG_ROOTwhich is set seperately on the environment thereby seperating the location details the ear file which contains code. Here's the configuration. [ Note: I had to load the property files as first thing before loading the servlets to make use of the properties using ${someProperty}]

我正在加载两种类型的属性,一种是 Environment 属性,另一种是您通常从中获取的上下文servletContext.getServletContext()。我的环境属性定义为:MOD_CONFIG_ROOT它在环境上单独设置,从而将包含代码的耳朵文件的位置详细信息分开。这是配置。[注意:在加载 servlet 以使用属性之前,我必须首先加载属性文件${someProperty}]

<bean id="externalProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>file:#{ systemEnvironment['MOD_CONFIG_ROOT']
                }#{servletContext.contextPath}/users.properties</value>
        </list>
    </property>
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
</bean>