情况如下:
xml配置如下所示:
<bean id="ppConfig1"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:c:\test\env.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
<bean id="string" class="java.lang.String" depends-on="ppConfig1">
<constructor-arg value="${env.app.type}"/>
</bean>
<bean id="ppConfig2"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="string">
<property name="locations">
<list>
<value>file:c:\test\#{string}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false" />
</bean>
很明显,我想根据env.app.type
中的密钥C:\test\env.properties
的值加载特定的属性文件(例如app1.properties)。
加载/测试上述配置的代码如下所示:
ApplicationContext context = new ClassPathXmlApplicationContext(
"SpringBeans.xml");
String ss = (String)context.getBean("string");
System.out.println(ss);
这似乎不起作用。它失败并出现以下错误:
线程“main”中的异常 org.springframework.beans.factory.BeanInitializationException:可以 不加载属性;嵌套异常是 java.io.FileNotFoundException:C:\ test \ $ {env.app.type} .properties(The 系统找不到指定的文件) org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:87)
文件c:\test\env.properties
如下所示
env.app.type = APP1
一个有趣的观察结果是,当我注释掉ppConfig2
时,一切正常,并打印出env.app.type
的正确值。我愿意接受任何其他建议来解决这个问题。我的基本要求是在运行时根据env.properties中指定的属性选择属性文件。 (我使用的是春季3.1.0)
答案 0 :(得分:1)
你需要这样的东西:
<context:component-scan base-package="com.foo.bar" />
<context:property-placeholder location="file:c:/test/${env.app.type}.properties" />
<bean id="service" class="com.foo.bar.ExampleService">
<property name="foo" value="${foo}" />
</bean>
package com.foo.bar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("file:c:/test/env.properties")
public class SpringConfig{
}
&#34; foo&#34;值来自app1.properties
文件。基本上,一个文件正在加载@PropertySource
,另一个文件正在加载常规属性占位符。
答案 1 :(得分:0)
我认为你正在尝试做一些Spring不喜欢的事情。 bean初始化的正常顺序是:
只要这3个传递被完全分开,一切都会好的,但你有一个后处理器bean(ppConfig2
),这取决于一个简单的bean(string
)。
使用环境变量或系统属性来避免bean后处理器依赖于另一个bean后处理器是否可以接受?如果是的话,你不会被ppConfig1
打扰而只是:
<bean id="ppConfig2"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="string">
<property name="locations">
<list>
<value>file:c:\test\${configured_env}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false" />
</bean>
如果环境变量或系统属性不是一个选项,您可以使用Andrei Stefan建议的编程配置。
答案 2 :(得分:0)
您可以使用util:properties
:
<util:properties id="envProperties" location="env.properties"/>
<util:properties id="properties" location="#{envProperties.getProperty('env.app.type')}.properties"/>
<context:property-placeholder properties-ref="envProperties" ignore-unresolvable="true" ignore-resource-not-found="true"/>
<context:property-placeholder properties-ref="properties" ignore-unresolvable="true"/>
顺便说一下,Spring中有一个bug,阻止在location
context:property-placeholder
{{1}}内的{{1}}属性中评估Spring EL。