【问题标题】:PropertyPlaceholderConfigurer with Tomcat & ContextLoaderListener带有 Tomcat 和 ContextLoaderListener 的 PropertyPlaceholderConfigurer
【发布时间】:2011-11-20 13:19:04
【问题描述】:

我将 PropertyPlaceholderConfigurer 与 Tomcat 和 ContextLoaderListener 一起使用。

这可行(使用硬编码的属性文件的名称):

<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:properties/test.properties"/>
</bean>

但是这个(将属性文件的名称替换为 ${env}):

<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:properties/${env}.properties"/>
</bean>

[Thread-2] 15:50:16 ERROR ContextLoader - 上下文初始化失败 org.springframework.beans.factory.BeanInitializationException:无法加载属性;嵌套异常是 java.io.FileNotFoundException:类路径资源 [properties/${env}.properties] 无法打开,因为它不存在

我知道该文件在那里,因为当我对其进行硬编码时它可以工作。

我尝试在启动 Tomcat 并设置环境变量时使用 -Denv=test。我使用自己的 main 方法而不是 ContextLoaderListener 在 Tomcat 之外工作。

我可能做错了什么?我可以使用 context.xml 或 web.xml 中的条目而不是 -Denv=test 来实现相同的目的吗?

谢谢

PS 我也试过了:

<bean id="initialcorePropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName">
        <value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
    </property>
    <property name="searchSystemEnvironment">
        <value type="boolean">true</value>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>

<bean id="corePropertyConfigurer" depends-on="initialcorePropertyConfigurer" lazy-init="true"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:properties/${env}.properties" />
</bean>

但我得到了同样的错误。

【问题讨论】:

    标签: java spring tomcat


    【解决方案1】:

    您不能在 PropertyPlaceholderConfigurer 定义中使用属性占位符。鸡和蛋。

    但是你可以使用#{ systemProperties['env'] }

    或者您可以继承 PropertyPlaceholderConfigurer 并覆盖 setLocation() 来处理占位符。

    【讨论】:

    • 我在您的 PropertyPlaceholderConfigurer 定义中有一个属性占位符工作得很好。但只能使用我自己的 main 方法,而不是使用 Tomcat 和 ContextLoaderListener。此外,即使我在电子邮件末尾使用 2 PropertyPlaceholderConfigurer,它仍然会出现同样的问题。
    • 谢谢。我根据您的建议将 ${env} 更改为 #{ systemProperties['env'] } 并解决了错误。我仍然不清楚为什么它适用于我自己的 main 但不适用于 Tomcat 和 ContextLoaderListener。
    【解决方案2】:

    您需要将环境变量 CATALINA_OPTS 或 JAVA_OPTS 设置为 -Denv=test。最好的方法是创建一个 setenv.bat(或者 .sh,如果你在 unix 上)并在那里添加这个环境变量定义。

    如果你将它作为参数传递给 startup.bat (.sh),它不会生效,我假设你在做什么。

    【讨论】:

    • 谢谢。我刚刚尝试过,似乎没有什么不同。我已经添加了一个简单的 servlet
    • 谢谢。我刚刚尝试过,似乎没有什么不同。我已经添加了一个 servlet,它执行一个简单的 System.getProperties(),然后将它们打印出来。我在该列表中看到了属性 env 。所以它在我的 Tomcat 代码中可用。
    【解决方案3】:

    设置完整的位置,例如-DpropFileLocation=classpath:env1.properties-DpropFileLocation=classpath:env2.properties,而不仅仅是其中的一部分:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreResourceNotFound" value="true"/>
        <property name="location" value="${propFileLocation}"/>
    </bean>
    

    【讨论】:

    • 毕竟它是一个黑客,有更干净的方法来做到这一点。
    【解决方案4】:

    此论坛上有一个similar question,其中需要将属性文件外部化。查看this solution。它认为您的问题类似,而不是将 env 作为系统变量传递,而是将其设置为 env variable 。

    【讨论】:

    • 谢谢。我已经尝试使用环境变量并得到了同样的错误。
    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 2023-03-03
    • 2016-09-12
    • 1970-01-01
    相关资源
    最近更新 更多