IOC(Inversion of Control)控制反轉:所謂控制反轉,就是把原先咱們代碼裏面須要實現的對象建立、依賴的代碼,反轉給容器來幫忙實現。那麼必然的咱們須要建立一個容器,同時須要一種描述來讓容器知道須要建立的對象與對象的關係。這個描述最具體表現就是咱們可配置的文件。
DI(Dependency Injection)依賴注入:就是指對象是被動接受依賴類而不是本身主動去找,換句話說
就是指對象不是從容器中查找它依賴的類,而是在容器實例化對象的時候主動將它依賴的類注入給它。java
咱們本身如何設計一個IOC容器,會有哪些須要思考呢?
1. 對象和對象關係怎麼表示?
能夠用 xml,properties 文件等語義化配置文件表示。
2. 描述對象關係的文件存放在哪裏?
多是 classpath,filesystem,或者是 URL 網絡資源,servletContext 等。 spring
有了配置文件,還須要對配置文件解析。
不一樣的配置文件對對象的描述不同,如標準的,自定義聲明式的,如何統一?在內部須要有一個統一
的關於對象的定義,全部外部的描述都必須轉化成統一的描述定義。
如何對不一樣的配置文件進行解析?須要對不一樣的配置文件語法,採用不一樣的解析器。安全
Spring Bean 的建立是典型的工廠模式,這一系列的 Bean 工廠,也即 IOC 容器爲開發者管理對象間的依賴關係提供了不少便利和基礎服務,在 Spring 中有許多的 IOC 容器的實現供用戶選擇和使用,
其相互關係以下:網絡
其中 BeanFactory 做爲最頂層的一個接口類,它定義了IOC容器的基本功能規範,BeanFactory有三個直接的子類:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory。
可是從上圖中咱們能夠發現最終的默認實現類是DefaultListableBeanFactory,他實現了全部的接口。那爲什麼要定義這麼多層次的接口呢?查閱這些接口的源碼和說明發現,每一個接口都有他使用的場合,它主要是爲了區分在 Spring 內部在操做過程當中對象的傳遞和轉化過程當中,對對象的數據訪問所作的限制。例如ListableBeanFactory接口表示這些Bean是可列表的,而 HierarchicalBeanFactory表示的是這些Bean是有繼承關係的,也就是每一個Bean 有可能有父Bean。AutowireCapableBeanFactory接口定義 Bean 的自動裝配規則。這四個接口共同定義了Bean的集合、Bean之間的關係、以及 Bean行爲.ui
最基本的 IOC 容器接口 BeanFactoryspa
public interface BeanFactory {
//對 FactoryBean 的轉義定義,由於若是使用 bean 的名字檢索 FactoryBean 獲得的對象是工廠生成的對象,
//若是須要獲得工廠自己,須要轉義
String FACTORY_BEAN_PREFIX = "&";
//根據 bean 的名字,在 IOC 容器中獲取 bean 實例
Object getBean(String name) throws BeansException;
//根據 bean 的名字和 Class 類型來獲得 bean 實例,增長了類型安全驗證機制。
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
//根據名字和參數 在IOC容器中獲取bean的實例
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
//根據類型和參數 在IOC容器中獲取bean的實例
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
//提供對 bean 的檢索,看看是否在 IOC 容器有這個名字的 bean
boolean containsBean(String name);
//根據 bean 名字獲得 bean 實例,並同時判斷這個 bean 是否是單例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
//獲得 bean 實例的 Class 類型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//獲得 bean 的別名,若是根據別名檢索,那麼其原名也會被檢索出來
String[] getAliases(String name);
}
在 BeanFactory 裏只對 IOC 容器的基本行爲做了定義,根本不關心你的 Bean 是如何定義怎樣加載的。
正如咱們只關心工廠裏獲得什麼的產品對象,至於工廠是怎麼生產這些對象的,這個基本的接口不關心。設計
而要知道工廠是如何產生對象的,咱們須要看具體的IOC容器實現,Spring 提供了許多 IOC 容器的實現。好比XmlBeanFactory,ClasspathXmlApplicationContext 等。其中XmlBeanFactory就是針對最基本的IOC容器的實現,這個 IOC 容器能夠讀取 XML 文件定義的 BeanDefinition(XML 文件
中對 bean 的描述),若是說XmlBeanFactory是容器中的屌絲,ApplicationContext 應該算容器中的高帥富.不過在Spring5.0中XmlBeanFactory已經標誌爲廢棄。
ApplicationContext是Spring提供的一個高級的IOC容器,它除了可以提供 IOC 容器的基本功能外,還爲用戶提供瞭如下的附加服務。code
從 ApplicationContext 接口的實現,咱們看出其特色:
1.支持信息源,能夠實現國際化。(實現 MessageSource 接口)
2.訪問資源。(實現 ResourcePatternResolver 接口)
3.支持應用事件。(實現 ApplicationEventPublisher 接口) xml
SpringIOC 容器管理了咱們定義的各類 Bean 對象及其相互的關係,Bean 對象在 Spring 實現中是以 BeanDefinition來描述的,其繼承體系以下:
對象
Bean 的解析過程很是複雜,功能被分的很細,由於這裏須要被擴展的地方不少,必須保證有足夠的靈活性,以應對可能的變化。Bean的解析主要就是對 Spring 配置文件的解析。這個解析過程主要經過下圖中的類完成:
文檔有參考其餘資料,若是問題請聯繫我,進行刪除!