美文网首页SpringJava技术升华
Spring 注解配置加载流程源码解析(一)

Spring 注解配置加载流程源码解析(一)

作者: 一个头发茂密的程序员 | 来源:发表于2021-09-02 14:34 被阅读0次

1.说明

其实spring对于xml解析与注解解析大体流程是一样的,不过注解解析是利用BeanFactoryPostProcessor的后置处理器子类ConfigurationClassPostProcessor来进行扫描的

2.上代码:测试类

包的层级关系


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. 两种容器加载的区别
  //注解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  创建DefaultListableBeanFactory 工厂对象
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,并进行XML文件读取,并将得到的BeanFactory记录在当前实体的属性中
        refreshBeanFactory();
        // 返回当前实体的beanFactory属性
        return getBeanFactory();
    }

@Override
    protected final void refreshBeanFactory() throws BeansException {
        // 如果存在beanFactory,则销毁beanFactory
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 创建DefaultListableBeanFactory对象
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 为了序列化指定id,可以从id反序列化到beanFactory对象
            beanFactory.setSerializationId(getId());
            // 定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
            customizeBeanFactory(beanFactory);
            // 初始化documentReader,并进行XML文件读取及解析,默认命名空间的解析,自定义标签的解析
            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 ,在实例化AnnotationConfigApplicationContext 时候,先要执行父类GenericApplicationContext 的构造方法,此时提前创建好了一个DefaultListableBeanFactory 工厂对象
  2. ClassPathXmlApplicationContext
    继承于AbstractApplicationContext,在创建DefaultListableBeanFactory 工厂对象时,是在refresh()方法中的obtainFreshBeanFactory方法中

综上所述,xml 文件的方式和纯注解的方式 在 容器刷新前的工作并不相同,但整体的处理流程是大体一致的。ClassPathXmlApplicationContext 是在内部构造函数中调用refresh()来进行容器的刷新,最开始的容器中是不存在bean工厂的,AnnotationConfigApplicationContext 在调用refresh()方法前已经将默认的bean工厂创建完成,其次还注册了一系列的BeanFactoryPostProcessor,BeanPostProccessor后置处理器以及监听器等等

我们看实例化后的AnnotationConfigApplicationContext


image.png

我们可以看到,构造过程中提前将5个BeanDefinition对象提前放到了BeanDefinitionMap中;先大概了解一下每个BeanDefinition在之后的作用
BeanFactoryPostProcessor
1)internalConfigurationAnnotationProcessor 对应的类是 ConfigurationClassPostProcessor
用来对 @Component @ComponentScan @Configuration @Service @Controller @PropertySource @Import @ImportResource @Bean 进行注解扫描
BeanPostProcessor
2)internalAutowiredAnnotationProcessor 对应的类是 AutowiredAnnotationBeanPostProcessor
扫描@Autowired 注解,@Value注解,进行属性填充
internalCommonAnnotationProcessor 对应的类是 CommonAnnotationBeanPostProcessor
扫描@Resource注解,@PreDestory,@PostConstruct注解,进行属性填充

  • 两个BeanPostProcessor 进行注解扫描时,都是在实例化过后填充属性之前进行扫描,获取对应注解的元数据,通过调用postProcessMergedBeanDefinition 方法。在填充属性的时候调用postProcessProperties 来进行属性填充

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) {
        // 从缓存中取出这个bean对应的依赖注入的元信息~
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            // 进行属性注入
            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标记的字段和方法封装到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.

上边已经完成了AnnotationConfigApplicationContext 对象的创建,容器中目前已经初始化好了需要的一些环境变量,Bean工厂,以及Bean工厂一些内置的BeanDefinition(主要是BeanPostProcessor,BeanFactoryProcessor)和其他属性,然后我们在看register方法做了什么事情

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方法

第一步:先创建了一个AnnotatedGenericBeanDefinition 对象
第二步:解析@scope注解
第三步:解析 @Lazy @Role @DependOn @Primary 注解
第四步:判断是否需要被代理
第五步://注册BeanDefinition,将BeanDefinition 放到BeanFactory中

    public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
        setBeanClass(beanClass);
               //封装配置类上的注解元数据信息
        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) {

        //创建AnnotatedGenericBeanDefinition 对象,获取配置类上的注解元数据信息
        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);
        //注册BeanDefinition,将BeanDefinition 放到BeanFactory中
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

此时的SpringConfig 的 BeanDefinition 已经成功注册到DefaultListableBeanFactory中了。这样我们其实是在逻辑上已经可以梳理通了,在调用register方法之后,容器会提前将配置类添加到BeanFactory的BeanDefinitionMap中,后续在调用refresh()方法的

image.png

4、重中之中:单独看ConfigurationClassPostProcessor BFPP怎样进行注解的解析工作的

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

  1. 为什么说XML文件 和注解 两种方式大体流程是一致的,主要原因就是因为bean的创建流程都是调用了AbstractFactory中的refresh方法,refresh方法中包含了整个Bean的生命周期。从Bean实例化到初始化的整个过程
@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            /**
             * 前戏,做容器刷新前的准备工作
             * 1、设置容器的启动时间
             * 2、设置活跃状态为true
             * 3、设置关闭状态为false
             * 4、获取Environment对象,并加载当前系统的属性值到Environment对象中
             * 5、准备监听器和事件的集合对象,默认为空的集合
             */

            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 创建容器对象:DefaultListableBeanFactory
            // 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinition
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // beanFactory的准备工作,对各种属性进行填充
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // 子类覆盖方法做额外的处理,此处我们自己一般不做任何扩展工作,但是可以查看web中的代码,是有具体实现的
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // 调用各种beanFactory处理器
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 注册bean处理器,这里只是注册功能,真正调用的是getBean方法
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 为上下文初始化message源,即不同语言的消息体,国际化处理,在springmvc的时候通过国际化的代码重点讲
                initMessageSource();

                // Initialize event multicaster for this context.
                // 初始化事件监听多路广播器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 留给子类来初始化其他的bean
                onRefresh();

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

                // Instantiate all remaining (non-lazy-init) singletons.
                // 初始化剩下的单实例(非懒加载的)
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
                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资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
                destroyBeans();

                // Reset 'active' flag.
                // 重置active标志
                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();
            }
        }
    }

先关注一下当前的BeanFactory中包含的BeanDefinition都有哪些?

image.png

