天天看點

Spring中代碼實作讀取properties值Spring代碼實作讀取properties值

Spring代碼實作讀取properties值

讀取properties這個工作基本都是項目必備。本人慣用的架構是spring,如果是bean的話,那就很簡單,在xml中配置下,然後用@value取值,蠻友善的。但是很多時候,我們需要程式設計方式取得Spring上下文的Properties。廢話不多說下面開始。

實作的方法有很多種,我這裡@value的讀取方式我就不詳說了,網上一大把。主要講解下用編碼方式實作讀取properties。

方法一:

利用JDK 内置的java.util.Properties 類為我們操作properties 檔案提供了便利。純粹的Java語言來讀取properties,任何的Java項目都可以使用。我通過靜态塊,當類加載的時候就運作讀取properties檔案,并一一讀取裡面的内容,并暴露出去。代碼如下:

public class PropertiesUtils {

    private static Properties properties;  

    static {
        properties = new Properties();
        String fileName = "config/qiniuConfig.properties";
        InputStream in = PropertiesUtils.class.getClassLoader().getResourceAsStream(fileName);
        try {
            properties.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * 根據key,擷取到相對應的Propertie。
     * @param key
     * @return
     */
    public static Object getContextPropertie(String key){
        return properties.get(key);
    }

}
           

方法二

用什麼方式來擷取properties了,最友善的當然是直接讀取檔案,方法如上。但是程式用了Spring加載的properties的話,那我們的何不在原本的基礎上做得更好。

在spring讀取properties的xml配置中,如下:

<!-- 加載配置屬性檔案 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <!-- 标準配置 -->
                <value>classpath*:*.properties</value>
                 <!-- 本地開發環境配置 -->
                <value>file:/d:/mindconf/platform/*.properties</value>
                <!-- 伺服器生産環境配置 -->
                <value>file:/etc/mindconf/platform/*.properties</value>
            </list>
        </property>
    </bean>
           

從上面代碼可以看得出來PropertyPlaceholderConfigurer是承擔properties讀取任務的類。如果熟悉spring源碼的同學肯定知道,spring啟動的時候會調用處理器的postProcessBeanFactory()方法。

public abstract class PropertyResourceConfigurer extends PropertiesLoaderSupport
        implements BeanFactoryPostProcessor, PriorityOrdered {

    ......

    /**
     * {@linkplain #mergeProperties Merge}, {@linkplain #convertProperties convert} and
     * {@linkplain #processProperties process} properties against the given bean factory.
     * @throws BeanInitializationException if any properties cannot be loaded
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            ......
            // Let the subclass process the properties.
            processProperties(beanFactory, mergedProps);
        }
        catch (IOException ex) {
            throw new BeanInitializationException("Could not load properties", ex);
        }
    }
    ......
           
Spring中代碼實作讀取properties值Spring代碼實作讀取properties值

通過上面的圖檔和源代碼,基本可以知道,當項目啟動的時候将會調用processProperties(beanFactory, mergedProps);這個方法。有興趣的同學可以看下源代碼,我也是剛開始接觸而已。

是以第二方法就從這裡找到突破口(其實上面都是廢話啦,哈哈),下面通過自建類繼承PropertyPlaceholderConfigurer,通過重寫processProperties方法把properties暴露出去了。

public class CustomPropertyConfigurer extends PropertyPlaceholderConfigurer {

    private static Properties properties;  

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
            throws BeansException {
        super.processProperties(beanFactoryToProcess, props);
        // 把properties暴露出去
        properties = props;
    }

    /**
     * 根據key,擷取到相對應的Propertie。
     * @param key
     * @return
     */
    public static Object getContextPropertie(String key){
        return properties.get(key);
    }
}
           

當然還有一步,我們需要把配置檔案xml中的配置改為重寫這個類。

<!-- 加載配置屬性檔案 -->
<bean class="com.fourwenwen.demo.CustomPropertyConfigurer">
    <property name="locations">
           <list>
               <value>classpath*:*.properties</value>
           </list>
       </property>
</bean>
           

本次部落格就寫到這裡了。本人渣渣一枚,程式員的眼中都是追求完美的,如果寫的不好或者寫錯了,請大神們體諒體諒,提出來,小弟盡快改進,謝謝。

如果你有更好的方法和建議,歡迎大家互相讨論。