我有一个应用程序,其中使用属性占位符来读取属性,在applicationContext.xml
中配置:
...
<context:property-placeholder
location="classpath*:META-INF/spring/*.properties"/>
...
应用程序在Tomcat中运行,并使用context.xml中定义的参数。
应用程序像普通属性(@Value(${cfma.applicationUrl})
)一样访问此参数。 此作品
在我的测试用例中,我没有这个tomcat属性,所以我想将它们“手动”添加到应用程序上下文中。但也加载正常的applicationContext.xml
testContext.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>
现在我有两个上下文:property-placeholder,这当然不起作用 - 所以我的问题是,我可以在测试中的“普通”属性占位符中扩展属性吗?
更多我需要的解释:
@Value(${cfma.applicationUrl})
)那样无神经地访问它们。此外,一定不能有任何回退,如果没有在Tomcat中定义属性,应用程序一定不能启动!context:property-placeholder
,则它们不会合并:@参见https://jira.springsource.org/browse/SPR-4881的评论 - 他们解释了这种行为。
当我谈论Tomcat参数时,我正在谈论这样的想法:
context.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>
答案 0 :(得分:5)
不确定这是否有帮助,但我在类似情况下做的是有2个app.properties文件同名,一个在sec / test / resources中,另一个在src / main / resources中。现在在测试期间第一个被加载,因为测试类首先在类路径上,但是当我部署时只有主要的那个在那里,所以它被加载。
答案 1 :(得分:3)
如果您将location
属性添加到context:property-placeholder
中testContext.xml
中定义的applicationContex.xml
属性,那么它是否有效?您还需要添加属性local-override="true"
,以使properties-ref
覆盖META-INF
下的内容。
编辑:
鉴于您最近的评论,我认为您需要放弃使用context
命名空间并直接使用幕后使用的Spring对象。也许是这样的:
在applicationContext.xml中:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath*:META-INF/spring/*.properties" />
</bean>
在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>
我猜你希望本地属性覆盖从类路径资源定义的属性,所以我将localOverride
定义为true。
答案 2 :(得分:3)
如果在主applicationContext.xml中使用PropertiesFactoryBean指定了下面列出的几个属性查找,则不会加载任何遗漏的属性文件,并使用上次成功加载的属性文件。在您的情况下,将加载default.properties(例如您的测试属性文件),并且因为第二个文件:$ {catalina} ...将不会被加载,您的@Value字段将注入默认值指定的值。属性。
摘自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>
答案 3 :(得分:1)
我通过将applicationContext.xml
拆分为两个文件来解决问题:
- applicationContext.xml
- 包含“普通”bean,但不包括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>
Web应用程序在启动时加载两个文件:
web.xml
:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
对于我的测试,我添加了一个propoperties文件:simulatedTomcat.test-properties
,其中包含所有tomcat属性。 注意:此文件与applicationContext-properties.xml
的属性占位符配置程序使用的模式不匹配
然后我为我的测试设置了一个属性占位符配置器,它加载了两种类型的操作属性文件(*.properties
和*.test-properties
)
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>