天啦!竟然從來沒有人講過 SpringBoot 支援配置如此平滑的遷移
SpringBoot 是原生支援配置遷移的,但是官方文件沒有看到這方面描述,在原始碼中才看到此模組,spring-boot-properties-migrator
,幸虧我沒有跳過。看到這篇文章的各位,可算是撿到寶了,相信你繼續往下看下去,定會忍不住點贊、收藏、關注。
效果
先放個效果吸引你 :)
從 SpringBoot 2.0.0
版本開始,配置服務上下文,不支援 server.context-path
,而需要server.servlet.context-path
配置。但是隻要加上以下一個官方依賴,就可以支援使用 server.context-path
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> </dependency>
server.context-path
所對應的屬性 ServerProperties#contextPath
在 Java 程式碼中已不存在,server.servlet.context-path 所對應的的屬性在內部類 Servlet
中才有,為何加了此依賴就能實現如此神奇的效果呢。
原理
SpringBoot 對外部化配置原生支援遷移功能,所謂遷移,具體是指對應配置的屬性名變動,仍可以使用原來的屬性名配置。
在 spring-configuration-metadata.json
的資訊可以輔助 IDE 進行配置的提示,也可以用來完成配置的遷移。非常的簡單。
相關文章: SpringBoot 配置提示功能
通過閱讀程式碼,獲得以下資訊:
- 監聽
ApplicationPreparedEvent
事件(即:環境已準備事件),執行以下操作並收集資訊 - 從
classpath*:/META-INF/spring-configuration-metadata.json
中載入所有配置 - 從上下文的
environment
中過濾出提示的配置(滿足條件:1. deprecation 不為 null,且提示level
為 error) - 判斷是否相容(相容條件見下一節),提取出相容的屬性
- 將 value 對應到
replacement
的 key,並將其屬性源命名為:migrate-原名 - 將配置遷移的
新屬性源
新增到 environment 中,且新增
之前
(優先順序高)。 - 監聽事件:ApplicationReadyEvent(應用上下文已準備) 或 ApplicationFailedEvent(應用啟動失敗),列印以上步驟收集的遺留配置資訊。以 warn 級別列印相容的配置,以 error 級別列印不相容的配置
配置相容條件
根據元資料中定義的 type
判斷
- 如果舊型別、新型別其中之一為 null(元資料中未指定),則不相容
- 如果兩個型別一樣,相容
- 如果新型別是 Duration,而舊型別是 Long 或 Integer,則相容
- 其他情況視為不相容
- 從
environment
中取配置資訊,理論上支援 SpringBoot 所有的配置方式。
效果
相容效果:
棄用
屬性(如果還存在)與替換
後的屬性都會使用配置檔案中的棄用的屬性名所對應的的值。
總結
使用配置遷移功能,需要以下步驟:
- 引入依賴:
spring-boot-properties-migrator
(支援配置遷移)、spring-boot-configuration-processor
(生成元資料檔案,如果已經有完整的,不需要此依賴) - 元資料檔案
spring-configuration-metadata.json
中棄用屬性名對應的 properties 中必須有deprecation
(在additional-spring-configuration-metadata.json
中新增,相關文章: SpringBoot 配置提示功能) deprecation
中需指定level
為 errordeprecation
中需指定replacement
replacement
對應的屬性配置在元資料檔案中存在,與棄用屬性相容
經典示例之配置上下文
再說回一開始展示的配置上下文示例。
# 配置 servlet 服務上下文
server:
context-path: test
從 SpringBoot 2.0.0
版本開始,以上配置不支援,點到配置元資料檔案中(spring-configuration-metadata.json
),發現如下資訊:
{
"properties": [
{
"name": "server.context-path",
"type": "java.lang.String",
"description": "Context path of the application.",
"deprecated": true,
"deprecation": {
"level": "error",
"replacement": "server.servlet.context-path"
}
},
{
"name": "server.servlet.context-path",
"type": "java.lang.String",
"description": "Context path of the application.",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties$Servlet"
}
替換屬性名為:server.servlet.context-path
,此屬性在org.springframework.boot.autoconfigure.web.ServerProperties
中,且在類中可以發現,server.context-path
所對應的屬性 ServerProperties#contextPath
在程式碼中已不存在,而是在內部類 Servlet
中有,也就是對應 server.servlet.context-path 的屬性才有。
但是其滿足配置相容的條件,為什麼實際上使用卻好像不相容呢?
其實是因為沒有引入依賴,當引入依賴,就會發現此方式配置可以起作用。
示例之兩種屬性都存在
程式碼示例見 https://gitee.com/lw888/spring-boot-source-example/tree/master/properties-migrator
1、引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2、Java 配置
此處故意保留棄用屬性
@Data
@Configuration
@ConfigurationProperties(prefix = "my")
public class MyProperties {
/** the project name */
private String name;
private App app;
@Data
public static class App {
private String name;
}
}
3、元資料配置,spring-configuration-metadata.json 由程式生成,自定義配置放在 additional-spring-configuration-metadata.json
中
{
"properties": [
{
"name": "my.name",
"type": "java.lang.String",
"description": "the project name.",
"deprecation": {
"reason": "test the properties-migrator feature.",
"replacement": "my.app.name",
"level": "error"
}
},
{
"name": "my.app.name",
"type": "java.lang.String",
"sourceType": "com.lw.properties.migrator.config.MyProperties$App",
"description": "the project name."
}
]
}
4、在 properties 或 yml 檔案中配置
my:
name: lw
app:
name: app
5、列印配置資訊
@Slf4j
@SpringBootApplication
public class PropertiesMigratorApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(PropertiesMigratorApplication.class, args);
MyProperties myProperties = context.getBean(MyProperties.class);
log.info("myProperties.name:{}", myProperties.getName());
log.info(
"myProperties$app.name:{}",
Optional.ofNullable(myProperties.getApp()).orElse(new App()).getName());
}
}
6、列印資訊如下:
2019-11-23 21:42:09.580 WARN 109408 --- [ main] o.s.b.c.p.m.PropertiesMigrationListener :
The use of configuration keys that have been renamed was found in the environment:
Property source 'applicationConfig: [classpath:/application.yml]':
Key: my.name
Line: 4
Replacement: my.app.name
Key: server.context-path
Line: 2
Replacement: server.servlet.context-path
Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.
......... myProperties.name:lw
......... myProperties\(app.name:lw ......... serverProperties\)servlet.contextPath:/app
7、效果解析
在 yml 中棄用屬性名優先順序更高,棄用屬性與新屬性都使用此棄用屬性名對應的值。
參考資料
SpringBoot 2.2.1.RELEASE
原始碼
公眾號:逸飛兮(專注於 Java 領域知識的深入學習,從原始碼到原理,系統有序的學習)
相關推薦
天啦!竟然從來沒有人講過 SpringBoot 支援配置如此平滑的遷移
SpringBoot 是原生支援配置遷移的,但是官方文件沒有看到這方面描述,在原始碼中才看到此模組,spring-boot-properties-migrator,幸虧我沒有跳過。看到這篇文章的各位,可算是撿到寶了,相信你繼續往下看下去,定會忍不住點贊、收藏、關注。 效果 先放個效果吸引你 :) 從 Sp
【IT職業】從來沒有人告訴你離職前要做的事 (收藏下,萬一哪天用到了呢)
據哈佛商學院教授、《行動起來:擁抱不確定性並創造未來》一書的合著者倫納德·施萊辛格所說:“如同書擋一樣,你如何開始與如何結束,是任何職業關係中最為重要的部分。”但問題是,人們總是會花很多時間準備與策劃如何給別人留下深刻的第一印象,卻很少考慮到“最後印象”。無論你是為何理由
“媽媽,我不想學了”,你的回答改變孩子一生(悵然若失,說了一句話:“為什麼當初沒有人逼我?”。我不願意學,你就不讓我學啦!那時候我還小,我還不懂事,難道你也不懂事嗎。要做成一件事,就必須有延遲滿足的能力)
“媽媽,我不想學了”,你的回答改變孩子一生(組圖)新聞來源: 槽值 前兩天,送孩子去書法班的時候,在小區門口看到一位媽媽,她正拽著孩子往車裡進,孩子哭著掙扎:“我不想學舞蹈了,我不去,太累了……” 媽媽怒吼著:“你今天去也得去,不去也得給我去!” 最終,孩子還是拗不過媽媽,上了車,去學舞蹈。 我不禁想
天啦擼!列印日誌竟然只曉得 Log4j?
空了的時候,我都會在群裡偷偷摸摸地潛水,對小夥伴們的一舉一動、一言一行篩查診斷。一副班主任的即時感,讓我感到非常的快樂,略微夾帶一絲絲的枯燥。 這不,我在戰國時代讀者群裡發現了這麼一串聊天記錄: 竟然有小夥伴不知道“打日誌”是什麼意思,不知道該怎麼學習,還有小夥伴回答說,只知道 Log4j! 有那麼一刻,
天啦,微信開發者工具預設竟然沒有開啟檔案儲存格式化功能,正確的開啟姿勢請看這裡
前言 程式碼格式化對於程式設計師來說,是個高頻使用的功能。直接影響程式設計體驗,如果每次寫完程式碼後,還要手動排版,那寫程式碼得多費力,程式設計效率得多低。然而我驚訝的發現,微信開發者工具預設沒有開啟檔案儲存自動化格式開關,需要開發者自己去開啟,開啟之後,儲存js和json檔案時,會提示有兩個格式化擴充套件可
微職位課程強大升級,優惠最後一天,明天就要恢復原價啦!
漲價 活動 下班後的幾小時,你都在忙些什麽? 有的人下班之後約在一起逛吃逛吃,享受生活。有的人下班之後去了健身房,為自己的身體負責。還有的人,下班之後就開啟學霸模式,因為他們知道,超前學習就是要領先於別人,就算做不到進步,也一定不能落後!那麽沒報名微職位的同學,抓緊時間報名吧! 今年,微職位課程更新,
天啊!這股神秘的東方力量竟然攪動了世界杯
活動 12個 http 之前 cto 戰勝 公司 命運 到來 2018年俄羅斯世界杯在6月27日淩晨2兩點,一場決定阿根廷的命運的比賽兩點到來,在此前進行的D組的兩場比賽中,阿根廷平一負一,在小組中積-3分,排名小組第四,只有戰勝尼日利亞,才有可能出現。比賽開始,上半場第1
滴滴出行瘋狂招人啦!
php 生活 rip ued 競爭 bte reac 加油 創投 滴滴出行瘋狂招人啦! 級別D6、D7、D8,職位包括前端、後端、產品、測試,我們只看能力,其他不限! 業務: 涉及汽車服務領域租售、維保、加油、分時、車生活等等,未來萬億級市場,潛力巨大,增長迅猛!
號外、號外!2019安天校園招聘簡歷投遞方式更換啦!
號外、號外!2019安天校園招聘簡歷投遞方式更換啦! 【我們要搞事情啦!】 有意向的同學請將簡歷投遞至郵箱 [email protected] 郵箱主題以及簡歷命名格式為:學校 姓名 應聘崗位 學歷 ,歡迎繼續投遞!!! 無畏前行十八
從來沒有任何一篇文章會把“程式設計師認知”講得如此透徹
程式猿問科比:“你為什麼這麼成功? ” 科比:“你知道洛杉磯凌晨四點是什麼樣子嗎? ” 程式猿:“知道,一般那個時候我還在寫程式碼,怎麼了?” 科比:“額…….” 你以為程式設計師都是這樣生活的: 別瞎,他們只是在歷劫! 度過這段日子,他們就飛昇上仙,乃至上神。過上另
感謝一路相伴的朋友們!我的個人工作室招人啦!
大家好,又來和大家嘮叨了。首先呢,在這裡要感謝大家一下。在我找不到工作的期間,隨意寫了一點當時自己的想法,竟然有這麼多朋友來關心和開導我,我很開心。在今年的6月份,我也是找到了我的第一份工作,而且還是在自己的老家。所以非常的開心,謝謝有你們一路的關心! 現在也已經進入了十一
#還真以為程式設計師沒有女朋友?不要被欺騙啦!
程式設計師沒有女朋友一直是大家調侃的點,不知道是從何時開始“程式設計師找不到女朋友”這枚輿論的螺旋就轉開了。程式設計師身上有各種標籤,錢多、人傻、直男癌、木訥…… 從客觀的角度來說,程式設計師行業的高薪毋庸置疑,舉幾個例子: 當你用力擠了擠一週的生活費,去星巴
3602: 中獎啦!(史上最強水解!!!沒有之一!!!)
3602: 中獎啦! 時間限制(普通/Java):1000MS/3000MS 記憶體限制:65536KByte 描述 L超時由於最近銷售量特別好。為答謝廣大的顧客,L公司準備舉行抽獎活動。而規則如下:超市會發行一批刮獎卡,每張刮獎卡刮開上面的圖層會
哈哈哈哈哈哈哈!我們都在1000人的大群裡,太好玩啦!驚喜太多…
揮手告別2018年,我們開始擁抱2019年啦!!! 你>>>>>>>是否還因為找不到組織而迷茫 莫慌莫慌,今天小編要給大家分享一波技術大群 在這裡, 你不僅能與大牛探討問題、探討技術、探討人生 還能。。。。。。 找到志同道合的道
#CSDN刷票門# 有沒有人在惡意刷票?CSDN請告訴我!用24小時監控資料說話!
特別宣告: 此次並非針對其他參與2013中國十大優秀開源專案的同行,體系有漏洞要譴責的是制定規則並從中獲益但不作為的權貴,草根們制定不了規則但可發現和利用漏洞,這是程式設計師應有反叛精神沒錯。但被作為道具不可接受。我代表FineUI請求CSDN公開資料,如果您覺得CSDN有必要撕下遮羞布,請共同呼籲。
沒有人喜歡聽廢話——講重點
-s 同學 身邊 喜歡 error tip 解釋 med white 這是我自己身上最大的一個缺點——也是我必須要改變的 以下是我自己個人的一些想法,做如下記錄:(期待下一次的進步) 通過幾個場
天啦嚕!生產機器連線數飆升到上萬,背後發生了什麼?
個人部落格地址 studyidea.cn,點選檢視更多原創文章 0x00. 翻車現場 那是個月黑風高的夜晚,小黑哥成功將新版本釋出到了生產,小心翼翼檢查了應用日誌,後續測試小姐姐驗收成功。 恩,小黑哥我還是一如既往的穩~ 接著小黑哥就跑到樓下食堂吃個夜宵,誰知正吃到一半,線上運維同學發來幾條告警資訊,
天哪!手動編寫mybatis雛形竟然這麼簡單
# 前言 mybaits 在ORM 框架中,可算是半壁江山了,由於它是輕量級,半自動載入,靈活性和易拓展性。深受廣大公司的喜愛,所以我們程式開發也離不開mybatis 。但是我們有對mabtis 原始碼進行研究嗎?或者想看但是不知道怎麼看的苦惱嗎? ![在這裡插入圖片描述](https://img2020.c
天啦嚕!知道硬碟很慢,但沒想到比 CPU L1 Cache 慢 10000000 倍
前言 大家如果想自己組裝電腦的話,肯定需要購買一個 CPU,但是儲存器方面的裝置,分類比較多,那我們肯定不能只買一種儲存器,比如你除了要買記憶體,還要買硬碟,而針對硬碟我們還可以選擇是固態硬碟還是機械硬碟。 相信大家都知道記憶體和硬碟都屬於計算機的儲存裝置,斷電後記憶體的資料是會丟失的,而硬碟則不會,因為硬