javascript
Spring(2)——Spring IoC 详解
Spring IoC 概述
IoC:Inverse of Control(控制反轉(zhuǎn))
- 讀作“反轉(zhuǎn)控制”,更好理解,不是什么技術(shù),而是一種設計思想,就是將原本在程序中手動創(chuàng)建對象的控制權(quán),交由Spring框架來管理。
- 正控:若要使用某個對象,需要自己去負責對象的創(chuàng)建
- 反控:若要使用某個對象,只需要從 Spring 容器中獲取需要使用的對象,不關(guān)心對象的創(chuàng)建過程,也就是把創(chuàng)建對象的控制權(quán)反轉(zhuǎn)給了Spring框架
- 好萊塢法則:Don’t call me ,I’ll call you
一個例子
控制反轉(zhuǎn)顯然是一個抽象的概念,我們舉一個鮮明的例子來說明。
在現(xiàn)實生活中,人們要用到一樣東西的時候,第一反應就是去找到這件東西,比如想喝新鮮橙汁,在沒有飲品店的日子里,最直觀的做法就是:買果汁機、買橙子,然后準備開水。值得注意的是:這些都是你自己“主動”創(chuàng)造的過程,也就是說一杯橙汁需要你自己創(chuàng)造。
然而到了今時今日,由于飲品店的盛行,當我們想喝橙汁時,第一想法就轉(zhuǎn)換成了找到飲品店的聯(lián)系方式,通過電話等渠道描述你的需要、地址、聯(lián)系方式等,下訂單等待,過一會兒就會有人送來橙汁了。
請注意你并沒有“主動”去創(chuàng)造橙汁,橙汁是由飲品店創(chuàng)造的,而不是你,然而也完全達到了你的要求,甚至比你創(chuàng)造的要好上那么一些。
Spring IoC 闡述
這就是一種控制反轉(zhuǎn)的理念,上述的例子已經(jīng)很好的說明了問題,我們再來描述一下控制反轉(zhuǎn)的概念:控制反轉(zhuǎn)是一種通過描述(在 Java 中可以是 XML 或者注解)并通過第三方(Spring)去產(chǎn)生或獲取特定對象的方式。
- 好處:
降低對象之間的耦合
我們不需要理解一個類的具體實現(xiàn),只需要知道它有什么用就好了(直接向 IoC 容器拿)
主動創(chuàng)建的模式中,責任歸于開發(fā)者,而在被動的模式下,責任歸于 IoC 容器,基于這樣的被動形式,我們就說對象被控制反轉(zhuǎn)了。(也可以說是反轉(zhuǎn)了控制)
Spring IoC 容器
Spring 會提供?IoC 容器來管理和容納我們所開發(fā)的各種各樣的 Bean,并且我們可以從中獲取各種發(fā)布在 Spring IoC 容器里的 Bean,并且通過描述可以得到它。
Spring IoC 容器的設計
Spring IoC 容器的設計主要是基于以下兩個接口:
- BeanFactory
- ApplicationContext
其中 ApplicationContext 是 BeanFactory 的子接口之一,換句話說:BeanFactory 是 Spring IoC 容器所定義的最底層接口,而 ApplicationContext 是其最高級接口之一,并對 BeanFactory 功能做了許多的擴展,所以在絕大部分的工作場景下,都會使用 ApplicationContext 作為 Spring IoC 容器。
BeanFactory
從上圖中我們可以幾乎看到, BeanFactory 位于設計的最底層,它提供了 Spring IoC 最底層的設計,為此,我們先來看看該類中提供了哪些方法:
由于這個接口的重要性,所以有必要在這里作一下簡短的說明:
- 【getBean】 對應了多個方法來獲取配置給 Spring IoC 容器的 Bean。
① 按照類型拿 bean:
bean = (Bean) factory.getBean(Bean.class);
注意:要求在 Spring 中只配置了一個這種類型的實例,否則報錯。(如果有多個那 Spring 就懵了,不知道該獲取哪一個)
② 按照 bean 的名字拿 bean:
bean = (Bean) factory.getBean("beanName");
注意:這種方法不太安全,IDE 不會檢查其安全性(關(guān)聯(lián)性)
③ 按照名字和類型拿 bean:(推薦)
bean = (Bean) factory.getBean("beanName", Bean.class); - 【isSingleton】 用于判斷是否單例,如果判斷為真,其意思是該 Bean 在容器中是作為一個唯一單例存在的。而【isPrototype】則相反,如果判斷為真,意思是當你從容器中獲取 Bean,容器就為你生成一個新的實例。
注意:在默認情況下,【isSingleton】為 ture,而【isPrototype】為 false - 關(guān)于 type 的匹配,這是一個按 Java 類型匹配的方式
- 【getAliases】方法是獲取別名的方法
這就是 Spring IoC 最底層的設計,所有關(guān)于 Spring IoC 的容器將會遵守它所定義的方法。
ApplicationContext
根據(jù) ApplicationContext 的類繼承關(guān)系圖,可以看到 ApplicationContext 接口擴展了許許多多的接口,因此它的功能十分強大,所以在實際應用中常常會使用到的是 ApplicationContext 接口,因為 BeanFactory 的方法和功能較少,而 ApplicationContext 的方法和功能較多。
通過上一篇 IoC 的例子,我們來認識一個 ApplicationContext 的子類——ClassPathXmlApplicationContext。
這樣就會使用 Application 的實現(xiàn)類 ClassPathXmlApplicationContext 去初始化 Spring IoC 容器,然后開發(fā)者就可以通過 IoC 容器來獲取資源了啦!
關(guān)于 Spring Bean 的裝配以及一些細節(jié),會在下一篇文章中講到
ApplicationContext 常見實現(xiàn)類:
1.ClassPathXmlApplicationContext:
讀取classpath中的資源
2:FileSystemXmlApplicationContext:-
讀取指定路徑的資源
3.XmlWebApplicationContext:
需要在Web的環(huán)境下才可以運行
BeanFactory 和 ApplicationContext 的區(qū)別:
- BeanFactory:是Spring中最底層的接口,只提供了最簡單的IoC功能,負責配置,創(chuàng)建和管理bean。
在應用中,一般不使用 BeanFactory,而推薦使用ApplicationContext(應用上下文),原因如下。 - ApplicationContext:
1.繼承了 BeanFactory,擁有了基本的 IoC 功能;
2.除此之外,ApplicationContext 還提供了以下功能:
① 支持國際化;
② 支持消息機制;
③ 支持統(tǒng)一的資源加載;
④ 支持AOP功能;
Spring IoC 的容器的初始化和依賴注入
雖然 Spring IoC 容器的生成十分的復雜,但是大體了解一下 Spring IoC 初始化的過程還是必要的。這對于理解 Spring 的一系列行為是很有幫助的。
注意:Bean 的定義和初始化在 Spring IoC 容器是兩大步驟,它是先定義,然后初始化和依賴注入的。
- Bean 的定義分為 3 步:
1.Resource 定位
Spring IoC 容器先根據(jù)開發(fā)者的配置,進行資源的定位,在 Spring 的開發(fā)中,通過 XML 或者注解都是十分常見的方式,定位的內(nèi)容是由開發(fā)者提供的。
2.BeanDefinition 的載入
這個時候只是將 Resource 定位到的信息,保存到 Bean 定義(BeanDefinition)中,此時并不會創(chuàng)建 Bean 的實例
3.BeanDefinition 的注冊
這個過程就是將 BeanDefinition 的信息發(fā)布到 Spring IoC 容器中
注意:此時仍然沒有對應的 Bean 的實例。
做完了以上 3 步,Bean 就在 Spring IoC 容器中被定義了,而沒有被初始化,更沒有完成依賴注入,也就是沒有注入其配置的資源給 Bean,那么它還不能完全使用。
對于初始化和依賴注入,Spring Bean 還有一個配置選項——【lazy-init】,其含義就是是否初始化 Spring Bean。在沒有任何配置的情況下,它的默認值為 default,實際值為 false,也就是?Spring IoC 默認會自動初始化 Bean。如果將其設置為 true,那么只有當我們使用 Spring IoC 容器的 getBean 方法獲取它時,它才會進行 Bean 的初始化,完成依賴注入。
IoC 是如何實現(xiàn)的
最后我們簡單說說IoC是如何實現(xiàn)的。想象一下如果我們自己來實現(xiàn)這個依賴注入的功能,我們怎么來做? 無外乎:
我們發(fā)現(xiàn)其實自己來實現(xiàn)也不是很難,Spring實際也就是這么做的。這么看的話其實IoC就是一個工廠模式的升級版!當然要做一個成熟的IoC框架,還是非常多細致的工作要做,Spring不僅提供了一個已經(jīng)成為業(yè)界標準的Java IoC框架,還提供了更多強大的功能,所以大家就別去造輪子啦!希望了解IoC更多實現(xiàn)細節(jié)不妨通過學習Spring的源碼來加深理解!
引用地址:這里
【參考資料】:《Java EE 互聯(lián)網(wǎng)輕量級框架整合開發(fā)》、《Spring 實戰(zhàn)(第四版)》
【好文推薦】:①Spring 的本質(zhì)系列(1) -- 依賴注入、?②Spring的IoC原理
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處!
簡書ID:@我沒有三顆心臟
總結(jié)
以上是生活随笔為你收集整理的Spring(2)——Spring IoC 详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring MVC【入门】就这一篇
- 下一篇: Spring(3)——装配 Spring