使用 SpEL 表达式和 PropertyPlaceHolder 设置 Spring bean 类名称

问题描述 投票:0回答:4

更新:截至 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 来执行此操作。 我还意识到我正在使用基于文件系统的上下文和路径 - 我也有这样做的原因。

java spring
4个回答
4
投票
你可以用一个factoryBean来完成你想要的事情:

<bean id="example" class="MyFactoryBean"> <property name="class" value="#{ ${is.debug.mode} ? com.springtest.ExampleDebug : com.springtest.ExampleProd}"/> </bean>

其中 MyFactoryBean 是一个简单的 FactoryBean 实现,返回指定类的实例。


2
投票
你可以做到这一点。

debug.class=com.springtest.ExampleDebug #debug.class=com.springtest.ExampleProd

然后

<bean id="example" class="${debug.class}"/>
    

2
投票
从 Spring 4.2 开始

可以在类属性中使用 SpEl,因此以下效果很好:

<bean id="example" class="#{T(java.lang.Boolean).parseBoolean('${is.debug.mode:false}') ? 'com.springtest.ExampleDebug' : 'com.springtest.ExampleProd'}"/>

在我的例子中,占位符

${is.debug.mode:false}

 不起作用,所以我明确地解析它。


0
投票
然后跑步:

java -jar -Dis.debug.mode=true

属性不起作用:

is.debug.mode=true

© www.soinside.com 2019 - 2024. All rights reserved.