Spring技巧之如何動態讀取配置文件
Spring 動態讀取配置文件
需求背景
最近碰到的需求大概是這樣,我們要在一個現有的項目基礎上進行二次開發,但又不願意碰原有項目裡的代碼。所以采用瞭Maven依賴的方式——新建一個Maven項目作為主要開發環境,將原有項目作為Maven依賴(war形式)引入進來。這樣在新建的擴展項目中打包出來的war將會是合並兩個項目的所有代碼。
而在實際搭建的過程中碰到這樣一個問題,Spring配置文件中的 <context:property-placeholder />隻允許存在一個, 而且這個機會已經被原有項目使用瞭——這種說法並不嚴謹,所以以下給出三種解決方案:
方案一
以上關於<context:property-placeholder />的說法並不嚴謹,其實多次添加也不會報錯; 但隻會有一個生效(含義是 如果spring從所設置的配置文件集合中沒有讀取到屬性去替換占位符,就會報錯, 除非設置 ignore-unresolvable ) ,如果按照如下設置方式,就可以避免這種情況,並接觸本次需求。
<!-- 如果要配置多個, 就要設置ignore-unresolvable ="true" --> <context:property-placeholder location="classpath:extend/db.properties" ignore-unresolvable="true" /> <context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true" />
但是這樣帶來的壞處就是:
1. 將發現錯誤的時機推遲到瞭運行時,這在系統比較龐大時實在是大忌。
2. 屬性重復時的替換危機,這種BUG想要找出來,耗費的時間和精力想想就不寒而栗。
方案二
第二個方法 就是BeanFactoryPostProcessor接口,註意該接口的回調時機早於占位符替換 操作。
// BeanFactoryPostProcessor.postProcessBeanFactory @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 我們自己去讀取指定的配置文件 Properties prop = null ; try { prop = PropertiesLoaderUtils.loadAllProperties("extend/db.properties", Thread.currentThread().getContextClassLoader()); } catch (IOException e) { e.printStackTrace(); } if(null == prop){ return; } // 註入到特定的Bean的特定屬性中 BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dataSource_extend"); beanDefinition.getPropertyValues().add("url", prop.getProperty("db.sd.url")); beanDefinition.getPropertyValues().add("driverClassName",prop.getProperty("db.sd.driverClassName")); beanDefinition.getPropertyValues().add("username", prop.getProperty("db.sd.username")); beanDefinition.getPropertyValues().add("password", prop.getProperty("db.sd.password")); super.postProcessBeanFactory(beanFactory); }
方案三
還有一種方法就是使用Spring的父子容器的關系,將這個 <context:property-placeholder/>和依賴它的Bean全部註冊到一個全新容器中,然後將該容器作為現有容器的Parent。此方法過去取巧,本人沒有實際去嘗試。
動態讀取配置文件中的信息
1、首先是寫一個配置文件,方便動態加載
jedis.properties
key-value形式保存
1、利用類加載器等讀取配置文件
1.讀取配置文件
InputStream is=JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
2.創建properties對象
Properteis pro=new Properties();
3.關聯文件
pro.load(is);
4.然後在項目中可以動態加載key獲取到value值
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Spring IOC容器基於XML外部屬性文件的Bean管理
- Java基礎之Spring5的核心之一IOC容器
- 一文詳解Spring加載properties文件的方式
- spring 和 spring boot 中的屬性配置方式
- Spring的BeanFactoryPostProcessor接口示例代碼詳解