設計乙個可拔插的 IOC 容器

2021-09-13 04:03:24 字數 3529 閱讀 4748

磨了許久,借助最近的一次通宵上線 cicada 終於更新了v2.0.0版本。

之所以大的版本號變為 2,確實是向下不相容了;主要表現為:

其中重點是後面兩個。

先來看第乙個:路由方式的更新。

在之前的版本想要寫乙個介面必須的實現乙個workaction;而且最麻煩的是乙個實現類只能做乙個介面。

因此也有朋友給我提過這個 issue。

於是改進後的使用方式如下:

是否有點似曾相識的感覺?。
如上圖所示,不需要實現某個特定的介面;只需要使用不同的註解即可。

同時也支援自定義pojo,cicada會在呼叫過程中對引數進行例項化。

拿這個getuser介面為例,當這樣請求時這些引數就會被封裝進demoreq中.

同時得到響應:

實現過程也挺簡單,大家檢視原始碼便會發現;這裡貼一點比較核心的步驟。

掃瞄類以及寫入對映關係

請求時查詢對映關係

反射呼叫這些方法

上面那幾個步驟其實我都是一把梭寫完的,但當我寫到執行具體方法時感覺有點意思了。

我第一次寫的時候是這樣的:

method.invoke(method.getdeclaringclass().newinstance(), object);
然後一測試,也沒問題。

當我寫完之後review**時發現不對:這樣這裡每次都會建立乙個新的例項,而且反射呼叫newinstance()效率也不高。

這時我不自覺的想到了 spring 中 ioc 容器,和這裡場景也非常的類似。

在應用初始化時將所有的介面例項化並儲存到 bean 容器中,當需要使用時只需要從容器中獲取即可。
這樣只是會在啟動時做很多載入工作,但造福後代啊。

於是我打算自己實現乙個這樣的 bean 容器。

但在實現之前又想到乙個 feature:

不如把實現 bean 容器的方案交給使用者選擇,可以選擇使用 bean 容器,也可以就用之前的每次都建立新的例項,就像 spring 中的 prototype 作用域一樣。
甚至可以自定義容器實現,比如將 bean 存放到資料庫、redis 都行;當然一般人也不會這麼幹。

spi的機制也有點類似。

要實現上述的需求大致需要以下步驟:

所以首先定義了乙個介面;cicadabeanfactory:

包含了註冊和獲取例項的介面。

同時分別有兩個不同的容器實現方案。

預設實現;cicadadefaultbean

也就是文中說道的,每次都會建立例項;由於這種方式其實根本就沒有 bean 容器,所以也不存在註冊了。

接下來是真正的 ioc 容器;cicadaioc

它將所有的例項都存放在乙個 map 中。
當然也少不了剛才提到的cicadabeanmanager,它會在應用啟動的時候將所有的例項註冊到bean容器中。

重點是圖中標紅的部分:

同時也提供了乙個獲取例項的方法:

就是直接呼叫cicadabeanfactory介面的方法。

然後在上文提到的反射呼叫方法處就變為:

bean容器中獲取例項了;獲取的過程可以是每次都建立乙個新的物件,也可以是直接從容器中獲取例項。這點對於這裡的呼叫者來說並不關心

所以這也實現了標題所說的:可拔插

為了實現這個目的,我將cicadaioc的實現單獨放到乙個模組中,以 jar 包的形式提供實現。

所以如果你想要使用ioc容器的方式獲取例項時只需要在你的應用中額外加入這個 jar 包即可。

top.crossoverjie.opensource

cicada-ioc

2.0.0

如果不使用則是預設的cicadadefaultbean實現,也就是每次都會建立物件。

這樣有個好處:

當你自己想實現乙個ioc容器時;只需要實現cicada提供的cicadabeanfactory介面,並在你的應用中只加入你的jar包即可。

其餘所有的**都不需要改變,便可隨意切換不的容器。

當然我是推薦大家使用ioc容器的(其實就是單例),犧牲一點應用啟動時間帶來後續效能的提公升是值得的。
cicada的大坑填的差不多了,後續也會做一些小功能的迭代。

還沒有關注的朋友趕緊關注一波:

ps:雖然沒有仔細分析 spring ioc 的實現,但相信看完此篇的朋友應該對 spring ioc 以及 springmvc 會有一些自己的理解。
你的點讚與分享是對我最大的支援

設計乙個可拔插的 IOC 容器

磨了許久,借助最近的一次通宵上線 cicada 終於更新了v2.0.0版本。之所以大的版本號變為 2,確實是向下不相容了 主要表現為 其中重點是後面兩個。先來看第乙個 路由方式的更新。在之前的版本想要寫乙個介面必須的實現乙個workaction 而且最麻煩的是乙個實現類只能做乙個介面。因此也有朋友給...

IoC容器的介面設計

1 從介面beanfactory hierarchicalbeanfactory configurablebeanfactory,是一條主要的beanfactory設計路徑。4 beanfactory是ioc容器最基本的介面,提供的是最基本的ioc容器的功能,比如getbean containsbe...

如何設計乙個可用的web容器

開發乙個web容器涉及很多不同方面不同層面的技術,例如通訊層的知識,程式語言層面的知識等等,且乙個可用的web容器是乙個比較龐大的系統,要說清楚需要很長的篇幅,本文旨在介紹如何設計乙個web容器,只 實現的思路,並不涉及過多的具體實現。把它分解劃分成若干模組和元件,每個元件模組負責不同的功能,下圖列...