更新:截至2016年12月9日的决议摘要
根据@ altazar在下面的回答,this is now possible从春季4.2开始!
截至2012年3月29日的旧决议摘要
截至此日期,在class
的{{1}}属性中,Spring SpEL 无法执行。
原始问题:
我正在尝试为Spring bean实现动态<bean>
属性,最终使用class
属性和SpEL表达式的组合进行设置。目的是选择要实例化的类的生产版本或调试版本。它不起作用,我想知道是否有可能实现。
到目前为止,我有以下内容:
平面属性文件:
PropertyPlaceHolder
Spring XML配置:
is.debug.mode=false
Spring引导程序Java代码:
<bean id="example"
class="#{ ${is.debug.mode} ?
com.springtest.ExampleDebug :
com.springtest.ExampleProd}"
/>
错误消息(为清晰起见,删除了大量空格):
// 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
属性已成功加载并替换。但是别的东西出了问题。它是我在Java中的引导序列吗?或者XML中的SPeL语法?还是另一个问题?
BTW我知道新的3.1配置文件功能,但我想通过SPeL这样做有各种原因。此外,我意识到我正在使用基于文件系统的上下文和路径 - 我也有理由。
答案 0 :(得分:4)
你可以用factoryBean完成你想要的东西:
<bean id="example" class="MyFactoryBean">
<property name="class" value="#{ ${is.debug.mode} ? com.springtest.ExampleDebug : com.springtest.ExampleProd}"/>
</bean>
其中MyFactoryBean是一个简单的FactoryBean实现,返回指定类的实例。
答案 1 :(得分:2)
你可以这样做。
debug.class=com.springtest.ExampleDebug
#debug.class=com.springtest.ExampleProd
然后
<bean id="example" class="${debug.class}"/>
答案 2 :(得分:2)
从Spring 4.2开始is possible在类属性中使用SpEl,以便以下工作正常:
<bean id="example"
class="#{T(java.lang.Boolean).parseBoolean('${is.debug.mode:false}') ?
'com.springtest.ExampleDebug' :
'com.springtest.ExampleProd'}"/>
在我的情况下占位符${is.debug.mode:false}
不起作用,所以我明确解析它。