2012-07-31 49 views
5

我需要爲我們的spring項目開發和生產設置。我知道你可以使用春天的個人資料,但這不是我們能做的事情。基於tomcat servlet上下文定義的spring加載application.properties

我想要做的就是在開發環境中放置一個test-application.properties文件,並在生產環境中放置一個prod-application.properties文件。在Tomcat上下文定義我們發送以下內容:

<Context> 
    <context-param> 
     <param-name>properties_location</param-name> 
     <param-value>file:C:\Users\Bill\test-application.properties</param-value> 
    </context-param> 
</Context> 

而且我們可以改變生產服務器的價值。在Spring配置,我們有這樣的事情:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>${properties_location}</value> 
     </list> 
    </property> 
    <property name="ignoreUnresolvablePlaceholders" value="false" /> 
</bean> 

但是我們不斷收到這樣的錯誤:

org.springframework.beans.factory.BeanInitializationException:難道 無法加載性能;嵌套的例外是 java.io.FileNotFoundException:無法打開ServletContext的資源 [/ $ {properties_location}]

上的任何想法如何解決?

回答

8

PropertyPlaceholder的一個特性是您可以定義多個資源位置。 因此,例如,你可以定義your-production-config.properties文件一起:C:/用戶/ $ {user.name} /test-application.properties

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>classpath:your-production-config.properties</value> 
      <value>file:C:/Users/${user.name}/test-application.properties</value> 
     </list> 
    </property> 
    <property name="ignoreUnresolvablePlaceholders" value="true"/> 
    <property name="ignoreResourceNotFound" value="true"/> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>   
</bean> 

您需要生產將prod配置放置到類路徑的某處(對於本地環境來說真的不重要) - 對於本地環境,您可以使用如下所示的轉義方式:C:/ Users/$ {user.name} /test-application.properties

+0

我做了同樣的事情,但忘記了ignoreResourceNotFound。現在工作。感謝你的回答! – checklist 2012-07-31 09:56:36

+0

另外,由於您指示了SYSTEM_PROPERTIES_MODE_OVERRIDE,所以在java調用時使用-D指定的任何屬性都將覆蓋在屬性文件中找到的內容,因此'java -Duser.name = ted ...'將優先。使用ignoreResourceNotFound,屬性文件也可以選擇性地不存在,而不會拋出異常。 – 2015-03-19 23:22:18

0

使用:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>C:/Users/Bill/test-application.properties</value> 
     </list> 
    </property> 
    <property name="ignoreUnresolvablePlaceholders" value="false" /> 
</bean> 

下面的代碼從web.xml

<Context> 
    <context-param> 
     <param-name>properties_location</param-name> 
     <param-value>file:C:\Users\Bill\test-application.properties</param-value> 
    </context-param> 
</Context> 
+0

我的觀點是將屬性文件的位置放在war文件的外部,因此不能放入bean定義中。謝謝 – checklist 2012-07-31 08:25:03

1

我結束了不使用上下文參數解決它刪除。相反,我們已經定義了

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>classpath:application.properties</value> 
      <value>file:C:\Users\Bill\prod-application.properties</value> 
     </list> 
    </property> 
    <property name="ignoreUnresolvablePlaceholders" value="true" /> 
    <property name="ignoreResourceNotFound" value="true"/> 
</bean> 

這種方式試圖加載這兩個文件。在測試服務器上,我們沒有prod文件,所以它沒有加載。在prod服務器上,prod-application.properties文件存在並覆蓋類路徑中的測試。繁瑣但有效!

+0

儘管這樣做有效,但如果春天有更好的解決方案,它本來會很好。我確信有很多人將應用程序部署到tomcat並且想要將道具外化 – checklist 2012-07-31 11:57:16

1

就個人而言,儘量避免指定位置。我認爲最適合你的是使用JNDI來實現這一點。

到Tomcat/conf目錄/ server.xml中

<Resource name="jdbc/prod" auth="Container" 
      type="javax.sql.DataSource" driverClassName="${database.driverClassName}" 
      url="${database.url}" 
      username="${database.username}" password="${database.password}" 
      maxActive="20" maxIdle="10" 
      maxWait="-1"/> 

,並在Tomcat中catalina.properties(如果使用的是Oracle XE否則應相應地):

database.driverClassName=oracle.jdbc.driver.OracleDriver 
database.url=jdbc:oracle:thin:@//localhost:1521/XE 
database.username=user 
database.password=password 

在應用程序中創建的屬性文件你的類路徑名爲jdbc。屬性。並且把以下(如果使用的是Oracle XE否則相應修改)

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver 
jdbc.url=jdbc:oracle:thin:user/[email protected]//localhost:1521/XE 

然後在Spring的applicationContext.xml

<context:property-placeholder location="classpath:jdbc.properties" /> 

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="java:comp/env/jdbc/prod" /> 
    <property name="defaultObject" ref="dataSourceFallback" /> 
</bean> 
<bean id="dataSourceFallback" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="${jdbc.driverClassName}" /> 
    <property name="url" value="${jdbc.url}" /> 
    <property name="poolPreparedStatements"> 
     <value>true</value> 
    </property> 
    <property name="maxActive"> 
     <value>4</value> 
    </property> 
    <property name="maxIdle"> 
     <value>1</value> 
    </property> 
</bean> 
2
<context:property-placeholder location="file:${catalina.home}/conf/myFirst.properties" ignore-unresolvable="true" /> 
<context:property-placeholder location="classpath:second.properties" ignore-unresolvable="true" /> 

我不喜歡它上面。 catalina.home變量允許在tomcat home conf目錄中顯示屬性文件。

0

如果你正在使用的tcServer和server.xml中配置資源,如數據庫,隊列等可以使用com.springsource.tcserver.properties.SystemProperties

Delcare這個監聽器在server.xml中像下面

<Listener className="com.springsource.tcserver.properties.SystemProperties" 
      file.1="${catalina.base}/conf/password.properties" 
      file.2="${catalina.base}/conf/server.properties" 
      immutable="false" 
      trigger="now"/> 

現在您可以將屬性外部化到兩個文件password.properties和server.properties。

相關問題