天天看點

spring系列——BeanFactory接口系列、IoC容器機制原理

目錄

1、IoC容器存儲bean的原理:

2、BeanFactory接口的繼承關系

BeanFactory是生産bean執行個體化對象的工廠類,要生産,首先要有呀,所有BeanFactory以及它的各種實作類,其實就是各種實作不同的容器,這些容器可以統稱為IoC容器。

容器有各種不同的容器(Factory),容器之間可能就會有繼承關系,這個上下級的繼承關系就是容器分層,也許父容器有自己的存儲bean的結構,子容器也有自己的存儲bean的結構。

1、IoC容器存儲bean的原理:

資料正規介紹為三個過程:1,用Resource接口找到資源檔案。2,将檔案中的bean轉換為spring需要的BeanDefinition結構。3,将這些BeanDefinition注冊(就是存進規定的ConcurrentHashMap結構中)。

下面是通俗的、詳細的介紹:

1、使用者編定義好bean,此時的bean是使用者層面的。

2、啟動spring,spring去讀取資源、配置等等檔案,擷取每一個bean的資訊,将每一個bean及其相關的資訊封裝成BeanDefinition類對象(class對象)形式,BeanDefinition形式是spring層面的(spring需要的),然後将這些BeanDefinition對象存儲在一個beanDefinitionMap(ConcurrentHashMap結構)中,這叫注冊。

3、當使用者通過BeanFactory調用getBean()去擷取某個bean的執行個體化對象時,(注意:單例模式的bean有專門的結構存儲),如果這個bean是單例模式,就先去SingletonObjects(ConcurrentHashMap結構,專門存儲單例模式bean的執行個體化對象)裡面看看是否已經有這個bean的對象,有就傳回,沒有的話,則去beanDefinitionMap中查找這個bean對應的BeanDefinition,如果沒有,則報錯,如果有,就根據BeanDefinition裡的資訊生成一個對象(通過反射機制生成對象),同時還要把這個對象存儲到SingletonObjects結構中去(因為這個bean是單例模式),然後傳回此對象。如果我們getBean() 要擷取的bean是原型模式,那就直接去beanDefinitionMap中去找,如果沒有這個bean的BeanDefinition,就報錯,如果有,就生成對象并傳回對象(不存到SingletonObjects中哦~)。

這就是我們說的IoC容器管理着bean。

問題1,根據BeanDefinition如果生成一個對象呢?使用者在定義bean的時候,有兩種:一種是構造函數形式、另一個種是property形式,就根據這個,如果是第一種的話,就用構造函數生成對象,如果是第二種的話,運作空構造函數,然後用setter方法完成初始化。預設是第二種。

問題2,java類在xml檔案中就反映為bean,類之間的引用關系,在xml中就表現為依賴,那什麼時候将依賴注入呢?在bean執行個體化的時候就注入依賴。什麼時候執行個體化呢?第一,容器初始化的時候,有些bean設定了lazy-init屬性為false,意思就是不延遲執行個體化,即在容器初始化的時候就初始化(初始化就是執行個體化)這些bean。第二,使用者調用getBean()的時候,即要用的時候,才是執行個體化這些bean。

2、BeanFactory接口的繼承關系

spring系列——BeanFactory接口系列、IoC容器機制原理

主要将重點放在BeanFactory 和 ApplicationContext 方向上。 實作類重點在 DefaultListableBeanFactory類。

對于BeanFactory接口的實作有很多,本文隻講比較重要的。

我們常說bean都交給容器管理了,當需要的時候,拿就行了。BeanFactory接口是給使用者用的,通過BeanFactory接口的實作類的具體方法,我們可以擷取到bean的執行個體化對象,這就是BeanFactory的主要作用。

BeanFactory接口定義了基本的bean操作:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
    //各種形式的擷取bean方法
    Object getBean(String var1) throws BeansException;
    <T> T getBean(String var1, Class<T> var2) throws BeansException;
    Object getBean(String var1, Object... var2) throws BeansException;
    <T> T getBean(Class<T> var1) throws BeansException;
    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
   
    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);
    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);
    //容器是否含有指定名字的bean
    boolean containsBean(String var1);
    //指定名字的bean是否是單例模式
    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
    //指定名字的bean是否是原型模式
    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
    //指定名字的bean是否是var2類型
    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
    //查詢指定名字的class類型
    @Nullable
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
    //查詢指定名字的bean的所有别名
    String[] getAliases(String var1);
}
           

BeanFactory接口隻是入口,有各種實作類,這些實作類都各自有特色功能,比如:XmlBeanFactory類,這個類的内部有一個類叫XmlBeanDefinitionReader,這個Reader類就負責讀取xml檔案,然後解析xml檔案中的資訊。

3、 ListableBeanFactory 接口系列

ListableBeanFactory接口源碼如下:

繼承了BeanFactory接口,同時也定義了自己的方法。代碼中的注釋,由于一個BeanDefinition對應一個Bean,基本資訊是一樣的,隻是資料結構不同。接口中每個方法定義了基本的操作,但是具體如何實作,還需看具體的實作類,有一個簡單的實作類StaticListableBeanFactory類,這個類不重要,不作介紹。

public interface ListableBeanFactory extends BeanFactory {
    //此bean工廠是否包含名字為var1的bean的BeanDefinition
    boolean containsBeanDefinition(String var1); 
    //傳回BeanDefinition的個數
    int getBeanDefinitionCount();
    //傳回所有BeanDefinition的名字
    String[] getBeanDefinitionNames();
    //傳回指定類型的所有的Bean的名字
    String[] getBeanNamesForType(ResolvableType var1);
    String[] getBeanNamesForType(@Nullable Class<?> var1);
    String[] getBeanNamesForType(@Nullable Class<?> var1, boolean var2, boolean var3);
    //傳回指定類型的所有Bean
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> var1) throws BeansException;
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> var1, boolean var2, boolean var3) throws BeansException;
    //傳回所有帶有此注解的bean的名字
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> var1);
    //傳回所有帶有此注解的bean
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> var1) throws BeansException;
    //傳回指定bean的注解
    @Nullable
    <A extends Annotation> A findAnnotationOnBean(String var1, Class<A> var2) throws NoSuchBeanDefinitionException;
}
           

4、DefaultListableBeanFactory 類

其它的接口定義,最終都被DefaultListableBeanFactory類實作了,DefaultListableBeanFactory類是spring 預設情況下使用的基本容器,我們就直接看它吧:

下圖,我覺得很簡單明了,是以貼在這,借用的是:https://www.cnblogs.com/duanxz/p/3787884.html 這篇文章中的一個圖。

spring系列——BeanFactory接口系列、IoC容器機制原理