欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors

程序员文章站 2023-11-23 00:02:10
Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors。`getBeanFactoryPostProcessors()`方法获取的是`AbstractApplicationContext#beanFactoryPostProcessors`这个成... ......

invokebeanfactorypostprocessors(beanfactory);方法源码如下:

protected void invokebeanfactorypostprocessors(configurablelistablebeanfactory beanfactory) {
    // getbeanfactorypostprocessors 获取的是 this.beanfactorypostprocessors;
    //this.beanfactorypostprocessors 只能通过 abstractapplicationcontext.addbeanfactorypostprocessor 方法添加
    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()));
    }
}

getbeanfactorypostprocessors()方法获取的是abstractapplicationcontext#beanfactorypostprocessors这个成员变量。

这个成员变量只能通过代码中手动编码调用abstractapplicationcontext#addbeanfactorypostprocessor方法来添加新的元素。很明显,我们这里为空。

invokebeanfactorypostprocessors(beanfactory)方法的主要的逻辑在postprocessorregistrationdelegate.invokebeanfactorypostprocessors方法中:

//postprocessorregistrationdelegate.invokebeanfactorypostprocessors(beanfactory, getbeanfactorypostprocessors())源码
public static void invokebeanfactorypostprocessors(
        configurablelistablebeanfactory beanfactory, list<beanfactorypostprocessor> beanfactorypostprocessors) {

    // invoke beandefinitionregistrypostprocessors first, if any.
    set<string> processedbeans = new hashset<>();

    if (beanfactory instanceof beandefinitionregistry) {
        beandefinitionregistry registry = (beandefinitionregistry) beanfactory;
        list<beanfactorypostprocessor> regularpostprocessors = new arraylist<>();
        list<beandefinitionregistrypostprocessor> registryprocessors = new arraylist<>();

        //beanfactorypostprocessors是传进来里的对象,把传入的对象分类放入 beanfactorypostprocessor 和  beandefinitionregistrypostprocessor
        //beandefinitionregistrypostprocessor extends beanfactorypostprocessor ,是一个特殊的 beanfactorypostprocessor
        for (beanfactorypostprocessor postprocessor : beanfactorypostprocessors) {
            if (postprocessor instanceof beandefinitionregistrypostprocessor) {
                beandefinitionregistrypostprocessor registryprocessor =
                        (beandefinitionregistrypostprocessor) postprocessor;
                //如果传入的beanfactorypostprocessors是它的子类,即:beandefinitionregistrypostprocessor
                //则执行传入的beandefinitionregistrypostprocessor的postprocessbeandefinitionregistry方法
                registryprocessor.postprocessbeandefinitionregistry(registry);
                registryprocessors.add(registryprocessor);
            } else {
                regularpostprocessors.add(postprocessor);
            }
        }

        // do noitialize 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.
        list<beandefinitionregistrypostprocessor> currentregistryprocessors = new arraylist<>();

        // first, invoke the beandefinitionregistrypostprocessors that implement priorityordered.

        //这里只能拿到spring内部的beandefinitionregistrypostprocessor,
        //因为到这里spring还没有去扫描bean,获取不到我们通过@component标识的自定义beandefinitionregistrypostprocessor
        //一般默认情况下,这里只有一个,beanname:org.springframework.context.annotation.internalconfigurationannotationprocessor
        //对应的beanclass:configurationclasspostprocessor
        string[] postprocessornames =
                beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false);
        for (string ppname : postprocessornames) {
            if (beanfactory.istypematch(ppname, priorityordered.class)) {
                //beanfactory.getbean, 这里开始创建beandefinitionregistrypostprocessor bean 了
                currentregistryprocessors.add(beanfactory.getbean(ppname, beandefinitionregistrypostprocessor.class));
                processedbeans.add(ppname);
            }
        }

        //排序
        sortpostprocessors(currentregistryprocessors, beanfactory);

        // registryprocessors 中放的是 beandefinitionregistrypostprocessor
        // 因为这里只执行eandefinitionregistrypostprocessor中独有的方法,而不会执行其父类即beanfactoryprocessor的方法
        // 所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
        registryprocessors.addall(currentregistryprocessors);

        // 执行beandefinitionregistrypostprocessor,currentregistryprocessors中放的是spring内部的beandefinitionregistrypostprocessor
        // 默认情况下,只有 org.springframework.context.annotation.configurationclasspostprocessor
        // configurationclasspostprocessor 里面就是在执行扫描bean,并且注册beandefinition
        invokebeandefinitionregistrypostprocessors(currentregistryprocessors, registry);

        // 清空这个临时变量,方便后面再使用
        currentregistryprocessors.clear();

        // next, invoke the beandefinitionregistrypostprocessors that implement ordered.
        // 这里已经可以获取到我们通过注册到spring容器的 beandefinitionregistrypostprocessor 了
        postprocessornames = beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false);
        for (string ppname : postprocessornames) {
            // 之前优先处理的是实现priorityordered接口的,而priorityordered接口也实现了ordered接口
            // 所有这里需要把之前已经处理过的给过滤掉
            if (!processedbeans.contains(ppname) && beanfactory.istypematch(ppname, ordered.class)) {
                //之前这个临时变量已经被清空了,现在又开始放东西了
                currentregistryprocessors.add(beanfactory.getbean(ppname, beandefinitionregistrypostprocessor.class));
                processedbeans.add(ppname);
            }
        }

        //排序
        sortpostprocessors(currentregistryprocessors, beanfactory);

        registryprocessors.addall(currentregistryprocessors);

        // 执行beandefinitionregistrypostprocessor
        invokebeandefinitionregistrypostprocessors(currentregistryprocessors, registry);

        //清空临时变量
        currentregistryprocessors.clear();

        // finally, invoke all other beandefinitionregistrypostprocessors until no further ones appear.
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postprocessornames = beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false);
            for (string ppname : postprocessornames) {
                //执行没有实现ordered接口的beandefinitionregistrypostprocessor
                if (!processedbeans.contains(ppname)) {
                    currentregistryprocessors.add(beanfactory.getbean(ppname, beandefinitionregistrypostprocessor.class));
                    processedbeans.add(ppname);
                    reiterate = true;
                }
            }
            sortpostprocessors(currentregistryprocessors, beanfactory);
            registryprocessors.addall(currentregistryprocessors);
            invokebeandefinitionregistrypostprocessors(currentregistryprocessors, registry);
            currentregistryprocessors.clear();
        }

        // now, invoke the postprocessbeanfactory callback of all processors handled so far.
        // list<beandefinitionregistrypostprocessor> registryprocessors
        // 之前已经执行过beandefinitionregistrypostprocessor独有方法,现在执行其父类方法
        invokebeanfactorypostprocessors(registryprocessors, beanfactory);

        // list<beanfactorypostprocessor> regularpostprocessors
        // 执行 beanfactorypostprocessor 方法
        invokebeanfactorypostprocessors(regularpostprocessors, beanfactory);
    } else {
        // invoke factory processors registered with the context instance.
        invokebeanfactorypostprocessors(beanfactorypostprocessors, beanfactory);
    }

    // do not initialize factorybeans here: we need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    // 获取 beanfactorypostprocessor 的 beanname
    string[] postprocessornames =
            beanfactory.getbeannamesfortype(beanfactorypostprocessor.class, true, false);

    // separate between beanfactorypostprocessors that implement priorityordered,
    // ordered, and the rest.
    list<beanfactorypostprocessor> priorityorderedpostprocessors = new arraylist<>();
    list<string> orderedpostprocessornames = new arraylist<>();
    list<string> nonorderedpostprocessornames = new arraylist<>();
    for (string ppname : postprocessornames) {
        // 如果已经被执行过了,就不在执行
        // 因为一开始先获取的beandefinitionregistrypostprocessor,而beandefinitionregistrypostprocessor继承了beanfactorypostprocessor
        if (processedbeans.contains(ppname)) {
            // skip - already processed in first phase above
        } else if (beanfactory.istypematch(ppname, priorityordered.class)) {
            priorityorderedpostprocessors.add(beanfactory.getbean(ppname, beanfactorypostprocessor.class));
        } else if (beanfactory.istypematch(ppname, ordered.class)) {
            orderedpostprocessornames.add(ppname);
        } else {
            nonorderedpostprocessornames.add(ppname);
        }
    }

    // first, invoke the beanfactorypostprocessors that implement priorityordered.
    // 根据不同的优先级,按序执行 beanfactorypostprocessor
    sortpostprocessors(priorityorderedpostprocessors, beanfactory);
    invokebeanfactorypostprocessors(priorityorderedpostprocessors, beanfactory);

    // next, invoke the beanfactorypostprocessors that implement ordered.
    list<beanfactorypostprocessor> orderedpostprocessors = new arraylist<>();
    for (string postprocessorname : orderedpostprocessornames) {
        orderedpostprocessors.add(beanfactory.getbean(postprocessorname, beanfactorypostprocessor.class));
    }
    sortpostprocessors(orderedpostprocessors, beanfactory);
    invokebeanfactorypostprocessors(orderedpostprocessors, beanfactory);

    // finally, invoke all other beanfactorypostprocessors.
    list<beanfactorypostprocessor> nonorderedpostprocessors = new arraylist<>();
    for (string postprocessorname : nonorderedpostprocessornames) {
        nonorderedpostprocessors.add(beanfactory.getbean(postprocessorname, beanfactorypostprocessor.class));
    }
    invokebeanfactorypostprocessors(nonorderedpostprocessors, beanfactory);

    // clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanfactory.clearmetadatacache();
}

