面試被問爛的Spring IOC請務必掌握

2022-12-06 12:51:05 字數 2910 閱讀 2097

廣義的 ioc

1. ioc(inversion of control) 控制反轉,即「不用打**過來,我們會打給你」。

兩種實現: 依賴查詢(dl)和依賴注入(di)。

ioc 和 di 、dl 的關係(這個 dl,**alon 和 ejb 就是使用的這種方式實現的 ioc):

1. dl 已經被拋棄,因為他需要使用者自己去是使用 api 進行查詢資源和組裝物件。即有侵入性。

2. di 是 spring 使用的方式,容器負責元件的裝配。

[, , , , , , , , , , , , , , , , ]

spring 的 ioc

spring 的 ioc 設計支援以下功能:

1. 依賴注入

2. 依賴檢查

3. 自動裝配

4. 支援集合

5. 指定初始化方法和銷毀方法

6. 支援**某些方法(但是需要實現 spring 介面,略有侵入)

其中,最重要的就是依賴注入,從 xml 的配置上說, 即 ref 標籤。對應 spring runtimebeanreference 物件。

對於 ioc 來說,最重要的就是容器。容器管理著 bean 的生命週期,控制著 bean 的依賴注入。

那麼, spring 如何設計容器的呢?

spring 作者 rod johnson 設計了兩個介面用以表示容器。

1. beanfactory

2. applicationcontext

beanfactory 粗暴簡單,可以理解為就是個 hashmap,key 是 beanname,value 是 bean 例項。通常只提供註冊(put),獲取(get)這兩個功能。我們可以稱之為 「低階容器」。

applicationcontext 可以稱之為 「高階容器」。因為他比 beanfactory 多了更多的功能。他繼承了多個介面。因此具備了更多的功能。

[, , , , , , , , , , ]

該介面定義了乙個 refresh 方法,此方法是所有閱讀 spring 原始碼的人的最熟悉的方法,用於重新整理整個容器,即重新載入/重新整理所有的 bean。

當然,除了這兩個大介面,還有其他的輔助介面,但我今天不會花太多篇幅介紹他們。

為了更直觀的展示 「低階容器」 和 「高階容器」 的關係,我這裡通過常用的 classpathxmlapplicationcontext 類,來展示整個容器的層級 uml 關係。

有點複雜? 先不要慌,我來解釋一下。

最上面的 beanfactory 知道吧?我就不講了。

下面的 3 個綠色的,都是功能擴充套件介面,這裡就不展開講。

看下面的隸屬 applicationcontext 粉紅色的 「高階容器」,依賴著 「低階容器」,這裡說的是依賴,不是繼承哦。他依賴著 「低階容器」 的 getbean 功能。而高階容器有更多的功能:

支援不同的資訊源頭,可以訪問檔案資源,支援應用事件(observer 模式)。

通常使用者看到的就是 「高階容器」。 但 beanfactory 也非常夠用啦!

左邊灰色區域的是 「低階容器」, 只負載載入 bean,獲取 bean。容器其他的高階功能是沒有的。例如上圖畫的 refresh 重新整理 bean 工廠所有配置。

生命週期事件**等。

[, , , , , , , , ]

下圖是 classpathxmlapplicationcontext 的構造過程,實際就是 spring ioc 的初始化過程。

注意,這裡為了理解方便,有所簡化。

這裡再用文本來描述這個過程:

1. 使用者構造 classpathxmlapplicationcontext(簡稱 cpac)

2. cpac 首先訪問了 「抽象高階容器」 的 final 的 refresh 方法,這個方法是模板方法。所以要**子類(低階容器)的 refreshbeanfactory 方法,這個方法的作用是使用低階容器載入所有 beandefinition 和 properties 到容器中。

3. 低階容器載入成功後,高階容器開始處理一些**,例如 bean 後置處理器。** setbeanfactory 方法。

或者註冊***等,發布事件,例項化單例 bean 等等功能,這些功能,隨著 spring 的不斷公升級,功能越來越多,很多人在這裡迷失了方向 :)。

簡單說就是:

1. 低階容器載入配置檔案(從 xml,資料庫,applet),並解析成 beandefinition 到低階容器中。

2. 載入成功後,高階容器啟動高階功能,例如介面**,***,自動例項化單例,發布事件等等功能。

所以,一定要把 「低階容器」 和「高階容器」 的區別弄清楚。不能一葉障目不見泰山。

好,當我們建立好容器,就會使用 getbean 方法,獲取 bean,而 getbean 的流程如下:

從圖中可以看出,getbean 的操作都是在低階容器裡操作的。其中有個遞迴操作,這個是什麼意思呢?

[, , , , , , , , , , , , , , , , , , , , , , ]

為什麼不是在載入的時候,就直接注入呢?因為載入的順序不同,很可能 bean_a 依賴的 bean_b 還沒有載入好,也就無法從容器中獲取,你不能要求使用者把 bean 的載入順序排列好,這是不人道的。

所以,spring 將其分為了 2 個步驟:

1. 載入所有的 bean 配置成 beandefinition 到容器中,如果 bean 有依賴關係,則使用佔位符暫時代替。

2. 然後,在呼叫 getbean 的時候,進行真正的依賴注入,即如果碰到了屬性是 ref 的(佔位符),那麼就從容器裡獲取這個 bean,然後注入到例項中 —— 稱之為依賴注入。

3. 可以看到,依賴注入實際上,只需要 「低階容器」 就可以實現。

這就是 ioc。

所以 applicationcontext refresh 方法裡面的操作不只是 ioc,是高階容器的所有功能(包括 ioc),ioc 的功能在低階容器裡就可以實現。

面試被問缺點,該如何應答

面試被問缺點,該如何應答?王老師 您好。我前些時候去面試 面試官問我很多問題,其中有一道題是 請你談談自己主要的優缺點。我覺得很難回答,尤其是缺點部分,怕說多了,影響面試官對我的印象,不說吧,又不可能,因為人人都有缺點,只是多少的問題。您說該怎麼辦啊?我問了其他考生,他們說對自己優點的介紹放為重點,...

被問概率達99的面試問題

在前程無憂論壇上,有太多有過面試經歷的求職者,筆者通過對他們的採訪,總結出3個10次面試9次會被hr問到的面試問題。大概率問題1 離職原因是什麼?從求職者角度來說,離職的原因不外乎這樣幾種 錢少 離家遠 沒前途 壓力大 人際關係不好等等。這些都是非常客觀和現實的問題,不能因為這些原因而否定這個人。但...

面試被問辭職理由別無所顧忌

許多跳槽者參加應聘面試時,都會被招聘者問及離開原來職位的原因。若是由於上班路途太遠 專業不對口 隨遷搬家等人人都可以理解的因素,說起來無顧忌,如果是以下四種因素,就要慎之又慎了,弄不好,就會失去了應聘機會。1 收入低沒勁幹這樣的跳槽理由會使招聘者誤認為你很計較個人得失,對工作沒有吃苦精神,把個人利益...