2011-06-17 248 views
5

我有其中屬性佔位符被用於讀取的屬性,配置在applicationContext.xml的應用程序:添加屬性屬性佔位符

... 
<context:property-placeholder 
    location="classpath*:META-INF/spring/*.properties"/> 
... 

中的應用在一個Tomcat的運行,並使用在context.xml中定義的參數。 應用程序像普通屬性一樣訪問此參數(@Value(${cfma.applicationUrl}))。 This works

在我的測試用例中,我沒有這個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> 

現在我有兩個方面:財產佔位符,這不工作(當然) - 所以我的問題是,誰能夠延長我我的測試中的「正常」屬性佔位符中的屬性?


更多解釋的什麼,我需要:

  • 生產環境(以及開發環境)定義了通過Tomcat的參數的一些屬性。因此,它們不包含在任何屬性文件中,但它們可以像普通屬性一樣無法訪問(@Value(${cfma.applicationUrl}))。此外,如果屬性沒有在Tomcat中定義,則不能有任何回退,應用程序一定不能啓動!
  • 在測試用例(使用spring上下文)中,我必須介紹如何插入屬性(cfma.applicationUrl),以便它可以注入到帶註釋的變量中。 但如果我添加第二context:property-placeholder他們不會被合併:在https://jira.springsource.org/browse/SPR-4881

@see評論 - 他們解釋這種行爲。


當我談到我說的somethink這樣Tomcat的參數:

的context.xml:

如果在同一 location屬性添加到定義的 context:property-placeholder
<?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

見http://stackoverflow.com/questions/6375016/spring-properties-file-setting-default-values它有效地允許您定義多個屬性的位置。缺少屬性文件將被忽略,並且加載列出的最後一個有效文件。 – Fil

+0

@Filip:我的問題不是關於多個位置。我得到了多個屬性佔位符配置器的困擾。我正在尋找一種方法來擴展/更改「正常」應用程序上下文屬性佔位符配置器的配置從我的test-context.xml – Ralph

+0

抱歉。我的評論不是很清楚,我沒有提出一種指定多個屬性文件的方法,而是一種執行條件屬性查找的方法。下面是一個擴展的答案。 – Fil

回答

5

不知道這是否會幫助,但我在一個類似的情況做的是有2個app.properties文件具有相同的名字,一個以秒/測試/資源另一個在src/main/resources中。現在在測試期間,第一個被加載,因爲測試類首先在類路徑上,但是當我只部署主要的一個在那裏,因此它被加載。

+0

因爲我的問題屬於其他屬性,我的解決方法是在測試/資源(Maven基礎項目)中爲我的測試添加一個額外的屬性文件。 – Ralph

+0

是的,我最終複製了兩個文件中的屬性! –

3

它的工作原理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爲真正的本地屬性來覆蓋從classpath資源定義的屬性。

+0

不幸的是,這並沒有幫助。我的理解是,我的問題是,如果我有兩個'context:property-placeholder'的定義,我也必須要屬性佔位符,而不是合併。 – Ralph

+0

我期望'testContext.xml'中的一個會覆蓋'applicationContext.xml'中的一個,如果它是第二個加載的。你看到的不正確的行爲是什麼? – laz

+0

是不正確的,它是預期的(它不適用於兩個上下文:屬性佔位符)。行爲是,測試中不填充字段@Value($ {cfma.applicationUrl})。 - 我正在尋找一種方法來從我的testContext.xml中的applicationContex.xml「擴展」property-placeholder。 – Ralph

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> 
+0

因此,您的建議與''的區別並不在於此。 - 至少你建議有一個額外的測試屬性文件 - 對嗎?確切地說, – Ralph

+0

。而且您還可以擴展PropertiesFactoryBean以更貼近您的需求;我使用它來幫助我加載不同的配置文件,具體取決於我在做什麼(例如,使用JNDI進行查找,或使用本地H2數據庫,使用DBUnit等進行種子...) – Fil

1

我在兩個文件分裂了applicationContext.xml解決了這個問題: - applicationContext.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> 

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>