繼上篇 Spring 開胃菜 之后,這篇我們繼續(xù)來盤盤 Spring 面試題。
這篇主要介紹幾個比較容易混淆的概念,防止被問到的時候一臉懵逼。
比如 BeanFactory 、FactoryBean、ObjectFactory 的區(qū)別?等等。
話不多說,發(fā)車!
BeanFactory 其實就是 IOC 的底層容器。
我們都說 Spring 是 IOC 容器,說的再直白點,其實就是 Bean 的工廠,它幫我們生產和管理 Bean,如果我們需要 Bean 就從工廠拿到 bean,所以再來理解下 BeanFactory 這個名字,就知曉它就是 Spring 的核心。
例如我們調用 getBean ,這就是 BeanFactory 定義的方法,通過它得到 Bean。
不過一般我們所述的 BeanFactory 指的是它實現類,例如 DefaultListableBeanFactory。
BeanFactory 本身只是一個接口。
從命名角度來看,我們可以得知它就是一個 Bean,而不是一個工廠。
那為什么名字如此奇怪,它其實是一個接口,并且有以下幾個方法
如果一個對象實現了這接口,那它就成為一種特殊的 Bean,注冊到 IOC 容器之后,如果調用 getBean 獲取得到的其實是 FactoryBean#getObject() 方法返回的結果。
為什么要這樣做?
假設你依賴一個第三方的類 A,而我們又不能修改第三方的類,并且這個對象創(chuàng)建比較復雜,那么你就可以創(chuàng)建一個 bean 來封裝它:
public class AFactoryBean implements FactoryBean<A> {
public A getObject() throws Exception {
A a = new A();
a.setXXX
....
...
return A
}
....省略一些實現
}
這樣,我們 getBean("A") 會得到 AFactoryBean#getObject 的結果。
如果單純只想要 AFactoryBean, 那么加個 “&” 即可,即 getBean("&A")
從命名角度來看,它是一個工廠。
好吧,攤牌了,沒啥特殊含義,就是一個工廠。
在前面我寫的循環(huán)依賴文章里就用到它了,三級緩存的 map 里面存儲的就是 ObjectFactory,用于延遲代理對象的創(chuàng)建。
其實就是封裝對象的創(chuàng)建過程,像三級緩存里的 ObjectFactory 邏輯就是判斷這個 Bean 是否有代理,如果有則返回代理對象,沒有則返回原來傳入的對象。
ApplicationContext 對我們來說應該很熟悉,我們基本上都是基于 ApplicationContext 操作的。
它也實現了 BeanFactory 這個接口,也屬于一個 BeanFactory ,但是它內部還包裝了一個 BeanFactory 的實現,這屬于組合。
而關于 Spring Beans 的一些操作都是委托內部的 BeanFactory 來操作的。
所以它有 BeanFactory 的所有功能,并且基于此它還擴展了很多其他功能:
因此,我們開發(fā)直接用的肯定是 ApplicationContext 而不是 BeanFactory。
從官網,我們很容易可以得知,最新版本一共有六種作用域:
別背網上那些多年前的答案了,以上才是最新的~
其實官網上關于注入就寫了構造器和setter :
像字段注入其實官方是不推薦的使用的。
因為字段注入依賴注解,然后無法注入靜態(tài)字段,無法控制成員變量注入順序。
emmmm...怎么說呢,反正我字段注入用的最多,你們呢,哈哈哈。
。