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類對象形式,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接口的繼承關係

 

主要將重點放在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 這篇文章中的一個圖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章