簡體   English   中英

使用SpEL表達式和PropertyPlaceHolder設置Spring bean類名

[英]Setting a Spring bean class name using a SpEL expression and PropertyPlaceHolder

更新:截至2016年12月9日的決議摘要

根據@ altazar下面的回答, 現在可以從Spring 4.2開始了!

截至2012年3月29日的舊決議摘要

截至此日期,Spring SpEL 無法<bean>class屬性中執行

原始問題:

我正在嘗試為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引導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語法? 還是另一個問題?

BTW我知道新的3.1配置文件功能,但我想通過SPeL這樣做有各種原因。 此外,我意識到我正在使用基於文件系統的上下文和路徑 - 我也有理由。

你可以用factoryBean完成你想要的東西:

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

其中MyFactoryBean是一個簡單的FactoryBean實現,返回指定類的實例。

從Spring 4.2開始, 可以在class屬性中使用SpEl,因此以下工作正常:

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

在我的情況下占位符${is.debug.mode:false}不起作用,所以我明確地解析它。

你可以這樣做。

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

然后

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM