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