Java 为什么在我的上下文文件中,${}变量没有被解释为构造函数arg值?

Java 为什么在我的上下文文件中,${}变量没有被解释为构造函数arg值?,java,spring,spring-mvc,servlets,Java,Spring,Spring Mvc,Servlets,我有一个Spring3.1应用程序,我尝试在上下文文件中使用一个系统变量。变量“JAVA_MY_ENV”是在我的系统上定义的(在Windows上,它位于控制面板的“系统变量”中) 在web.xml中,我可以使用它作为变量,并且它可以工作,它成功地被变量的实际值替换(比如“电类型”): org.springframework.web.util.Log4jConfigListener log4jConfigLocation classpath:log/${JAVA_MY_ENV}.log4j.pr

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

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


org.springframework.web.util.Log4jConfigListener
log4jConfigLocation
classpath:log/${JAVA_MY_ENV}.log4j.properties
我还可以在我的主“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”中,我尝试了以下方法,但没有成功:


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

我不确定${}变量在哪里解释,在哪里不解释


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

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

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


或者,您可以研究如何使用PropertySourcesPlaceholderConfigurer或类似的类。创建它将告诉spring如何查找变量。我通常也会制作一些属性文件,以便应用程序可以使用环境和内部属性文件值。e、 g

<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" />

类路径:someprops.properties


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

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

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

这将创建一个字符串bean,其中包含${JAVA_MY_ENV}的解析值

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

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

因此,现在我在解释${JAVA_MY_ENV}的地方使用${JAVA_MY_ENV},而不添加PropertyPlaceHolderConfigure,否则使用JAVA_MY_ENV bean。

可能重复的
据我所知,这是预期的行为。您应该只在servlet上下文中注入bean,或者将配置bean包含到servlet context.xml

中。问题是,我没有用“-DJAVA_my_ENV=electrotype”启动我的应用程序,而是将JAVA_my_ENV设置为系统全局变量。在我的应用程序中,System.getenv(“JAVA_my_ENV”)返回“electrotype”,但System.getProperty(“JAVA_my_ENV”)返回NULL@值(“#{systemProperties['JAVA_MY_ENV']}”)也为空。我希望能够使用web.xml使用的${JAVA_MY_ENV}变量,以确保值也相同!对于PropertyPlaceHolderConfigure,我不确定它是“-D”var还是全局系统属性(如果有一天出于某种原因同时使用这两个属性)。谢谢
<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" />
<bean id="JAVA_MY_ENV" class="org.springframework.util.SystemPropertyUtils" factory-method="resolvePlaceholders">
    <constructor-arg value="${JAVA_MY_ENV}" /> 
</bean>
<bean id="appConfiguration" class="com.xxx.app.AppConfiguration">
    <constructor-arg ref="JAVA_MY_ENV" />
</bean>