4.1然后我们直接看BeanFactoryPostProcessor的执行流程

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值,并且实例化调用执行所有已经注册的beanFactoryPostProcessor
        // 默认情况下,通过getBeanFactoryPostProcessors()来获取已经注册的BFPP,但是默认是空的,那么问题来了,如果你想扩展,怎么进行扩展工作?
        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.
        // 无论是什么情况,优先执行BeanDefinitionRegistryPostProcessors
        // 将已经执行过的BFPP存储在processedBeans中,防止重复执行
        Set<String> processedBeans = new HashSet<>();

        // 判断beanfactory是否是BeanDefinitionRegistry类型,此处是DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,所以为true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // 类型转换
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 此处希望大家做一个区分,两个接口是不同的,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子集
            // BeanFactoryPostProcessor主要针对的操作对象是BeanFactory,而BeanDefinitionRegistryPostProcessor主要针对的操作对象是BeanDefinition
            // 存放BeanFactoryPostProcessor的集合
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 存放BeanDefinitionRegistryPostProcessor的集合
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 首先处理入参中的beanFactoryPostProcessors,遍历所有的beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor
            // 和BeanFactoryPostProcessor区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果是BeanDefinitionRegistryPostProcessor
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 直接执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    // 添加到registryProcessors,用于后续执行postProcessBeanFactory方法
                    registryProcessors.add(registryProcessor);
                } else {
                    // 否则,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后续执行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.
            // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
            // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 遍历处理所有符合规则的postProcessorNames
            for (String ppName : postProcessorNames) {
                // 检测是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 调用所有实现Ordered接口的BeanDefinitionRegistryPostProcessor实现类
            // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,
            // 此处需要重复查找的原因在于上面的执行过程中可能会新增其他的BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 检测是否实现了Ordered接口,并且还未执行过
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后,调用所有剩下的BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                // 遍历执行
                for (String ppName : postProcessorNames) {
                    // 跳过已经执行过的BeanDefinitionRegistryPostProcessor
                    if (!processedBeans.contains(ppName)) {
                        // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                // 按照优先级进行排序操作
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
                registryProcessors.addAll(currentRegistryProcessors);
                // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 执行完毕之后,清空currentRegistryProcessors
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 最后,调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            // 如果beanFactory不归属于BeanDefinitionRegistry类型,那么直接执行postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 到这里为止,入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,下面开始处理容器中
        // 所有的BeanFactoryPostProcessor
        // 可能会包含一些实现类,只实现了BeanFactoryPostProcessor,并没有实现BeanDefinitionRegistryPostProcessor接口

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

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了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按实现PriorityOrdered、实现Ordered接口、普通三种区分开
        for (String ppName : postProcessorNames) {
            // 跳过已经执行过的BeanFactoryPostProcessor
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 添加实现了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.
        // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 创建存放实现了Ordered接口的BeanFactoryPostProcessor集合
//      List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        // 遍历存放实现了Ordered接口的BeanFactoryPostProcessor名字的集合
//      for (String postProcessorName : orderedPostProcessorNames) {
        // 将实现了Ordered接口的BeanFactoryPostProcessor添加到集合中
//          orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//      }
        // 对实现了Ordered接口的BeanFactoryPostProcessor进行排序操作
//      sortPostProcessors(orderedPostProcessors, beanFactory);
        sortPostProcessors(orderedPostProcessor, beanFactory);
        // 遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//      invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessor, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // 最后,创建存放普通的BeanFactoryPostProcessor的集合
//      List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        // 遍历存放实现了普通BeanFactoryPostProcessor名字的集合
//      for (String postProcessorName : nonOrderedPostProcessorNames) {
        // 将普通的BeanFactoryPostProcessor添加到集合中
//          nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//      }
        // 遍历普通的BeanFactoryPostProcessor,执行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...
        // 清除元数据缓存(mergeBeanDefinitions、allBeanNamesByType、singletonBeanNameByType)
        // 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符
        beanFactory.clearMetadataCache();
    }

我们可以看到 在 BFPP的执行过程是先执行外部传入的beanFactoryPostProcessors集合,然后再执行BeanDefinition中包含的BeanFactoryPostProcessor.在执行所有BFPP时,会将BFPP的BeanDefinition提前进行实例化初始化,获取到Bean的实例来进行方法调用。在代码中可以看到显式调用了getBean()方法。
getBean()方法也是Spring框架的一个核心方法,调用执行大概过程:getBean()->doGetBean()->createBean()->doCreateBean() ,普通Bean的创建都遵循这个方法调用的流程
1.处理外部传入的beanFactoryPostProcessors集合
BeanFactoryPostProcessor 是 BeanDefinitionRegistryPostProcessor的父类
(1)BeanDefinitionRegistryPostProcessor类型,则先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,执行完后放入到registryPostProcessor集合中
(2)BeanFactoryPostProcessor类型,放入到regularpostProcessor集合中
2.处理BeanFactory中类型为BeanDefinitionRegistry的BeanDefinition
(1)BeanDefinitionRegistryPostProcessor类型,则放入到currentRegistryProcessors中,排序后全部添加到registryPostProcessor集合中,执行currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,然后清空currentRegistryProcessors集合
(2)重新获取一次(因为可能有新增的BeanDefinitionRegistryPostProcessor,比如在调用postProcessBeanDefinitionRegistry方法中新增了BeanDefinitionRegistryPostProcessor),调用getBean()方法获取初始化后的Bean实例,最终调用postProcessBeanDefinitionRegistry来执行所有的BeanDefinitionRegistryPostProcessors,
然后执行完成后添加到regularpostProcessor集合中,然后统一执行父类方法invokeBeanFactoryPostProcessors,然后添加到processedBeans集合中,此集合用于记录执行过的BeanFactoryPostProcessor
3.处理BeanFactory中类型为BeanFactoryPostProcessor 的BeanDefinition,调用getBean()方法获取初始化后的Bean实例,然后根据Order的优先级先后调用postProcessBeanFactory;

下一篇文章将会详细讲解ConfigurationClassPostProcessor的内部执行流程,是怎样进行注解解析的?

第一次写源码解析的文章,希望大家多多指点

相关文章

网友评论

    本文标题:Spring 注解配置加载流程源码解析(一)

    本文链接:https://www.haomeiwen.com/subject/ypnxwltx.html