更新:截至 2016 年 12 月 9 日的决议摘要
根据下面 @altazar 的回答,从 Spring 4.2 开始,这现在是可能的!
截至 2012 年 3 月 29 日的旧决议摘要
截至目前,Spring SpEL无法在 class
的
<bean>
属性内执行。
原问题:
我正在尝试为 Spring bean 实现动态class
属性,最终使用
PropertyPlaceHolder
属性和 SpEL 表达式的组合进行设置。目的是选择要实例化的类的生产版本或调试版本。 它不起作用,我想知道是否可以实现。到目前为止,我有以下内容:
平面属性文件:
is.debug.mode=false
Spring XML 配置:
<bean id="example"
class="#{ ${is.debug.mode} ?
com.springtest.ExampleDebug :
com.springtest.ExampleProd}"
/>
Spring bootstrap Java代码:
// Get basic ApplicationContext - DO NOT REFRESH
FileSystemXmlApplicationContext applicationContext = new
FileSystemXmlApplicationContext
(new String[] {pathSpringConfig}, false);
// Load properties
ResourceLoader resourceLoader = new DefaultResourceLoader ();
Resource resource = resourceLoader.getResource("file:" + pathProperties);
Properties properties = new Properties();
properties.load(resource.getInputStream());
// Link to ApplicationContext
PropertyPlaceholderConfigurer propertyConfigurer =
new PropertyPlaceholderConfigurer() ;
propertyConfigurer.setProperties(properties) ;
applicationContext.addBeanFactoryPostProcessor(propertyConfigurer);
// Refresh - load beans
applicationContext.refresh();
// Done
Example example = (Example) applicationContext.getBean("example");
错误消息(为了清晰起见,删除了大量空格):
Caused by: java.lang.ClassNotFoundException:
#{ true ? com.springtest.ExampleDebug : com.springtest.ExampleProd}
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
. . .
通过消息中的“
true
”可以看到,
is.debug.mode
属性已成功加载并替换。 但还有其他事情出了问题。 这是我在 Java 中的引导序列吗? 或者 XML 中的 SPeL 语法? 还是其他问题?顺便说一句,我知道新的 3.1 配置文件功能,但出于多种原因我想通过 SPeL 来执行此操作。 我还意识到我正在使用基于文件系统的上下文和路径 - 我也有这样做的原因。
<bean id="example" class="MyFactoryBean">
<property name="class" value="#{ ${is.debug.mode} ? com.springtest.ExampleDebug : com.springtest.ExampleProd}"/>
</bean>
其中 MyFactoryBean 是一个简单的 FactoryBean 实现,返回指定类的实例。
debug.class=com.springtest.ExampleDebug
#debug.class=com.springtest.ExampleProd
然后
<bean id="example" class="${debug.class}"/>
<bean id="example"
class="#{T(java.lang.Boolean).parseBoolean('${is.debug.mode:false}') ?
'com.springtest.ExampleDebug' :
'com.springtest.ExampleProd'}"/>
在我的例子中,占位符
${is.debug.mode:false}
不起作用,所以我明确地解析它。
java -jar -Dis.debug.mode=true
属性不起作用:
is.debug.mode=true