Spring 注解配置加載流程源碼解析(一)

1.說(shuō)明

其實(shí)spring對(duì)于xml解析與注解解析大體流程是一樣的,不過注解解析是利用BeanFactoryPostProcessor的后置處理器子類ConfigurationClassPostProcessor來(lái)進(jìn)行掃描的

2.上代碼:測(cè)試類

包的層級(jí)關(guān)系


image.png

Main方法

public class ApplicationAnnotationTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        ac.register(SpringConfig.class);
        ac.refresh();
        User2 user2 = (User2) ac.getBean("user2");
        User3 user3 = (User3) ac.getBean("user3");
        User user = (User) ac.getBean("user");

        System.out.println(user);
        System.out.println(user2);
        System.out.println(user3);
    }
}

User類

public class User {
    private String name;
    private String sex;

    public User(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

User2類

@Component
public class User2 {
    private String name;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User2{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

User3類


@Component
@PropertySource(value={"demo.properties"},encoding = "utf8")
public class User3 {
    @Value("${user3.name}")
    private String username;
    @Value("${user3.sex}")
    private String sex;


    @Override
    public String toString() {
        return "User3{" +
                "username='" + username + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

3.開始debug

    1. 兩種容器加載的區(qū)別
  //注解spring容器加載
 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
//配置文件spring容器加載
ClassPathXmlApplicationContext ac =   new ClassPathXmlApplicationContext("applicationContext.xml");

解析

AnnotationConfigApplicationContext

//省略一部分代碼
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
   ...........
}
//GenericApplicationContext  創(chuàng)建DefaultListableBeanFactory 工廠對(duì)象
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    private final DefaultListableBeanFactory beanFactory;
    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
  ...........
}

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        Assert.notNull(environment, "Environment must not be null");
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

ClassPathXmlApplicationContext

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 初始化BeanFactory,并進(jìn)行XML文件讀取薪夕,并將得到的BeanFactory記錄在當(dāng)前實(shí)體的屬性中
        refreshBeanFactory();
        // 返回當(dāng)前實(shí)體的beanFactory屬性
        return getBeanFactory();
    }

@Override
    protected final void refreshBeanFactory() throws BeansException {
        // 如果存在beanFactory理张,則銷毀beanFactory
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 創(chuàng)建DefaultListableBeanFactory對(duì)象
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 為了序列化指定id算灸,可以從id反序列化到beanFactory對(duì)象
            beanFactory.setSerializationId(getId());
            // 定制beanFactory蛤吓,設(shè)置相關(guān)屬性充活,包括是否允許覆蓋同名稱的不同定義的對(duì)象以及循環(huán)依賴
            customizeBeanFactory(beanFactory);
            // 初始化documentReader,并進(jìn)行XML文件讀取及解析,默認(rèn)命名空間的解析硼砰,自定義標(biāo)簽的解析
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
  1. AnnotationConfigApplicationContext
    AnnotationConfigApplicationContext 繼承于GenericApplicationContext 且蓬,在實(shí)例化AnnotationConfigApplicationContext 時(shí)候,先要執(zhí)行父類GenericApplicationContext 的構(gòu)造方法题翰,此時(shí)提前創(chuàng)建好了一個(gè)DefaultListableBeanFactory 工廠對(duì)象
  2. ClassPathXmlApplicationContext
    繼承于AbstractApplicationContext恶阴,在創(chuàng)建DefaultListableBeanFactory 工廠對(duì)象時(shí),是在refresh()方法中的obtainFreshBeanFactory方法中

綜上所述豹障,xml 文件的方式和純注解的方式 在 容器刷新前的工作并不相同冯事,但整體的處理流程是大體一致的。ClassPathXmlApplicationContext 是在內(nèi)部構(gòu)造函數(shù)中調(diào)用refresh()來(lái)進(jìn)行容器的刷新血公,最開始的容器中是不存在bean工廠的昵仅,AnnotationConfigApplicationContext 在調(diào)用refresh()方法前已經(jīng)將默認(rèn)的bean工廠創(chuàng)建完成,其次還注冊(cè)了一系列的BeanFactoryPostProcessor坞笙,BeanPostProccessor后置處理器以及監(jiān)聽器等等

我們看實(shí)例化后的AnnotationConfigApplicationContext


image.png

我們可以看到岩饼,構(gòu)造過程中提前將5個(gè)BeanDefinition對(duì)象提前放到了BeanDefinitionMap中;先大概了解一下每個(gè)BeanDefinition在之后的作用
BeanFactoryPostProcessor
1)internalConfigurationAnnotationProcessor 對(duì)應(yīng)的類是 ConfigurationClassPostProcessor
用來(lái)對(duì) @Component @ComponentScan @Configuration @Service @Controller @PropertySource @Import @ImportResource @Bean 進(jìn)行注解掃描
BeanPostProcessor
2)internalAutowiredAnnotationProcessor 對(duì)應(yīng)的類是 AutowiredAnnotationBeanPostProcessor
掃描@Autowired 注解,@Value注解薛夜,進(jìn)行屬性填充
internalCommonAnnotationProcessor 對(duì)應(yīng)的類是 CommonAnnotationBeanPostProcessor
掃描@Resource注解,@PreDestory,@PostConstruct注解籍茧,進(jìn)行屬性填充

  • 兩個(gè)BeanPostProcessor 進(jìn)行注解掃描時(shí),都是在實(shí)例化過后填充屬性之前進(jìn)行掃描梯澜,獲取對(duì)應(yīng)注解的元數(shù)據(jù)寞冯,通過調(diào)用postProcessMergedBeanDefinition 方法。在填充屬性的時(shí)候調(diào)用postProcessProperties 來(lái)進(jìn)行屬性填充

AutowiredAnnotationBeanPostProcessor

        //注解解析
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 解析注解并緩存
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
      // 屬性填充注入
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 從緩存中取出這個(gè)bean對(duì)應(yīng)的依賴注入的元信息~
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            // 進(jìn)行屬性注入
            metadata.inject(bean, beanName, pvs);
        }
        catch (BeanCreationException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
        }
        return pvs;
    }

CommonAnnotationBeanPostProcessor

    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 處理@PostConstruct和@PreDestroy注解
        super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
        //找出beanType所有被@Resource標(biāo)記的字段和方法封裝到InjectionMetadata中
        InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
        try {
            metadata.inject(bean, beanName, pvs);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
        }
        return pvs;
    }

3.

上邊已經(jīng)完成了AnnotationConfigApplicationContext 對(duì)象的創(chuàng)建晚伙,容器中目前已經(jīng)初始化好了需要的一些環(huán)境變量吮龄,Bean工廠,以及Bean工廠一些內(nèi)置的BeanDefinition(主要是BeanPostProcessor,BeanFactoryProcessor)和其他屬性咆疗,然后我們?cè)诳磖egister方法做了什么事情

image.png

1)

    @Override
    public void register(Class<?>... componentClasses) {
        Assert.notEmpty(componentClasses, "At least one component class must be specified");
        this.reader.register(componentClasses);
    }

    public void register(Class<?>... componentClasses) {
        for (Class<?> componentClass : componentClasses) {
            registerBean(componentClass);
        }
    }

    /**
     * Register a bean from the given bean class, deriving its metadata from
     * class-declared annotations.
     * @param beanClass the class of the bean
     */
    public void registerBean(Class<?> beanClass) {
        doRegisterBean(beanClass, null, null, null, null);
    }

doRegisterBean方法

第一步:先創(chuàng)建了一個(gè)AnnotatedGenericBeanDefinition 對(duì)象
第二步:解析@scope注解
第三步:解析 @Lazy @Role @DependOn @Primary 注解
第四步:判斷是否需要被代理
第五步://注冊(cè)BeanDefinition漓帚,將BeanDefinition 放到BeanFactory中

    public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
        setBeanClass(beanClass);
               //封裝配置類上的注解元數(shù)據(jù)信息
        this.metadata = AnnotationMetadata.introspect(beanClass);
    }

