天天看點

SpringIOC知其然一、SpringIOC的定義二、DefaultListableBeanFactory與BeanFactory的關系BeanFactory作用BeanDefinitionRegistry的作用AbstractBeanDefinition

一、SpringIOC的定義

關于SpringIOC的定義,網上應該也是一大堆,無非就是複制粘貼了,我這邊也就不長篇累牍的說明;

SpringIOC的核心就在于BeanFactory的容器接口,之前的知識我也隻是知道在這一塊了,接下來就開始正式學習關于SpringIOC相關的一些底層的知識;

二、DefaultListableBeanFactory與BeanFactory的關系

DefaultListableBeanFactory可以說是IOC容器的始祖,他是BeanFactory接口的實作類,我們可以檢視類圖;

SpringIOC知其然一、SpringIOC的定義二、DefaultListableBeanFactory與BeanFactory的關系BeanFactory作用BeanDefinitionRegistry的作用AbstractBeanDefinition

由類圖得知,DefaultListableBeanFactory這個類有兩個我們認識的大佬,第一位大佬就是BeanFactory,而第二位大佬,很明顯就是我們的BeanDefinitionRegistry,這個接口是用來幹嘛的呢,我現在還不清楚,接着往下面走;

哦,對了這個主題他們的關系,就由圖中得知了,DefaultListableBeanFactory是一個實作類,具體的源碼,我就不貼了,繼續往下學;

BeanFactory作用

發現不看這個代碼是不行了,我就不貼出來了,把中間幾個重要的方法看一下

顯而易見,我們經常用到的不管是配置檔案還是注解的方式注入對象之前,第一步我們就是去getBean,顯然,BeanFactory接口已經提供了這個方法;

Object getBean(String var1) throws BeansException;

  <T> T getBean(String var1, Class<T> var2) throws BeansException;
           

很顯然,BeanFactory的作用就是用來擷取我們日常使用的bean的,

既然getBean,那接下來又有一個疑問,從哪裡進行set的,回到剛剛的類圖,百度一下那個BeanDefinitionRegistry的英文

Bean Definition Registry

bean定義系統資料庫

so?

BeanDefinitionRegistry的作用

漸漸明了,Spring是通過BeanDefinitionRegistry進行注入,BeanDefinitionRegistry這個接口相對于核心的代碼如下:

void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
           

雖然是個4級沒過的學渣,但還是看懂了這個方法是幹嘛的,明顯是注冊bean用的,就像如果沒猜錯,這第一個參數Sring應該是就bean的名稱,配置檔案和注解的起源

<bean id="var1" />
@Service("var1")
...
           

應該是這樣吧,那現在存在疑問的就是BeanDefinition這個參數是怎麼來的

那就看一下這個東西有些什麼子類

SpringIOC知其然一、SpringIOC的定義二、DefaultListableBeanFactory與BeanFactory的關系BeanFactory作用BeanDefinitionRegistry的作用AbstractBeanDefinition

咱也不敢問,咱也不敢說,反正我就看到了AbstractBeanDefinition這個,還有一個可疑人員AnnotatedBeanDefinition

AbstractBeanDefinition

SpringIOC知其然一、SpringIOC的定義二、DefaultListableBeanFactory與BeanFactory的關系BeanFactory作用BeanDefinitionRegistry的作用AbstractBeanDefinition

看類圖得知,這個玩意是BeanDefinition的抽象類,那麼可以說明,AbstractBeanDefinition可能是實作了BeanDefinition裡面的方法的,沒辦法,這還是個抽象類,那我隻能找找最終實作類了

兜兜轉轉找到一個看起來比較靠譜的實作類名字叫做RootBeanDefinition,類圖我就不貼了,我不管,反正我看這個RootBeanDefinition的構造方法裡面有個比較厲害的東西

public RootBeanDefinition(@Nullable Class<?> beanClass) {
        this.setBeanClass(beanClass);
    }
           

是的,就是這個,beanClass,我又不是瞎子,自然之道這個beanClass是指的我們要進行注入的類咯;

是以,開幹

在SpringBoot的項目中嘗試一下

//首先聲明并且執行個體化beanFactory這個工廠類
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

//用RootBeanDefinition這個類進行執行個體化
AbstractBeanDefinition beanDefinitionRegistry = new RootBeanDefinition(Date.class);

//毫無疑問的開始注冊Bean
//感覺應該XML或者注解的方式都是這麼注入的,具體的得學習到後面再啪啪打臉
beanFactory.registerBeanDefinition("date", beanDefinitionRegistry);

//測試一下是不是直接可以拿到Bean
 Date date = (Date) beanFactory.getBean("date");
 
//列印一下時間
 System.out.println(date);

           

哦豁,竟然真的輸出了結果

SpringIOC知其然一、SpringIOC的定義二、DefaultListableBeanFactory與BeanFactory的關系BeanFactory作用BeanDefinitionRegistry的作用AbstractBeanDefinition

好吧,我們現在就已經知其然了,下一篇就學習一下,Spring是怎麼從registerBeanDefinition到getBean這個過程,說到底也就是這一句代碼

//這一句
beanFactory.registerBeanDefinition("date", beanDefinitionRegistry);
//或者這一句
Date date = (Date) beanFactory.getBean("date");

           

繼續閱讀