Spring注解驅(qū)動之BeanDefinitionRegistryPostProcessor原理解析
BeanDefinitionRegistryPostProcessor概述
可以看到BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。
注釋中說執(zhí)行時機是所有合法的bean定義已經(jīng)加載,但是還沒實例化。
看起來和BeanFactoryPostProcessor執(zhí)行時機差不多,但是BeanFactoryPostProcessor的注釋是所有bean定義被加載,而BeanDefinitionRegistryPostProcessor是所有合法的bean定義。
接著看注釋:
This allows for adding further bean definitions before the next post-processing phase kicks in.
意思是BeanDefinitionRegistryPostProcessor允許添加將來的bean定義在下一個后置處理器階段開始之前。簡單說就是還可以往容器中增加新的bean的定義。
因此,大概率BeanDefinitionRegistryPostProcessor的執(zhí)行順序在BeanFactoryPostProcessor之前。
案例實踐
首先,編寫一個類,例如MyBeanDefinitionRegistryPostProcessor,它應(yīng)要實現(xiàn)BeanDefinitionRegistryPostProcessor這個接口。
package com.meimeixia.ext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.stereotype.Component; import com.meimeixia.bean.Blue; // 記住,我們這個組件寫完之后,一定別忘了給它加在容器中 @Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // TODO Auto-generated method stub System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的數(shù)量:" + beanFactory.getBeanDefinitionCount()); } /** * 這個BeanDefinitionRegistry就是Bean定義信息的保存中心,這個注冊中心里面存儲了所有的bean定義信息, * 以后,BeanFactory就是按照BeanDefinitionRegistry里面保存的每一個bean定義信息來創(chuàng)建bean實例的。 * * bean定義信息包括有哪些呢?有這些,這個bean是單例的還是多例的、bean的類型是什么以及bean的id是什么。 * 也就是說,這些信息都是存在BeanDefinitionRegistry里面的。 */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessBeanDefinitionRegistry...bean的數(shù)量:" + registry.getBeanDefinitionCount()); // 除了查看bean的數(shù)量之外,我們還可以給容器里面注冊一些bean,我們以前也簡單地用過 /* * 第一個參數(shù):我們將要給容器中注冊的bean的名字 * 第二個參數(shù):BeanDefinition對象 */ // RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); // 現(xiàn)在我準備給容器中添加一個Blue對象 // 咱們也可以用另外一種辦法,即使用BeanDefinitionBuilder這個構(gòu)建器生成一個BeanDefinition對象,很顯然,這兩種方法的效果都是一樣的 AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition(); registry.registerBeanDefinition("hello", beanDefinition); } }
測試結(jié)果
可以看到,BeanDefinitionRegistryPostProcessor里面的兩個方法,postProcessBeanDefinitionRegistry在postProcessBeanFactory之前執(zhí)行。
BeanDefinitionRegistryPostProcessor比BeanFactoryPostProcessor先執(zhí)行。
源碼分析
自己在測試示例中方法打斷點,然后查看調(diào)用棧即可,下面是一些主要的代碼片段。
繼續(xù)向下看,可以看到會取出所有實現(xiàn)了BeanDefinitionRegistryPostProcessor接口的類,即從容器中獲取到所有的BeanDefinitionRegistryPostProcessor組件。
然后,優(yōu)先調(diào)用實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor組件。
點進去這個方法里面一看究竟,原來是先調(diào)用完BeanDefinitionRegistryPostProcessor組件里面的postProcessBeanDefinitionRegistry方法,然后再來調(diào)用它里面的postProcessBeanFactory方法。
我們再來仔細看一下PostProcessorRegistrationDelegate類中的invokeBeanFactoryPostProcessors方法,只不過這時是從程序停留的地方(即第122行代碼處)往下看,如下圖所示。
小結(jié)
BeanDefinitionRegistryPostProcessor的執(zhí)行流程。
1. 創(chuàng)建IOC容器。
2. 調(diào)用refresh方法。
3. 從IOC容器中獲取所有的BeanDefinitionRegistryPostProcessor組件,并依次觸發(fā)它們的postProcessBeanDefinitionRegistry方法,之后觸發(fā)它的postProcessBeanFactory方法。
4. 從IOC容器中獲取到所有的BeanFactoryPostProcessor組件,并依次觸發(fā)它們的postProcessBeanFactory方法。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot如何讀取配置文件(application.yml)中的屬性值
本篇文章主要介紹了springboot如何讀取配置文件(application.yml)中的屬性值,具有一定的參考價值,有興趣的小伙伴可以了解一下2017-04-04