【问题标题】:Why is the ${} variable not interpreted as a constructor-arg value, in my context file?为什么在我的上下文文件中 ${} 变量没有被解释为构造函数参数值?
【发布时间】:2012-05-03 11:05:16
【问题描述】:

我有一个 Spring 3.1 应用程序,我尝试在上下文文件中使用系统变量。变量“JAVA_MY_ENV”是在我的系统上定义的(在 Windows 上,它位于控制面板的“系统变量”中)。

在 web.xml 中,我可以将它用作变量并且它可以工作,它成功地被变量的实际值替换(比如说“electrotype”):

<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener> 
<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:log/${JAVA_MY_ENV}.log4j.properties</param-value>
</context-param>

我也可以在我的主要“bean”上下文中使用它来进行导入,它也可以工作:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"       
        xmlns:tx="http://www.springframework.org/schema/tx" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.1.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!-- (...) -->

    <import resource="classpath:spring/app-config.xml" />
    <import resource="classpath:spring/env/context-env-${JAVA_MY_ENV}.xml" />

</beans>

但是在“app-config.xml”,我的其他上下文文件之一,我尝试了这个,它不起作用

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"       
        xmlns:tx="http://www.springframework.org/schema/tx" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.1.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <bean id="appConfiguration" class="com.xxx.app.AppConfiguration">
        <constructor-arg value="${JAVA_MY_ENV}" />
    </bean>

</beans>

com.xxx.app.AppConfiguration 接收字符串“${JAVA_MY_ENV}”作为构造函数参数,而不是它的解释值!

我不确定在哪里解释 ${} 变量以及在哪里不解释。

有没有办法可以将解释的 ${JAVA_MY_ENV} 值传递给我的 com.xxx.app.AppConfiguration 构造函数?

【问题讨论】:

    标签: java spring spring-mvc servlets


    【解决方案1】:

    从 Spring 的 3.0 开始,您应该将值注入属性

    @Value("#{ systemProperties['JAVA_MY_ENV'] }") 
    private String myVar;
    

    <property name ="myVar" value="#{systemProperties['JAVA_MY_ENV']}"/>
    

    或者,您可以考虑使用 PropertySourcesPlaceholderConfigurer 或类似的类。创建它会告诉 spring 如何查找变量。我经常制作一些属性文件,以便应用程序可以使用环境和内部属性文件值。例如

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="locations">
        <list>
            <value>classpath:someprops.properties</value>
        </list>
      </property>
      <property name="ignoreResourceNotFound" value="true" />
      <property name="searchSystemEnvironment" value="true" />
      <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    

    上述示例中的一个关键元素是“searchSystemEnvironment”设置为 true。这告诉 spring 使用 env 变量(这是你想要的)

    【讨论】:

    • 问题是我没有使用“-DJAVA_MY_ENV=electrotype”启动我的应用程序,而是将 JAVA_MY_ENV 设置为系统全局变量。在我的应用程序中,System.getenv("JAVA_MY_ENV") 返回“electrotype”,但 System.getProperty("JAVA_MY_ENV") 返回 NULL。 @Value("#{ systemProperties['JAVA_MY_ENV'] }") 也是 NULL。我希望能够使用 web.xml 使用的 完全相同 ${JAVA_MY_ENV} 变量,以确保值也相同!使用 PropertyPlaceholderConfigurer,我不确定它是“-D”变量还是全局系统属性(如果我有一天同时使用这两种属性,出于某种原因)。谢谢。
    【解决方案2】:

    使用 BruceLowe 建议的 PropertyPlaceholderConfigurer 是可行的。我发现解决特定属性的另一种方法(可能更复杂)是使用:

    <bean id="JAVA_MY_ENV" class="org.springframework.util.SystemPropertyUtils" factory-method="resolvePlaceholders">
        <constructor-arg value="${JAVA_MY_ENV}" /> 
    </bean>
    

    这将创建一个 String bean,其中包含 ${JAVA_MY_ENV} 的 已解析 值!

    然后我可以在任何可以使用 bean ref 的地方使用这个 bean。例如作为构造函数参数:

    <bean id="appConfiguration" class="com.xxx.app.AppConfiguration">
        <constructor-arg ref="JAVA_MY_ENV" />
    </bean>
    

    所以现在我在解释它的地方使用 ${JAVA_MY_ENV},而不添加 PropertyPlaceholderConfigurer,否则使用 JAVA_MY_ENV bean。

    【讨论】:

      【解决方案3】:

      <context:property-placeholder> properties not accessible to the child (web) context 可能重复 据我了解,这是预期的行为。您应该只在 servlet 上下文中注入 bean,或者将配置 bean 包含到 servlet-context.xml 中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-13
        • 1970-01-01
        • 1970-01-01
        • 2014-06-18
        • 1970-01-01
        相关资源
        最近更新 更多