将属性添加到属性占位符

时间:2011-06-17 14:37:35

标签: java unit-testing spring properties

我有一个应用程序,其中使用属性占位符来读取属性,在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,这当然不起作用 - 所以我的问题是,我可以在测试中的“普通”属性占位符中扩展属性吗?


更多我需要的解释:

  • 生产环境(以及开发环境)通过Tomcat参数定义一些属性。因此,它们不包含在任何属性文件中,但可以像普通属性(@Value(${cfma.applicationUrl}))那样无神经地访问它们。此外,一定不能有任何回退,如果没有在Tomcat中定义属性,应用程序一定不能启动!
  • 在测试用例(使用spring上下文)中,我必须介绍如何插入属性(cfma.applicationUrl),以便可以将其注入带注释的变量中。 但是,如果我添加第二个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>

4 个答案:

答案 0 :(得分:5)

不确定这是否有帮助,但我在类似情况下做的是有2个app.properties文件同名,一个在sec / test / resources中,另一个在src / main / resources中。现在在测试期间第一个被加载,因为测试类首先在类路径上,但是当我部署时只有主要的那个在那里,所以它被加载。

答案 1 :(得分:3)

如果您将location属性添加到context:property-placeholdertestContext.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>