框架怎么選 中小項目別踩坑)
已經(jīng)做了有幾年時間的Java后臺開發(fā)工作, 所以插件化框架這些東西真正可不是隨便找個SPI就能搞定的。今天想聊幾個在實際項目開發(fā)過程里碰到過的陷阱或者問題點。java插件化框架選型在我的這個項目里面, 我是使用了Maven結(jié)合自定義ClassLoader的這種處理方案的。這樣做的話, 它的整體架構(gòu)比OSGi要輕得多。其中的核心操作方式是, 我們需要把每一個單獨的插件都打包成獨立的jar包形式。然后在系統(tǒng)啟動的過程中去掃描相應(yīng)的目錄來實現(xiàn)動態(tài)的加載。對于類隔離這一項機制是如何來保證的問題, 主要是靠打破父類委托這個方式來實現(xiàn)的, 這部分內(nèi)容在文本中得到了類隔離靠打破父委托這樣的強調(diào)表述。在選擇技術(shù)框架的時候, 不能僅僅只是盯著文檔去看, 其實最核心的關(guān)鍵點是觀察這個框架具體是如何處理各個插件之間出現(xiàn)的依賴沖突問題的。我有親眼見過這么一個大項目實例, 當(dāng)時在該項目里有兩個不同的插件各自引用了不一樣版本的fastjson組件, 最終導(dǎo)致了ClassCastException異常的發(fā)生,然后開發(fā)人員足足花了一整天的時間來進(jìn)行排查和解決。java插件化熱部署方案在熱部署這個方面, 真正最靠譜的其實是用URLClassLoader替換這種辦法。具體的做法是把舊的實例里面的加載類的東西給它置空, 這樣就能讓垃圾回收機制去把它收走了。然后呢, 再去把新的jar包給重新加載一遍。對于那些說什么可以直接修改字節(jié)碼來達(dá)到效果的說法, 大家千萬別信。特別是在生產(chǎn)環(huán)境里用的時候, 絕對不要自己去折騰那些花哨的東西去弄什么熱字節(jié)碼修改。你必須把接口定義的那個操作, 嚴(yán)格地放置在插件端以及宿主端進(jìn)行共同協(xié)作的api那個包里面去, 與此同時插件端的代碼絕對不允許出現(xiàn)向宿主進(jìn)行反向依賴的這種情形, 這條規(guī)則要是稍微有點被破壞了這種狀態(tài)的話, 那么在卸載插件環(huán)節(jié)的時候就會直接拋出NoClassDefFoundError這個錯誤現(xiàn)象, 然后排查起問題來那就真的是非常痛苦的狀態(tài)了。插件化這種技術(shù)在表面上看是挺簡單的, 不過真正的難點在于非得去把邊界給劃清楚。具體到宿主方要暴露出來什么東西、插件方面能夠去調(diào)用什么東西、以及在出現(xiàn)異常的時候要怎么去進(jìn)行兜底處理, 把這些事項都得定好了之后, 后面再去搞迭代開發(fā)才能不慌啊。