image.png
    private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
            @Nullable BeanDefinitionCustomizer[] customizers) {

        //創(chuàng)建AnnotatedGenericBeanDefinition 對(duì)象,獲取配置類上的注解元數(shù)據(jù)信息
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }

        abd.setInstanceSupplier(supplier);
        //獲取@scope注解
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
        //解析 @Lazy @Role @DependOn @Primary 注解
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        if (qualifiers != null) {
            for (Class<? extends Annotation> qualifier : qualifiers) {
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }
        if (customizers != null) {
            for (BeanDefinitionCustomizer customizer : customizers) {
                customizer.customize(abd);
            }
        }
        //包裝成BeanDefinitionHolder
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        //判斷是否需要被代理
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        //注冊(cè)BeanDefinition,將BeanDefinition 放到BeanFactory中
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

此時(shí)的SpringConfig 的 BeanDefinition 已經(jīng)成功注冊(cè)到DefaultListableBeanFactory中了午磁。這樣我們其實(shí)是在邏輯上已經(jīng)可以梳理通了尝抖,在調(diào)用register方法之后,容器會(huì)提前將配置類添加到BeanFactory的BeanDefinitionMap中迅皇,后續(xù)在調(diào)用refresh()方法的

image.png

4昧辽、重中之中:?jiǎn)为?dú)看ConfigurationClassPostProcessor BFPP怎樣進(jìn)行注解的解析工作的

Spring框架中最重要的方法: refresh()方法

  1. 為什么說(shuō)XML文件 和注解 兩種方式大體流程是一致的,主要原因就是因?yàn)閎ean的創(chuàng)建流程都是調(diào)用了AbstractFactory中的refresh方法登颓,refresh方法中包含了整個(gè)Bean的生命周期搅荞。從Bean實(shí)例化到初始化的整個(gè)過程
@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            /**
             * 前戲,做容器刷新前的準(zhǔn)備工作
             * 1、設(shè)置容器的啟動(dòng)時(shí)間
             * 2咕痛、設(shè)置活躍狀態(tài)為true
             * 3痢甘、設(shè)置關(guān)閉狀態(tài)為false
             * 4、獲取Environment對(duì)象暇检,并加載當(dāng)前系統(tǒng)的屬性值到Environment對(duì)象中
             * 5产阱、準(zhǔn)備監(jiān)聽器和事件的集合對(duì)象,默認(rèn)為空的集合
             */

            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 創(chuàng)建容器對(duì)象:DefaultListableBeanFactory
            // 加載xml配置文件的屬性值到當(dāng)前工廠中块仆,最重要的就是BeanDefinition
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // beanFactory的準(zhǔn)備工作,對(duì)各種屬性進(jìn)行填充
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // 子類覆蓋方法做額外的處理王暗,此處我們自己一般不做任何擴(kuò)展工作悔据,但是可以查看web中的代碼,是有具體實(shí)現(xiàn)的
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // 調(diào)用各種beanFactory處理器
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 注冊(cè)bean處理器俗壹,這里只是注冊(cè)功能科汗,真正調(diào)用的是getBean方法
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 為上下文初始化message源,即不同語(yǔ)言的消息體绷雏,國(guó)際化處理,在springmvc的時(shí)候通過國(guó)際化的代碼重點(diǎn)講
                initMessageSource();

                // Initialize event multicaster for this context.
                // 初始化事件監(jiān)聽多路廣播器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 留給子類來(lái)初始化其他的bean
                onRefresh();

                // Check for listener beans and register them.
                // 在所有注冊(cè)的bean中查找listener bean,注冊(cè)到消息廣播器中
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // 初始化剩下的單實(shí)例(非懶加載的)
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 完成刷新過程头滔,通知生命周期處理器lifecycleProcessor刷新過程,同時(shí)發(fā)出ContextRefreshEvent通知?jiǎng)e人
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                // 為防止bean資源占用涎显,在異常處理中坤检,銷毀已經(jīng)在前面過程中生成的單件bean
                destroyBeans();

                // Reset 'active' flag.
                // 重置active標(biāo)志
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

先關(guān)注一下當(dāng)前的BeanFactory中包含的BeanDefinition都有哪些?

image.png

