Spring中手動增加配置文件中占位符引用的變量


在項目中遇到一個這樣的需求,項目的配置文件由外部傳入,這時spring配置文件那些占位符變量該如何取值呢?

解決這個問題的做法有幾種,我想到的大概有以下三種:

1.通過系統屬性來實現,把外部傳入的配置信息保存到系統屬性,spring配置中的占位符可以獲取到系統屬性的值.這種做法很簡單,調用System.setProperty() | setProperties()方法就可以實現。

2.把外部的配置信息動態寫入到配置文件,生成配置文件之后再啟動spring.spring的配置文件中需要把生成配置文件的配置寫到PropertyPlaceholderConfigurerlocation屬性。這種方式有點繞,還可以更優雅一點。

3.我們知道spring配置文件中占位符替換是在PropertyPlaceholderConfigurer類中實現的,也就是說該類中必定維護了一種占位符變量與該值的Map數據結構(實際上是Properties,當然Properties本身就是基於Hashtable實現的),我們只需要找到該集合,spring加載完其他配置文件以后往這個集合中添加我們自定義的配置,也可以同樣解決這個需求.並且個人覺得這個方式相比之前兩種都有意思點。

這篇文章我們主要討論第三種實現方式,首先說解決辦法,之后再簡單說下這樣的原因。解決辦法就是自定義一個類,繼承PropertyPlaceholderConfigurer,復寫processProperties(),實際上該類是spring中的一個后處理器(BeanFactoryPostProcessor)

 

import java.util.Map;
import java.util.Properties;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
/**
 * 擴展PropertyPlaceholderConfigurer類,不僅可以加載配置文件中的配置信息,還可以手動增加其他配置
 *    使用該類前,在spring配置文件中增加如下配置:
     <bean class=" com.xxx.aaa.context.ExternalPropertyResourceInjector">
         <!-- 如果還要加載module.properties文件中的配置信息,添加如下配置 -->
        <property name="locations">
            <list>
                <value>classpath:module.properties</value>
            </list>
        </property>
    </bean>    
    注:該類是PropertyPlaceholderConfigurer的子類,如果配置了該類,無需在重復配置PropertyPlaceholderConfigurer
    
 * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
 * @author Jack
 */
public class ExternalPropertyResourceInjector extends PropertyPlaceholderConfigurer {

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
        Map<String,String> map = new HashMap<String,String>();
// map.put(key,value) ... 添加配置信息
        props.putAll(map);
        super.processProperties(beanFactory, props);
    }

}

 

配置bean:

 

<bean class=" com.xxx.aaa.context.ExternalPropertyResourceInjector">
    <!-- 如果還要加載其他配置文件,配置locations屬性即可
        <property name="locations">
            <list>
                <value>classpath:module.properties</value>
            </list>
        </property>
     -->
</bean>

 

上面說了解決的辦法,現在來看下解決該問題兩個關鍵的地方,其一,在於弄清楚spring在哪個地方替換配置文件中所使用到占位符?第二個關鍵在於找到spring加載占位符中變量值配置文件之后保存配置的集合。這兩個點都需要對照源碼才能找到.

這兩個關鍵的地方都都可以從PropertyPlaceholderHelper可以入手.replacePlaceholders()方法處設置斷點,debug模式下可以清晰看到占位符的替換過程。

 

parseStringValue()方法中的147行可以看到占位符取值來源何處.

從以上兩點順藤摸瓜就能找到spring加載配置文件並進行占位符替換的流程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM