Java 菜鳥,會把可變的配置信息寫死在代碼里;Java 老鳥,會把可變的配置信息提取到配置文件中。坊間流傳這么一句非科學的衡量標准,來評判程序員的級別。
那么,項目中的配置信息,你平時都是怎樣來實現的呢?你項目中用過哪些配置文件呢?
近期將結合實際項目或源碼,說說這些年用過的那些有關配置的奇技淫巧,看看能否幫你提高研發能力(那怕是提高一丟丟,就算成功)。
1. 后綴為 .ini 的文件,你用過沒?
后綴為 .ini 的文件,是 Initialization File 的縮寫,主要用於程序的初始化的一些配置參數,后綴當然也可以是 .conf、.cfg,只是項目中習慣上用后綴 .ini 罷了。
簡單介紹一下,一個 ini 配置文件主要由節(section)、鍵值對組成。
如上圖所示,ini 文件中,配置參數都是以節(section)為單位組合在一起的,每個節名字都被方括號包圍着,像 owner、database 都被方括號括着。而每個節聲明后的鍵值對都屬於該 section,而且一個 section 沒有結束標識符,一個節的開始就是上一個節的結束。
2. 后綴為 .ini 的文件,怎么用啊?
在自研框架或者業務項目開發中,往往會配置一些項目啟動時要初始化的一些參數信息,例如端口、域名等等。從老項目中截取一段,其實就配置鍵值對而已,很簡單,有沒有?
另外,項目研發中在面對身份驗證、授權、密碼和會話管理等需求時,經常會集成 Java 安全框架 Shiro,而 Shiro 就提供了使用 ini 文件,進行配置參數的能力(INI is easy to read, simple to use, and requires very fewdependencies)。
后綴為 .ini 的文件,怎么解析啊?
老土方法:用腳指頭想出來的簡單方法,往文件上插一根管子,直接采用 Properties 的 load 方法完成數據的讀取,勢必能達到解析的目的(腦補代碼,懶得寫代碼啦)。
老土方法:用手指頭想出來的簡單方法,往文件上插一根管子,一行一行去讀,再按照等號拆分鍵值對,最后把鍵值對向 Map 放一下,必然也能達到解析的目的(腦補代碼,代碼懶得寫啦)。
優雅方法:看看 Shiro 咋搞的?項庄舞劍意在沛公。嘗試告訴你:為什么 Java 輪子會多呢?這可能就是造輪子的其中一條路徑,熟讀源碼,到處抄,哈哈。
3. shiro.ini,到底人家怎么解析的?
首先,Shiro 加載配置文件支持好幾種方式,我們就挑如何加載類路徑下的 shiro.ini 配置文件進行剖析,掌握這一條路徑,其它方式殊途同歸。
如上圖源碼所示,在加載 shiro.ini 配置文件前,首先會判斷文件是否存在,存在則從類路徑下進行加載,而且會發現 Shiro 把 ini 配置封裝成了 Ini 對象(這不就是面向對象嗎?Java 的核心思想:Every thing is object!)。
如上圖源碼所示,很顯然會發現,具體讀取 shiro.ini 配置的事情,就交給了 ResourceUtils 去辦了(術業有專攻,分工明確,各司其職),不過和咱們能想到的土方法也差不多,就是往文件上插一根管子,然后調用 load 方法進行讀取。
通過上面源碼截圖,發現 load 方法只是稍微裝飾了一下,把 InputStream 變成了 Reader(設計模式:裝飾器模式;面向對象的核心:多態)。
看到上面的代碼,會發現依然沒有真正的讀取,而是繼續包裝 Reader,變成 Scanner 來獲取文件輸入(敢問,有必要這么繞來繞去嗎?不過,無所謂,繼續往下看!)
到這兒,如上面截圖所示,看到了廬山真面目,終於見到了一行一行進行讀取內容,並進行截取其中的 section(節),也就是 shiro.ini 中配置的 [main]、[urls] 等等,接着把每個 section 下面的內容直接拼接在一起形成字符串,而此時,並沒有拆分鍵值對。
如上面源碼所示,很顯然 Shiro 把 ini 配置的組件又封裝成了 Section 對象(再一次體會Java 的核心思想:Every thing is object!)。
不過,還記得配置文件咋配置的嗎?把 shiro.ini 配置圖再貼一次。
我們結合下面的源碼,再去看上面這個段配置,順道看看 Section 對象里面都有啥?
如上圖源碼標注 1,定義了一個 Map 用於保存配置的鍵值對信息;代碼標注 2,是把上一步的字符串轉換成 Map,具體轉換如下圖所示,按照等號進行拆分鍵值對,並放到 Map中。
仔細去看源碼,會發現拆分鍵值對時,不僅僅是按照等號,但是 who care 呢?只因為到這兒,梗概已經了解個八九不離十啦。
好了,剖析的差多了,從源碼去看反而感覺復雜了不少,其實際使用超級之簡單,和咱們用手指頭想的老土方法差不多,只是 Shiro 封裝的稍微好一些。
但是,你有沒有發現,有好多代碼是可以簡單抽一抽,你就可以直接應用到項目中的呢?
4. 它山之石可以攻玉,相信會對你有所幫助。
行文至此,你肯定會有疑問,為什么不用 properties 啊?為什么不用 ymal 啊?其實說實話,黑貓白貓抓住老鼠都是好貓。
另外,為了能夠幫你提高研發能力(那怕是提高一丟丟呢),后續將繼續結合實際項目,看看用到的其它形式的配置文件,敬請期待。