來源:https://lepdou.github.io/blogs/config/config.html
引言
專案開發中總是有各種各樣的配置,對于程式開發新手來說,配置是擺在面前的第一座大山, 回想當年在學校學習經典的“SSH”的時候,一個web.xml配置都是例外的艱辛,作業多年的你,對配置真的了解嗎?
什么是配置?
首先我們來看一下組態檔的定義:
“A software file used to configure the initial settings for a computer program.” -- From wikipedia
配置來源可能有以下這些:
- 硬編碼引數
- 專案里的組態檔
- 檔案系統上的組態檔
- 網路上的組態檔
- 啟動引數(JVM屬性)
- 作業系統引數

下面會詳細介紹每一種配置型別的使用場景,
硬編碼引數
最常見的就是定義靜態變數方式,例如: public static final int PAGE_SIZE = 10;
另外就是通過框架暴露的各種API介面設定引數,
優點
- 這種是最簡單、成本最低的方式
- 不用額外創建檔案
- 代碼里能直接能讀取
- 離配置使用地方最近的一種方式
缺點
- 代碼和配置糅合在一起,不易于維護
- 修改配置必須修改源代碼,重新編譯、打包、上線
- 同一個框架的配置散落到專案各個角度,不利于查找
適用場景
- Hard Code 適用于配置極其簡單且幾乎不會變更
- 為了賦予常量語意
- 配置極少從而創建組態檔成本高
專案里組態檔
這種方式是最常見的,標準的maven專案有一個resources目錄就是用來放置各種型別的組態檔,例如:
- web專案的web.xml
- log框架的配置
- spring的bean定義的xml檔案
- mybatis的sql組態檔
- spring boot的application.yml application.properties
- 自定義的properties檔案
另外maven專案的核心pom.xml也算是組態檔,專案里使用到的各種各樣的框架、中間件基本上都需要組態檔來支撐,框架在運行時,讀取組態檔來決定運行時的行為, 組態檔路徑一般有兩種方式:
- 按照框架約定的目錄(相對于classpath)
- 告訴框架組態檔的路徑
優點
- 配置和代碼分離
- 集中統一管理配置
- 不依賴專案外部資源
缺點
- 跟Hard Code一樣不能動態修改配置
- 組態檔增生,導致專案臃腫
適用場景
- 非常適合框架或者中間件的配置
- 專案中自定義業務配置
檔案系統上的組態檔
此類組態檔是放在應用運行的機器上,常見的比如攜程公司內部機器上都會放置一個server.properties檔案,檔案內容主要是當前機器的一些資訊,比如env=dev標示當前機器屬于dev環境,公司配套提供framework-fundation基礎jar包,用來決議這個檔案,
那么應用只要通過framework-foundation來獲取機器的相關資訊, framework-foundation在這里的作用就是作為機器和應用之間的橋梁,這種方式主要好處是規范運維, 另外一種使用比較多的場景是應用直接讀取檔案系統上的某個檔案,這種方式的好處就是可以動態更新配置,無需重新編譯、打包、運行應用,
優點
- 配置和代碼分離
- 可動態修改配置
缺點
- 配置和應用代碼不在一個地方(專案原始碼),不易于理解和運行
- 修改配置需要登錄機器
- 修改組態檔可能涉及權限問題
- 組態檔路徑也需要溝通
適用場景
- 不建議作為應用業務相關的配置,成本高且不易于開發維護
- 適用于運維相關的配置,如前面舉的例子
筆者遇到過一個dal框架,datasource組態檔就是放在檔案系統上,結果開發人員在上線時,忘記在機器上放置這個檔案導致線上bug,
網路上的組態檔
常見的包括兩種:DB上的配置表、配置中心,如果公司沒有統一的配置中心,那么最簡單的動態修改配置的方式莫過于把配置放置在DB上,相信大部分的開發都使用過或者遇到過,
配置中心是最適合集中化管理配置、動態修改配置的地方,常見的配置中心都會提供管理配置后臺、實時推送配置、分環境管理配置、配置版本管理等,筆者目前就在開發一款開源的配置中心系統,
優點
- 集中管理配置、全方位管理配置
- 動態修改配置、實時推送、更新配置
- 配置更加靈活,例如可以分環境、集群以及灰度發布等
缺點
- 需要依賴資料庫或者配置中心,成本高
適用場景
- 經常需要變更的配置
- 配置值每個環境不一致
- 不希望配置值隨著代碼一起發布,例如開源專案中的某些配置
啟動引數(JVM屬性)
JVM屬性主要是應用運行的JVM行程相關的屬性,比如java.class.version、java.class.path等Java相關的引數,在代碼里,可以通過System.getProperty()獲取引數值, 另外,可以通過在啟動時指定-D引數來設定JVM屬性,最常見的使用場景是用來解決不同環境需要配置不同的引數,例如作為中間件,依賴的外部系統越少越好,如果不依賴配置中心,那么就可以通過這種方式來實作不同環境配置不同的引數,例如每個環境的資料庫連接串不一樣, 另外需要提到的是maven打包引數,
相比于-D運行時引數,maven打包引數是在編譯時設定配置屬性,maven會獲取打包引數然后替換掉組態檔里的placeholder,假設一個可運行的jar包,只需要在打包的時候傳入引數值,打出來的jar包就可以到處運行了,如果不這么做,那么需要每次運行的時候指定引數,成本太高,使用方式則是在mvn package 時指定-D引數, 新手很容易混淆這兩種引數,換個角度看-D是命令列引數,
優點
- 以非常小的代價就可以達到運行時指定特殊引數值
缺點
- 啟動運行專案需要設定啟動引數,增加使用成本
適用場景
- 適合中間件類系統,不推薦業務系統使用(業務系統用配置中心解決此類場景)
- 增加統一運維成本
作業系統引數
作業系統引數一般是只讀的,當然也可以設定,例如前面提到的server.properties檔案里的env引數,其實也可以作為系統引數,但是不建議這么做,
后記
配置的好處顯而易見,但是我們在作業中經常會遇到這種情況,拿到一個專案,看到亂七八糟的配置無從下手,專案中使用的框架、中間件配置風格更不相同,更頭疼的是配置項如果不了解框架的基礎上很難理解,
導致的結果就是如果不復制、粘貼配置,手寫配置基本上很難寫對, 驗證這種情況最簡單的方式就是不復制其它專案的配置,手動搭建一個新專案,我相信絕大多數的人都難以做到,
片面的說學習一個框架其實是在學習這個框架的API和配置引數,如果你非常熟悉一個框架的配置,那么你對框架的使用就得心應手了,當然,知道框架的原理也非常重要, 說這么多,只想說明專案的配置真的非常重要,更好的管理、規范配置更加重要,
對于框架、中間件開發者來說,配置應該越少越好,增加一個配置對于使用者使用成本就會大大提高,如果配置很多,那么你的框架基本上就是很難用了, Spring一直是Java界最權威的框架體系,最新的Spring Boot框架的配置就非常少,一眼看上去非常舒心,
Spring現在倡導減少組態檔,例如Spring早期版本的xml配置其實是很繁瑣的,新的Spring更多的配置放置在代碼中,利用注解以及API方式配置,Servlet最新版本也不需要web.xml檔案了,
說明一個道理: 大道至簡?
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
2.勁爆!Java 協程要來了,,,
3.Spring Boot 2.x 教程,太全了!
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500908.html
標籤:Java
上一篇:JAVA反射機制詳解