4.1然后我們直接看BeanFactoryPostProcessor的執(zhí)行流程

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 獲取到當(dāng)前應(yīng)用程序上下文的beanFactoryPostProcessors變量的值期吓,并且實(shí)例化調(diào)用執(zhí)行所有已經(jīng)注冊(cè)的beanFactoryPostProcessor
        // 默認(rèn)情況下早歇,通過getBeanFactoryPostProcessors()來(lái)獲取已經(jīng)注冊(cè)的BFPP,但是默認(rèn)是空的讨勤,那么問題來(lái)了箭跳,如果你想擴(kuò)展,怎么進(jìn)行擴(kuò)展工作潭千?
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
        // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }
public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 無(wú)論是什么情況谱姓,優(yōu)先執(zhí)行BeanDefinitionRegistryPostProcessors
        // 將已經(jīng)執(zhí)行過的BFPP存儲(chǔ)在processedBeans中,防止重復(fù)執(zhí)行
        Set<String> processedBeans = new HashSet<>();

        // 判斷beanfactory是否是BeanDefinitionRegistry類型刨晴,此處是DefaultListableBeanFactory,實(shí)現(xiàn)了BeanDefinitionRegistry接口屉来,所以為true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // 類型轉(zhuǎn)換
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 此處希望大家做一個(gè)區(qū)分,兩個(gè)接口是不同的割捅,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子集
            // BeanFactoryPostProcessor主要針對(duì)的操作對(duì)象是BeanFactory奶躯,而BeanDefinitionRegistryPostProcessor主要針對(duì)的操作對(duì)象是BeanDefinition
            // 存放BeanFactoryPostProcessor的集合
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 存放BeanDefinitionRegistryPostProcessor的集合
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 首先處理入?yún)⒅械腷eanFactoryPostProcessors,遍歷所有的beanFactoryPostProcessors,將BeanDefinitionRegistryPostProcessor
            // 和BeanFactoryPostProcessor區(qū)分開
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果是BeanDefinitionRegistryPostProcessor
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 直接執(zhí)行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    // 添加到registryProcessors亿驾,用于后續(xù)執(zhí)行postProcessBeanFactory方法
                    registryProcessors.add(registryProcessor);
                } else {
                    // 否則嘹黔,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后續(xù)執(zhí)行postProcessBeanFactory方法
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            // 用于保存本次要執(zhí)行的BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 調(diào)用所有實(shí)現(xiàn)PriorityOrdered接口的BeanDefinitionRegistryPostProcessor實(shí)現(xiàn)類
            // 找到所有實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 遍歷處理所有符合規(guī)則的postProcessorNames
            for (String ppName : postProcessorNames) {
                // 檢測(cè)是否實(shí)現(xiàn)了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 獲取名字對(duì)應(yīng)的bean實(shí)例儡蔓,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 將要被執(zhí)行的BFPP名稱添加到processedBeans郭蕉,避免后續(xù)重復(fù)執(zhí)行
                    processedBeans.add(ppName);
                }
            }
            // 按照優(yōu)先級(jí)進(jìn)行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后執(zhí)行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍歷currentRegistryProcessors喂江,執(zhí)行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 執(zhí)行完畢之后召锈,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 調(diào)用所有實(shí)現(xiàn)Ordered接口的BeanDefinitionRegistryPostProcessor實(shí)現(xiàn)類
            // 找到所有實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口bean的beanName,
            // 此處需要重復(fù)查找的原因在于上面的執(zhí)行過程中可能會(huì)新增其他的BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 檢測(cè)是否實(shí)現(xiàn)了Ordered接口获询,并且還未執(zhí)行過
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 獲取名字對(duì)應(yīng)的bean實(shí)例涨岁,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 將要被執(zhí)行的BFPP名稱添加到processedBeans,避免后續(xù)重復(fù)執(zhí)行
                    processedBeans.add(ppName);
                }
            }
            // 按照優(yōu)先級(jí)進(jìn)行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中吉嚣,用于最后執(zhí)行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍歷currentRegistryProcessors梢薪,執(zhí)行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 執(zhí)行完畢之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后尝哆,調(diào)用所有剩下的BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 找出所有實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口的類
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                // 遍歷執(zhí)行
                for (String ppName : postProcessorNames) {
                    // 跳過已經(jīng)執(zhí)行過的BeanDefinitionRegistryPostProcessor
                    if (!processedBeans.contains(ppName)) {
                        // 獲取名字對(duì)應(yīng)的bean實(shí)例秉撇,添加到currentRegistryProcessors中
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        // 將要被執(zhí)行的BFPP名稱添加到processedBeans,避免后續(xù)重復(fù)執(zhí)行
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                // 按照優(yōu)先級(jí)進(jìn)行排序操作
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 添加到registryProcessors中秋泄,用于最后執(zhí)行postProcessBeanFactory方法
                registryProcessors.addAll(currentRegistryProcessors);
                // 遍歷currentRegistryProcessors琐馆,執(zhí)行postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 執(zhí)行完畢之后,清空currentRegistryProcessors
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 調(diào)用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 最后恒序,調(diào)用入?yún)eanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            // 如果beanFactory不歸屬于BeanDefinitionRegistry類型瘦麸,那么直接執(zhí)行postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 到這里為止,入?yún)eanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已經(jīng)全部處理完畢奸焙,下面開始處理容器中
        // 所有的BeanFactoryPostProcessor
        // 可能會(huì)包含一些實(shí)現(xiàn)類瞎暑,只實(shí)現(xiàn)了BeanFactoryPostProcessor,并沒有實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // 找到所有實(shí)現(xiàn)BeanFactoryPostProcessor接口的類
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 用于存放實(shí)現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor的beanName
//      List<String> orderedPostProcessorNames = new ArrayList<>();
        List<BeanFactoryPostProcessor> orderedPostProcessor = new ArrayList<>();
        // 用于存放普通BeanFactoryPostProcessor的beanName
//      List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        List<BeanFactoryPostProcessor> nonOrderedPostProcessorNames = new ArrayList<>();
        // 遍歷postProcessorNames,將BeanFactoryPostProcessor按實(shí)現(xiàn)PriorityOrdered与帆、實(shí)現(xiàn)Ordered接口了赌、普通三種區(qū)分開
        for (String ppName : postProcessorNames) {
            // 跳過已經(jīng)執(zhí)行過的BeanFactoryPostProcessor
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 添加實(shí)現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 添加實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNames
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//              orderedPostProcessorNames.add(ppName);
                orderedPostProcessor.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            } else {
                // 添加剩下的普通BeanFactoryPostProcessor的beanName到nonOrderedPostProcessorNames
//              nonOrderedPostProcessorNames.add(ppName);
                nonOrderedPostProcessorNames.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // 對(duì)實(shí)現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor進(jìn)行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 遍歷實(shí)現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor,執(zhí)行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 創(chuàng)建存放實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor集合
//      List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        // 遍歷存放實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor名字的集合
//      for (String postProcessorName : orderedPostProcessorNames) {
        // 將實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor添加到集合中
//          orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//      }
        // 對(duì)實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor進(jìn)行排序操作
//      sortPostProcessors(orderedPostProcessors, beanFactory);
        sortPostProcessors(orderedPostProcessor, beanFactory);
        // 遍歷實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor玄糟,執(zhí)行postProcessBeanFactory方法
//      invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessor, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // 最后勿她,創(chuàng)建存放普通的BeanFactoryPostProcessor的集合
//      List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        // 遍歷存放實(shí)現(xiàn)了普通BeanFactoryPostProcessor名字的集合
//      for (String postProcessorName : nonOrderedPostProcessorNames) {
        // 將普通的BeanFactoryPostProcessor添加到集合中
//          nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//      }
        // 遍歷普通的BeanFactoryPostProcessor,執(zhí)行postProcessBeanFactory方法
//      invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessorNames, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        // 清除元數(shù)據(jù)緩存(mergeBeanDefinitions阵翎、allBeanNamesByType逢并、singletonBeanNameByType)
        // 因?yàn)楹笾锰幚砥骺赡芤呀?jīng)修改了原始元數(shù)據(jù),例如郭卫,替換值中的占位符
        beanFactory.clearMetadataCache();
    }

我們可以看到 在 BFPP的執(zhí)行過程是先執(zhí)行外部傳入的beanFactoryPostProcessors集合砍聊,然后再執(zhí)行BeanDefinition中包含的BeanFactoryPostProcessor.在執(zhí)行所有BFPP時(shí),會(huì)將BFPP的BeanDefinition提前進(jìn)行實(shí)例化初始化贰军,獲取到Bean的實(shí)例來(lái)進(jìn)行方法調(diào)用玻蝌。在代碼中可以看到顯式調(diào)用了getBean()方法。
getBean()方法也是Spring框架的一個(gè)核心方法,調(diào)用執(zhí)行大概過程:getBean()->doGetBean()->createBean()->doCreateBean() ,普通Bean的創(chuàng)建都遵循這個(gè)方法調(diào)用的流程
1.處理外部傳入的beanFactoryPostProcessors集合
BeanFactoryPostProcessor 是 BeanDefinitionRegistryPostProcessor的父類
(1)BeanDefinitionRegistryPostProcessor類型俯树,則先執(zhí)行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法帘腹,執(zhí)行完后放入到registryPostProcessor集合中
(2)BeanFactoryPostProcessor類型,放入到regularpostProcessor集合中
2.處理BeanFactory中類型為BeanDefinitionRegistry的BeanDefinition
(1)BeanDefinitionRegistryPostProcessor類型许饿,則放入到currentRegistryProcessors中阳欲,排序后全部添加到registryPostProcessor集合中,執(zhí)行currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法陋率,然后清空currentRegistryProcessors集合
(2)重新獲取一次(因?yàn)榭赡苡行略龅腂eanDefinitionRegistryPostProcessor,比如在調(diào)用postProcessBeanDefinitionRegistry方法中新增了BeanDefinitionRegistryPostProcessor)球化,調(diào)用getBean()方法獲取初始化后的Bean實(shí)例,最終調(diào)用postProcessBeanDefinitionRegistry來(lái)執(zhí)行所有的BeanDefinitionRegistryPostProcessors翘贮,
然后執(zhí)行完成后添加到regularpostProcessor集合中赊窥,然后統(tǒng)一執(zhí)行父類方法invokeBeanFactoryPostProcessors,然后添加到processedBeans集合中狸页,此集合用于記錄執(zhí)行過的BeanFactoryPostProcessor
3.處理BeanFactory中類型為BeanFactoryPostProcessor 的BeanDefinition,調(diào)用getBean()方法獲取初始化后的Bean實(shí)例,然后根據(jù)Order的優(yōu)先級(jí)先后調(diào)用postProcessBeanFactory扯再;

