Spring源碼擴展篇-BeanDefinitionRegistryPostProcessor

把一個bean註冊到spring容器,一般有3個方法可以實現:
我們開發的類,如果想註冊到spring容器,讓spring來完成實例化,常用方式如下:
1. xml中通過bean節點來配置;
2. 使用@Service、@Controller、@Conponent等註解;
3.使用bean自定義註冊工廠處理器

 

可以參考下面它的執行核心原理和步驟

boolean reiterate = true;
while (reiterate) {
    reiterate = false;
    //查出所有實現了BeanDefinitionRegistryPostProcessor接口的bean名稱
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
        //前面的邏輯中,已經對實現了PriorityOrdered和Ordered的bean都處理過了,因此通過processedBeans過濾,processedBeans中沒有的纔會在此處理
        if (!processedBeans.contains(ppName)) {
            //根據名稱和類型獲取bean
            BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
            //把已經調用過postProcessBeanDefinitionRegistry方法的bean全部放在registryPostProcessors中
            registryPostProcessors.add(pp);
            //把已經調用過postProcessBeanDefinitionRegistry方法的bean的名稱全部放在processedBeans中
            processedBeans.add(ppName);
            //執行此bean的postProcessBeanDefinitionRegistry方法
            pp.postProcessBeanDefinitionRegistry(registry);
            //改變退出while的條件
            reiterate = true;
        }
    }
}

//registryPostProcessors中保存了所有執行過postProcessBeanDefinitionRegistry方法的bean,
//現在再來執行這些bean的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
//regularPostProcessors中保存的是所有入參中帶來的BeanFactoryPostProcessor實現類,並且這裏面已經剔除了BeanDefinitionRegistryPostProcessor的實現類,現在要讓這些bean執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

下面看一下如何把自定義的bean通過它註冊到spring容器中

 

下面把這個bean註冊到spring容器

@Component
public class CustomizeBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
    //打印當前堆棧信息    
        Utils.printTrack("execute postProcessBeanDefinitionRegistry");

    //創建一個bean的定義類的對象,bean類型是CalculateServiceImpl
        RootBeanDefinition helloBean = new RootBeanDefinition(CalculateServiceImpl.class);

        //bean的定義註冊到spring環境
        beanDefinitionRegistry.registerBeanDefinition("calculateService", helloBean);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    //打印當前堆棧信息        
        Utils.printTrack("execute postProcessBeanFactory");
    }
}

這樣後面就可以使用了,等於給bean加了個名字...

 

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