Spring IoC - Spring IoC 的設計

前言

本文爲解讀Spring IoC 模塊源碼的開篇介紹。介紹Spring IoC 的相關概念與設計。java

What is IoC

控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,能夠用來減低計算機代碼之間的耦合度。其中最多見的方式叫作依賴注入(Dependency Injection,簡稱DI),還有一種方式叫「依賴查找」(Dependency Lookup)。經過控制反轉,對象在被建立的時候,由一個調控系統內全部對象的外界實體,將其所依賴的對象的引用傳遞(注入)給它。spring

-- 摘自維基百科編程

大型應用中,須要多個類組合工做來實現業務邏輯。這使得每一個對象都須要在工做的時候獲取到與其合做的對象的引用。數據結構

若是這個獲取過程要靠自身來實現,那麼,代碼會變得高度耦合而且難以測試。這對複雜的OOP系統的設計是很是不利的。框架

在OOP系統中,對象封裝了數據和對數據的處理動做,對象的依賴關係體如今了對數據和方法的依賴上。這些依賴關係,能夠經過把對象的依賴注入交給框架或IoC容器來完成。oop

簡單來講:源碼分析

  • 控制:當前對象對其內部成員對象的控制權/獲取組裝對象的過程
  • 反轉:上述的過程/控制權,交由專門的第三方組件(容器或者說平臺)來管理

這種從具體對象手中,交出控制的作法,在解耦代碼的同時提升了代碼的可測試性。好處具體以下:post

  1. 不用本身組裝,拿來就用。
  2. 享受單例的好處,效率高,不浪費空間。
  3. 便於單元測試,方便切換mock組件。
  4. 便於進行AOP操做,對於使用者是透明的。
  5. 統一配置,便於修改。

Spring IoC

在Spring中,IoC容器是實現這個模式的載體,它能夠在對象生成或初始化時直接將數據注入到對象中,也能夠經過將對象引用注入到對象數據域中的方式來注入對方法調用的依賴。這種依賴注入是能夠遞歸的,對象被逐層注入單元測試

就此而言,這種方案有一種完整而簡潔的美感,它把對象的依賴關係有序地創建起來,簡化了對象依賴關係的管理,在很大程度上簡化了面向對象系統的複雜性。學習

Spring IoC提供了一個基本的JavaBean容器,經過IoC模式管理依賴關係,並經過依賴注入和AOP切面加強了爲JavaBean這樣的POJO對象賦予事務管理、生命週期管理等基本功能。

IoC 容器的設計

在Spring IOC 容器的設計當中,咱們能夠看到兩個主要的容器系列(根據命名),

  • 實現了BeanFactory接口的簡單容器系列,只實現了容器的最基本功能;
  • ApplicationContext應用上下文,容器的高級形態,增長了許多面向框架的特性和對應用環境的適配;

對於使用者來講,這些都是容器,是容器的不一樣表現形式,使用什麼樣的容器徹底取決於使用者的需求。

undefined

BeanFactory

BeanFactory接口定義了IoC容器最基本的形式,而且提供了IoC容器所應該遵照的最基本的服務契約,同時,這也是咱們使用IoC容器所應遵照的最底層和最基本的編程規範,這些接口定義勾畫出了IoC的基本輪廓。

往下的整個繼承樹是蠻複雜的,你也不須要全部都掌握,就想咱們以前提過的怎麼學習源碼,找核心類。如今來挑幾個重點的BeanFactory說一下。避免後面源碼分析章節會一臉懵逼。

  • ListableBeanFactory,這個 Listable 的意思就是,經過這個接口,咱們能夠獲取多個 Bean,你們看源碼會發現,最頂層 BeanFactory 接口的方法都是獲取單個 Bean 的。
  • ApplicationContext 繼承了 HierarchicalBeanFactory,Hierarchical 單詞自己已經能說明問題了,也就是說咱們能夠在應用中起多個 BeanFactory,而後能夠將各個 BeanFactory 設置爲父子關係。
  • AutowireCapableBeanFactory 這個名字中的 Autowire 你們都很是熟悉,它就是用來自動裝配 Bean 用的,可是仔細看上圖,ApplicationContext 並無繼承它,不過不用擔憂,不使用繼承,不表明不可使用組合,若是你看到 ApplicationContext 接口定義中的最後一個方法 getAutowireCapableBeanFactory() 就知道了。
  • DefaultListableBeanFactory,在Spring中,其實是把DefaultListableBeanFactory做爲一個默認的功能完整的IoC容器來使用的。包含了基本IoC容器所具備的重要功能。

以上接口,推薦你們去閱讀一下他們的JavaDoc,來了解做者是怎麼描述的。更爲準確。

ApplicationContext

ApplicationContext是一個高級形態意義的IoC容器,ApplicationContext在BeanFactory的基礎上集成了MessageSource, ApplicationEventPublisher, ResourcePatternResolver這幾個接口,這些接口爲ApplicationContext提供瞭如下BeanFactory不具有的新特性:

  • 支持不一樣的信息源。咱們看到ApplicationContext擴展了MessageSource接口,這些信息源的擴展功能能夠支持國際化的實現,爲開發多語言版本的應用提供服務。
  • 訪問資源。這一特性體如今對ResourceLoader和Resource的支持上,這樣咱們能夠從不一樣地方獲得Bean定義資源。這種抽象使用戶程序能夠靈活地定義Bean定義信息,尤爲是從不一樣的I/O途徑獲得Bean定義信息。
  • 支持應用事件。繼承了接口ApplicationEventPublisher,從而在上下文中引入了事件機制。這些事件和Bean的生命週期的結合爲Bean的管理提供了便利。
  • 在ApplicationContext中提供的附加服務。這些服務使得基本IoC容器的功能更豐富。由於具有了這些豐富的附加功能,使得ApplicationContext與簡單的BeanFactory相比,對它的使用是一種面向框架的使用風格,因此通常建議在開發應用時使用ApplicationContext做爲IoC容器的基本形式。

BeanDefinition

在這些Spring提供的基本IoC容器的接口定義和實現的基礎上,Spring經過定義BeanDefinition來管理基於Spring的應用中的各類對象以及它們之間的相互依賴關係。

BeanDefinition 中保存了咱們的 Bean 信息,好比這個 Bean 指向的是哪一個類、是不是單例的、是否懶加載、這個 Bean 依賴了哪些 Bean 等等。

image.png

BeanDefinition抽象了咱們對Bean的定義,是讓容器起做用的主要數據類型。對IoC容器來講,BeanDefinition就是對依賴反轉模式中管理的對象依賴關係的數據抽象,也是容器實現依賴反轉功能的核心數據結構,依賴反轉功能都是圍繞對這個BeanDefinition的處理來完成的。

這些BeanDefinition就像是容器裏裝的水,有了這些基本數據,容器纔可以發揮做用。

結語

接下去的章節咱們會正式開始分析Spring IoC 的具體實現,容器的初始化和依賴注入是怎麼實現的。大部分都是源碼解讀的內容。

若是以前沒有閱讀源碼經驗的同窗,能夠先看看這篇你爲何要看源碼?如何看源碼?

參考

相關文章
相關標籤/搜索