『網際網路架構』軟體架構-spring原始碼之spring ioc(九)
上次說了spring的體系結構和概要大概有那些模組,spring ioc是最核心最原始的一個框架,其實就是spring的老本,spring就是依靠著ioc,慢慢發展到其他Data,web,AOP上的。記得當初專案裡面使用spring的時候,就知道配置個xml,在struts2上引用spring配置的bean,引用這個類就可以直接用了,不用直接new了,完全不管原理,確實方便但是需要配置2次,一次是spring bean.xml,一次是struts引用的時候配置。這次主要看看spring IOC底層是如何實現的。
Spring IOC
IOC容器的組成和體系架構
- 什麼是IOC
IoC 不是一種技術,只是一種思想,一個重要的面向物件程式設計的法則,它能指導我們如何設計出鬆耦合、更優良的程式。傳統應用程式都是由我們在類內部主動建立依賴物件,從而導致類與類之間高耦合,難於測試;有了IoC容器後,把建立和查詢依賴物件的控制權交給了容器,由容器進行注入組合物件,所以物件與物件之間是 鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程式的整個體系結構變得非常靈活。 說白了就是管理bean(Bean的建立,Bean的儲存,Bean的獲取)。
- BeanFactory
BeanFactory是最基本的IOC容器介面,這個介面為具體的IOC容器的實現作了最基本的功能規定。
BeanFactory類結構體系
BeanFactory的原始碼解析
public interface BeanFactory { //這裡是對FactoryBean的轉義定義,因為如果使用bean的名字檢索FactoryBean得到的物件是工廠生成的物件, //如果需要得到工廠本身,加上“&” String FACTORY_BEAN_PREFIX = "&"; //根據bean的名字,在IOC容器中得到bean例項 Object getBean(String name) throws BeansException; //根據bean的名字和Class型別來得到bean例項,若根據名字取得的bean例項的Class型別和需要的不同的話 //會丟擲異常 <T> T getBean(String name, Class<T> requiredType) throws BeansException; //根據指定的型別取得IoC容器中管理的Bean <T> T getBean(Class<T> requiredType) throws BeansException; //過載了getBean(String name)方法,可變引數用來指定構造方法或者工廠方法需要的引數 //覆蓋之前已經在bean中定義好的引數 Object getBean(String name, Object... args) throws BeansException; //過載了getBean(Class<T> requiredType)方法,可變引數用來指定構造方法或者工廠方法需要的引數 //覆蓋之前已經在bean中定義好的引數 <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; //判斷在IOC容器是否 有這個名字的bean boolean containsBean(String name); //查詢指定名字的Bean是否是單態型別(singleton) boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //查詢指定名字的Bean是否是原型(prototype)型別 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //查詢指定名字的Bean的class型別是否支援特定的class型別 boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; //查詢指定名字的Bean的class型別 Class<?> getType(String name) throws NoSuchBeanDefinitionException; //查詢指定名字的Bean的所有別名 String[] getAliases(String name); }
beanFactroy 對bean的例項化過程
spring Ioc容器的實現,從根源上是beanfactory,但真正可以作為一個可以獨立使用的ioc容器還是DefaultListableBeanFactory,因此可以這麼說,
DefaultListableBeanFactory 是整個spring ioc的始祖,研究透它的前生今世對我們理解spring ioc的概念有著重要的作用。 Spring Bean的建立是典型的工廠模式,這一系列的Bean工廠,也即IOC容器為開發者管理物件間的依賴關係提供了很多便利和基礎服務,在Spring中有許多的IOC容器的實現供使用者選擇和使用,其相互關係如下:
- 管理Bean
- Bean的建立
- Bean的儲存
- Bean的獲取
- 自動完成依賴的檢測和注入
- 自動生成Bean
Beandefinition的定義組成
富士康的蘋果手機,研發都是美國那邊統一來進行的。也就是說富士康工廠本身是不會定義咱們的蘋果手機的,都是由美國的研發對蘋果手機進行定義,然後富士康對手機進行生產,儲存,運輸。蘋果手機就類似咱們的bean。
- Bean屬性的定義
- name
- id
- scope(單例,多例)
- className
- parent
- lazyInt
- depends
- property
- bean定義儲存
- xml
- properties
BeandefinitionReader載入解析Bean
spring提供了有兩種方式的bean definition解析器:PropertiesBeanDefinitionReader和XmLBeanDefinitionReader即屬性檔案格式的bean definition解析器和xml檔案格式的bean definition解析器。
- 載入檔案
- 轉換成Document
- 解析註冊Beandefinition
流程
- IOC容器的構建歸為以下六步
- 定義好Spring的配置檔案。
- 通過Resource物件將Spring配置檔案進行抽象,抽象成一個Resource物件。
定義好Bean工廠。 - 定義好XmlBeanDefinitionReader物件,並將工廠作為引數傳遞進去供後續回撥使用。
- 通過XmlBeanDefinitionReader物件讀取之前抽象出的Resource物件(包含了XML檔案的解析過程)。本質上,XML檔案的解析是由XmlBeanDefinitionReader交由
- BeanDefinitionParserDelegate委託來完成(用到了委託模式)
- IoC容器建立完畢,使用者可以通過容器獲取到所需的物件資訊。
- 簡化版流程
- 裝載BeanDefinition到beanfactroy中
- 獲取bean的時候去getBeanDefinition
- 然後createBean
流程圖
IOC容器全部的體系結構
PS:讀原始碼確實很麻煩,但是spring的原始碼大概120多MB,相當於一個JAVA的JDK了,讀了懟咱們日常開發真的很有用,設計到的模式:單例模式,工廠模式,建造者模式。
>>原創文章,歡迎轉載。轉載請註明:轉載自IT人故事會,謝謝!
>>原文連結地址:上一篇:已是最新文章