5

我需要为我们的 spring 项目进行开发和生产设置。我知道您可以为 spring 使用配置文件,但这不是我们可以做的。

我想要做的是在开发环境中放置一个 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}]

关于如何解决的任何想法?

4

6 回答 6

8

PropertyPlaceholder 的一项功能是您可以定义多个资源位置。因此,例如,您可以定义your-production-config.properties以及file:C:/Users/${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

于 2012-07-31T09:12:07.127 回答
2

我最终通过不使用上下文参数来解决它。相反,我们定义了

<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 文件存在并覆盖了类路径中的测试。繁琐但有效!

于 2012-07-31T08:34:28.263 回答
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 目录中。

于 2012-07-31T09:42:46.023 回答
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.properties 的类路径中创建属性文件并放置以下内容(如果使用 Oracle XE,则相应地进行更改)

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:user/password@//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>
于 2012-07-31T09:30:04.880 回答
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>
于 2012-07-31T07:58:08.370 回答
0

如果您使用 Tcserver 和 server.xml 来配置数据库、队列等资源,您可以使用 com.springsource.tcserver.properties.SystemProperties

在 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。

于 2017-04-21T13:57:32.890 回答