Spring boot外部配置(配置中心化)詳解
前言
在項(xiàng)目中為了靈活配置,我們常采用配置文件,常見(jiàn)的配置文件就比如xml和properties,springboot允許使用properties和yaml文件作為外部配置。現(xiàn)在編譯器對(duì)于yaml語(yǔ)言的支持還不夠好,目前還是使用properties文件作為外部配置。
在Spring cloud config出來(lái)之前, 自己實(shí)現(xiàn)了基于ZK的配置中心, 杜絕了本地properties配置文件, 原理很簡(jiǎn)單, 只是重載了PropertyPlaceholderConfigurer的mergeProperties() :
/**
* 重載合并屬性實(shí)現(xiàn)
* 先加載file properties, 然后并入ZK配置中心讀取的properties
*
* @return 合并后的屬性集合
* @throws IOException 異常
*/
@Override
protected Properties mergeProperties() throws IOException {
Properties result = new Properties();
// 加載父類(lèi)的配置
Properties mergeProperties = super.mergeProperties();
result.putAll(mergeProperties);
// 加載從zk中讀取到的配置
Map<String, String> configs = loadZkConfigs();
result.putAll(configs);
return result;
}
這個(gè)實(shí)現(xiàn)在spring項(xiàng)目里用起來(lái)還是挺順手的, 但是近期部分spring-boot項(xiàng)目里發(fā)現(xiàn)這種placeholder的實(shí)現(xiàn)跟spring boot的@ConfigurationProperties(prefix = "xxx") 不能很好的配合工作,
也就是屬性沒(méi)有被resolve處理, 用@Value的方式確可以讀到, 但是@Value配置起來(lái)如果屬性多的話還是挺繁瑣的, 還是傾向用@ConfigurationProperties的prefix, 于是看了下spring boot的文檔發(fā)現(xiàn) PropertySource
order:
* Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
* @TestPropertySource annotations on your tests.
* @SpringBootTest#properties annotation attribute on your tests.
* Command line arguments.
* Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
* ServletConfig init parameters.
* ServletContext init parameters.
* JNDI attributes from java:comp/env.
* Java System properties (System.getProperties()).
* OS environment variables.
* A RandomValuePropertySource that only has properties in random.*.
* Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
* Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
* Application properties outside of your packaged jar (application.properties and YAML variants).
* Application properties packaged inside your jar (application.properties and YAML variants).
* @PropertySource annotations on your @Configuration classes.
* Default properties (specified using SpringApplication.setDefaultProperties).
不難發(fā)現(xiàn)其會(huì)檢查Java system propeties里的屬性, 也就是說(shuō), 只要把mergerProperties讀到的屬性寫(xiě)入Java system props里即可, 看了下源碼, 找到個(gè)切入點(diǎn)
/**
* 重載處理屬性實(shí)現(xiàn)
* 根據(jù)選項(xiàng), 決定是否將合并后的props寫(xiě)入系統(tǒng)屬性, Spring boot需要
*
* @param beanFactoryToProcess
* @param props 合并后的屬性
* @throws BeansException
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
// 原有邏輯
super.processProperties(beanFactoryToProcess, props);
// 寫(xiě)入到系統(tǒng)屬性
if (writePropsToSystem) {
// write all properties to system for spring boot
Enumeration<?> propertyNames = props.propertyNames();
while (propertyNames.hasMoreElements()) {
String propertyName = (String) propertyNames.nextElement();
String propertyValue = props.getProperty(propertyName);
System.setProperty(propertyName, propertyValue);
}
}
}
為避免影響過(guò)大, 設(shè)置了個(gè)開(kāi)關(guān), 是否寫(xiě)入系統(tǒng)屬性, 如果是spring boot的項(xiàng)目, 就開(kāi)啟, 這樣對(duì)線上非spring boot項(xiàng)目做到影響最小, 然后spring boot的@ConfigurationProperties完美讀到屬性;
具體代碼見(jiàn): org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
ConfigurationProperties annotation = AnnotationUtils
.findAnnotation(bean.getClass(), ConfigurationProperties.class);
if (annotation != null) {
postProcessBeforeInitialization(bean, beanName, annotation);
}
annotation = this.beans.findFactoryAnnotation(beanName,
ConfigurationProperties.class);
if (annotation != null) {
postProcessBeforeInitialization(bean, beanName, annotation);
}
return bean;
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Java使用POI實(shí)現(xiàn)導(dǎo)出Excel的方法詳解
在項(xiàng)目開(kāi)發(fā)中往往需要使用到Excel的導(dǎo)入和導(dǎo)出,導(dǎo)入就是從Excel中導(dǎo)入到DB中,而導(dǎo)出就是從DB中查詢數(shù)據(jù)然后使用POI寫(xiě)到Excel上。本文將利用POI實(shí)現(xiàn)導(dǎo)出Excel,需要的可以參考一下2022-10-10
解讀@ResponseBody與@RequestBody注解的用法
這篇文章主要介紹了Spring MVC中的@ResponseBody和@RequestBody注解的用法,@ResponseBody注解用于將Controller方法的返回對(duì)象轉(zhuǎn)換為指定格式(如JSON)并通過(guò)Response響應(yīng)給客戶端,@RequestBody注解用于讀取HTTP請(qǐng)求的內(nèi)容2024-11-11
JavaMail實(shí)現(xiàn)帶附件的郵件發(fā)送
這篇文章主要為大家詳細(xì)介紹了JavaMail實(shí)現(xiàn)帶附件的郵件發(fā)送,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Mybatis一對(duì)多與多對(duì)一查詢處理詳解
這篇文章主要給大家介紹了關(guān)于Mybatis一對(duì)多與多對(duì)一查詢處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Jenkins安裝多個(gè)jdk版本并在項(xiàng)目中選擇對(duì)應(yīng)jdk版本
在使用jenkins構(gòu)建項(xiàng)目時(shí)會(huì)遇到不同的job需要配置不同版本的jdk,下面這篇文章主要給大家介紹了關(guān)于Jenkins安裝多個(gè)jdk版本并在項(xiàng)目中選擇對(duì)應(yīng)jdk版本的相關(guān)資料,需要的朋友可以參考下2024-03-03
Spring Security實(shí)現(xiàn)微信公眾號(hào)網(wǎng)頁(yè)授權(quán)功能
這篇文章主要介紹了Spring Security中實(shí)現(xiàn)微信網(wǎng)頁(yè)授權(quán),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
Java常見(jiàn)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了Java常見(jiàn)數(shù)據(jù)結(jié)構(gòu)面試題,帶有答案及解釋,希望對(duì)廣大的程序愛(ài)好者有所幫助,同時(shí)祝大家有一個(gè)好成績(jī),需要的朋友可以參考下,希望可以幫助到你2021-07-07

