2012-07-31 70 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。

相关问题