下一篇文章將會(huì)詳細(xì)講解ConfigurationClassPostProcessor的內(nèi)部執(zhí)行流程芍耘,是怎樣進(jìn)行注解解析的?

第一次寫源碼解析的文章熄阻,希望大家多多指點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斋竞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子秃殉,更是在濱河造成了極大的恐慌坝初,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钾军,死亡現(xiàn)場(chǎng)離奇詭異鳄袍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吏恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門拗小,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人樱哼,你說(shuō)我怎么就攤上這事哀九。” “怎么了搅幅?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵阅束,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我茄唐,道長(zhǎng)息裸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮界牡,結(jié)果婚禮上簿寂,老公的妹妹穿的比我還像新娘。我一直安慰自己宿亡,他們只是感情好常遂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挽荠,像睡著了一般克胳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上圈匆,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天漠另,我揣著相機(jī)與錄音,去河邊找鬼跃赚。 笑死笆搓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纬傲。 我是一名探鬼主播满败,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叹括!你這毒婦竟也來(lái)了算墨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤汁雷,失蹤者是張志新(化名)和其女友劉穎净嘀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侠讯,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挖藏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了继低。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熬苍。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖袁翁,靈堂內(nèi)的尸體忽然破棺而出柴底,到底是詐尸還是另有隱情,我是刑警寧澤粱胜,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布柄驻,位于F島的核電站,受9級(jí)特大地震影響焙压,放射性物質(zhì)發(fā)生泄漏鸿脓。R本人自食惡果不足惜抑钟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望野哭。 院中可真熱鬧在塔,春花似錦、人聲如沸拨黔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)篱蝇。三九已至贺待,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間零截,已是汗流浹背麸塞。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涧衙,地道東北人哪工。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像弧哎,于是被迫代替她去往敵國(guó)和親正勒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容