Java 将属性添加到属性占位符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6387450/
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
Add properties to property placeholder
提问by Ralph
I have an application where a property placeholder is used to read properties, configured in applicationContext.xml
:
我有一个应用程序,其中属性占位符用于读取属性,配置为applicationContext.xml
:
...
<context:property-placeholder
location="classpath*:META-INF/spring/*.properties"/>
...
The application runs in an Tomcat and uses the parameter defined in context.xml.
The application access this parameter like normal properties (@Value(${cfma.applicationUrl})
). This works
该应用程序在 Tomcat 中运行并使用 context.xml 中定义的参数。应用程序像普通属性 ( @Value(${cfma.applicationUrl})
)一样访问此参数。这有效
In my test cases I do not have this tomcat properties, so I want to add them "manually" to the application context. But also load the normal applicationContext.xml
在我的测试用例中,我没有这个 tomcat 属性,所以我想将它们“手动”添加到应用程序上下文中。而且加载正常applicationContext.xml
testContext.xml:
测试上下文.xml:
<import resource="classpath:/META-INF/spring/applicationContext.xml" />
<context:property-placeholder properties-ref="simulatedTomcatProperties"/>
<util:properties id="simulatedTomcatProperties">
<prop key="cfmt.applicationBaseUrl">localhost:8080/cfmt</prop>
</util:properties>
Now I have two context:property-placeholder and this does not work (of course) – So my question is, who can I extend the properties in the “normal” property-placeholder in my test?
现在我有两个上下文:property-placeholder 这不起作用(当然) –所以我的问题是,我可以在测试中扩展“正常”属性占位符中的属性?
More Explanation of what I need:
我需要什么的更多解释:
- The productive environment (as well as the development environment) defines some properties via Tomcat parameter. Therefore they are not included in any properties file, but nerveless they can be accessed like normal properties (
@Value(${cfma.applicationUrl})
). Moreover there must not be any Fallback, if the properties are not defined in the Tomcat, the application must not start! - In the test cases (that use the spring context) I must some how insert the property (cfma.applicationUrl) so that it can be injected in the annotated variables.
But if I add an second
context:property-placeholder
they are not merged:
- 生产环境(以及开发环境)通过 Tomcat 参数定义了一些属性。因此,它们不包含在任何属性文件中,但可以像普通属性 (
@Value(${cfma.applicationUrl})
)一样轻松访问它们。而且一定不能有任何Fallback,如果Tomcat中没有定义属性,应用程序一定不能启动! - 在测试用例(使用 spring 上下文)中,我必须了解如何插入属性 (cfma.applicationUrl) 以便将其注入带注释的变量中。但是,如果我添加第二个,
context:property-placeholder
它们不会合并:
@See Comments on https://jira.springsource.org/browse/SPR-4881-- they explain that behaviour.
@See Comments on https://jira.springsource.org/browse/SPR-4881——他们解释了这种行为。
When I talk about Tomcat parameter I am talking about somethink like this:
当我谈论 Tomcat 参数时,我在谈论这样的想法:
context.xml:
上下文.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Parameter name="cfmt.applicationBaseUrl"
value="http://localhost/demoApp" override="false"/>
</Context>
采纳答案by Duncan McGregor
Not sure if this will help, but what I do in a similar situation is have 2 app.properties files with the same name, one in sec/test/resources and the other in src/main/resources. Now during testing the first is loaded because the test classes are first on the classpath, but when I deploy only the main one is there and so it is loaded.
不确定这是否会有所帮助,但我在类似情况下所做的是有 2 个同名的 app.properties 文件,一个在 sec/test/resources 中,另一个在 src/main/resources 中。现在在测试期间加载第一个,因为测试类首先在类路径上,但是当我部署时只有主类在那里,所以它被加载。
回答by laz
Does it work if you add the same location
attribute to the context:property-placeholder
defined in testContext.xml
that is in the one defined in applicationContex.xml
? You would also need to add the attribute local-override="true"
to have the properties-ref
override those from under META-INF
.
请问如果添加相同的它的工作location
属性的context:property-placeholder
定义testContext.xml
是在定义的applicationContex.xml
?您还需要添加属性local-override="true"
以properties-ref
覆盖来自 under的属性META-INF
。
Edit:
编辑:
Given your most recent comment, I think that you will need to forgo using the context
namespace and directly use the Spring objects that is uses behind the scenes. Perhaps something like this:
鉴于您最近的评论,我认为您将需要放弃使用context
命名空间并直接使用在幕后使用的 Spring 对象。也许是这样的:
In applicationContext.xml:
在 applicationContext.xml 中:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath*:META-INF/spring/*.properties" />
</bean>
In testContext.xml:
在 testContext.xml 中:
<bean id="propertyConfigurerTest" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" parent="propertyConfigurer">
<property name="properties" ref="simulatedTomcatProperties" />
<property name="localOverride" value="true" />
</bean>
<util:properties id="simulatedTomcatProperties">
<prop key="cfmt.applicationBaseUrl">localhost:8080/cfmt</prop>
</util:properties>
I'm guessing you want the local properties to override the properties defined from the classpath resources so I defined localOverride
as true.
我猜您希望本地属性覆盖从类路径资源定义的属性,所以我定义localOverride
为 true。
回答by Fil
If, in your main applicationContext.xml, you specify several property lookups as listed below using a PropertiesFactoryBean, any missed properties files are not loaded, and the last successfully loaded properties file is used. In your case, default.properties (e.g. your test properties file) would be loaded, and because the second file:${catalina}... wouldn't be loaded, your @Value fields would be injected with values specified in default.properties.
如果在主 applicationContext.xml 中使用 PropertiesFactoryBean 指定如下所列的多个属性查找,则不会加载任何丢失的属性文件,并使用上次成功加载的属性文件。在您的情况下,将加载 default.properties(例如您的测试属性文件),并且由于第二个文件:${catalina}... 不会被加载,您的 @Value 字段将被注入默认指定的值。特性。
Answer taken from here:
从这里获取的答案:
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:default.properties</value>
<value>file:${catalina.home}/webapps/myProperties.properties</value>
</list>
</property>
</bean>
回答by Ralph
I solved the problem by splitting up the applicationContext.xml
in two files:
- applicationContext.xml
-- contains the "normal" bean, but NO include of applicationContext-properties.xml
- applicationContext-properties.xml
-- contains the property placeholder config
我通过分成applicationContext.xml
两个文件解决了这个问题: - applicationContext.xml
-- 包含“普通”bean,但不包含applicationContext-properties.xml
- applicationContext-properties.xml
-- 包含属性占位符配置
applicationContext-properties.xml
:
applicationContext-properties.xml
:
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations" value="classpath*:META-INF/spring/*.properties" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
</bean>
The web application loads both files on startup:
Web 应用程序在启动时加载这两个文件:
web.xml
:
web.xml
:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
For my tests I have added a propoperties file: simulatedTomcat.test-properties
that contains all the tomcat properties. note: that this file does not match the pattern used by the properties placeholder configurer of applicationContext-properties.xml
对于我的测试,我添加了一个属性文件:simulatedTomcat.test-properties
包含所有 tomcat 属性。注意:此文件与属性占位符配置器使用的模式不匹配applicationContext-properties.xml
Then I have an properties placeholder configurer for my test that load both kind op properties files (*.properties
and *.test-properties
)
然后我有一个属性占位符配置器用于我的测试,它加载两种类型的操作属性文件(*.properties
和*.test-properties
)
test-context.xml
test-context.xml
<import resource="classpath:/META-INF/spring/applicationContext.xml" />
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:META-INF/spring/*.properties</value>
<value>classpath*:META-INF/spring/*.test-properties</value>
</list>
</property>
</bean>