源码超级长,我们慢慢来看。

  1. spring容器使用的beanfactorydefaultlistablebeanfactory,它实现了beandefinitionregistry接口,if条件成立。

  2. 优先处理程序传进来的beanfactorypostprocessors,也就是我们手动调用abstractapplicationcontext#addbeanfactorypostprocessor方法来添加的beanfactorypostprocessor

  3. beanfactorypostprocessor是一个*接口,他还有一个子类beandefinitionregistrypostprocessor。在该方法中声明了两个list来存放beanfactorypostprocessorbeandefinitionregistrypostprocessor,以便控制这两个接口方法的执行。

  4. 遍历传入的list<beanfactorypostprocessor> beanfactorypostprocessors,将其分类放到两个list中。如果传入的是beandefinitionregistrypostprocessor类,则先执行beandefinitionregistrypostprocessor类中独有的方法postprocessbeandefinitionregistry方法。当然,我们这里传入的list<beanfactorypostprocessor> beanfactorypostprocessors为空。

  5. 第一次执行beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false);方法,从容器中获取beandefinitionregistrypostprocessor类型的bean的name(这里只是获取名称,还没有实例化bean)。注意,程序执行到这里,spring还没有扫描包,还没有将项目中的bean注册到容器中。默认情况下,这里返回的数据为如下图所示。回忆一下,这个beandefinition是在什么时候被加入到beanfactory的呢?是在annotationconfigapplicationcontext的无参构造器中创建reader时注册的beandefinition。其中beanname为org.springframework.context.annotation.internalconfigurationannotationprocessor,对应的class为org.springframework.context.annotation.configurationclasspostprocessorSpring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors

  6. 遍历这个获取的postprocessornames,如果实现了priorityordered接口,就调用beanfactory.getbean(ppname, beandefinitionregistrypostprocessor.class)方法,从容器中获取这个bean,将其加入到临时变量list<beandefinitionregistrypostprocessor> currentregistryprocessors中。

  7. currentregistryprocessors中的元素进行排序,然后执行beandefinitionregistrypostprocessor中的特有方法postprocessbeandefinitionregistry。注意哦,这里没有执行其父类的方法,而是又将其放到list<beandefinitionregistrypostprocessor> registryprocessors中,到后面再执行其父类方法。

  8. 默认情况下,此时currentregistryprocessors中只有一个bean即:org.springframework.context.annotation.configurationclasspostprocessor(它实现了priorityordered接口)。configurationclasspostprocessor是一个非常重要的类,我们后面在讲。当程序执行完configurationclasspostprocessorbeandefinitionregistrypostprocessor方法后,我们程序中的bean就被注册到了spring容器中了,需要注意的是,这里还只是注册了beandefinition,还没有创建bean对象。Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors

    Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors

  9. 当第二次执行postprocessornames = beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false);方法,此时因为之前已经完成了bean的扫描,所以如果我们有自定义的beandefinitionregistrypostprocessor就可以在这里被获取了。获取之前,判断其是否实现ordered接口,并且之前没有被执行过,则调用getbean方法,从容器中获取该bean,然后进行排序,执行postprocessbeandefinitionregistry方法。

  10. 前面已经按顺序执行了实现priorityorderedordered接口的beandefinitionregistrypostprocessor,最后,执行没有实现ordered接口的beandefinitionregistrypostprocessorpostprocessbeandefinitionregistry方法。执行完之后再beandefinitionregistrypostprocessor的父类方法postprocessbeanfactory

  11. 获取容器中还没有被执行过的实现beanfactorypostprocessor接口的bean,然后按顺序执行的postprocessbeanfactory。默认情况下,这里会获取到:

Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors

由于bean org.springframework.context.annotation.internalconfigurationannotationprocessor(对应的class为org.springframework.context.annotation.configurationclasspostprocessor)在之前已经被执行了,这里只会执行bean org.springframework.context.event.internaleventlistenerprocessor(对应的class为org.springframework.context.event.eventlistenermethodprocessor)的postprocessbeanfactory方法,源码如下:

//org.springframework.context.event.eventlistenermethodprocessor#postprocessbeanfactory 源码
@override
public void postprocessbeanfactory(configurablelistablebeanfactory beanfactory) {
    this.beanfactory = beanfactory;

    map<string, eventlistenerfactory> beans = beanfactory.getbeansoftype(eventlistenerfactory.class, false, false);
    list<eventlistenerfactory> factories = new arraylist<>(beans.values());
    annotationawareordercomparator.sort(factories);
    this.eventlistenerfactories = factories;
}

未完待续......

源码学习笔记:https://github.com/shenjianeng/spring-code-study

欢迎关注公众号:

Spring5源码解析4-refresh方法之invokeBeanFactoryPostProcessors