Spring源码阅读 - 基础流程

1. AnnotationConfigApplicationContext 的 reader 和 scanner

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    // 注册解析这个 Bean 为 BeanDefinition
    register(componentClasses);
    // 刷新容器,这个时候才是对这个 BeanDefinition 进行进一步解析
    refresh();
}
public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

内部逻辑先暂略,简略描述

/**
 * 注解 Class 读取器/处理器,在构造函数中创建
 * AnnotatedBeanDefinitionReader 被实例化时已经向容器注入了部分 BeanDefinition
 * 区分 BeanPostProcessor 和 BeanFactoryPostProcessor
 *
 * 从其提供的 API 来看,大致就是将一个 Class 解析为 BeanDefinition 放入 BeanFactory
 */
private final AnnotatedBeanDefinitionReader reader;

/**
 * 类路径扫描器,可以进行包扫描,然后呢?
 * 这个在实例化时就没有创建预先注入 BeanDefinition 了
 */
private final ClassPathBeanDefinitionScanner scanner;

2. register

利用 reader 解析传入的 Class 并进行基础的解析转换为 BeanDefinition 并将这个 BeanDefinition 注入 BeanFactory
org.springframework.context.annotation.AnnotationConfigApplicationContext#register

public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    // 使用注解BD读取器去注册/处理这个 Bean
    this.reader.register(componentClasses);
}

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#register

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

public void registerBean(Class<?> beanClass) {
    doRegisterBean(beanClass, null, null, null, null);
}

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

    // Generic [dʒəˈnerɪk],通用的,adj. (药物或商品)无专利的,未注册的
    // 这个应该是用于封装一个(可能)使用了注解的Bean,内部会进行解析注解信息并封装
    // 封装为 BeanDefinition
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    // 这个应该是涉及到条件注入等的
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

    // 下面解析注解并设置 BeanDefinition,从上面的 new AnnotatedGenericBeanDefinition 可以看到只是将解析的注解封装为一个属性,具体
    //    如何处理这些注解并设置 BeanDefinition 则由后面的进行解析

    // 这个是不由 Spring 实例化,表示由这个 supplier 进行实例化,在哪里有使用呢?
    abd.setInstanceSupplier(supplier);
    // 解析 Bean 的生命周期 Scope,这里解析器也有几种,Spring 自己的注解 @Scope 解析,javax.inject.Scope 的解析,略后者
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    // beanName 生成,如何自定义 BeanName 生成器?
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    // 通用注解解析,那么区分需要外部处理的和需要工具类处理的标准/条件是什么?是是否可以直接进行简单处理吗(如上面的还需要解析器啥的)
    // @Lazy、@Primary、@DependsOn、@Role、@Description,后面两个都没使用过
    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));
            }
        }
    }

    // 定制处理,customizers 这种可以定制处理的(或命名)的在 Spring 中还挺多的
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(abd);
        }
    }

    // 问题:这里的 beanName 为什么不可以设计到 BeanDefinition 里面呢,还需要封装一层
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    // 如果当前类要被代理,代理的模式(JDK、CGLIB)
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    // 注册 BD 到容器,没有进一步处理
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

3. rerfresh.BeanFactoryPostProcessor 执行

上面已经将配置类给转换为 BeanDefinition 注入容器了,接下来还需要解析这个 BeanDefinition
BeanFactoryPostProcessor:对 BeanDefinition 进行进一步修饰和处理,一般不会再将 BeanDefinition 注入 BeanFactory
BeanDefinitionRegistryPostProcessors:BeanFactoryPostProcessor 的子接口,主要是发现 BeanDefinition 并将 BeanDefinition 注入 BeanFactory
注意上面两个接口所提供的/需要实现的方法的功能,一般不会在 BeanFactoryPostProcessor 接口提供的功能中发现 BD 和注入 BD

org.springframework.context.support.AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // Prepare this context for refreshing.
        // 暂略
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 暂略
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 内部设置了一些 BeanFactory 的属性,直接注入了一些 Bean 实例
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 暂略,这里好像 Web 进行处理了
            postProcessBeanFactory(beanFactory);

            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            // 调用 BeanFactoryPostProcessor 对 BeanDefinition 进行处理,通过对 BeanDefinition 处理可能又会发现更多的 BeanDefinition(如解析 @ComponentScan 时)
            invokeBeanFactoryPostProcessors(beanFactory);
            ...
        }
    }
}

上面代码很多都略去了,现在仅先抓住主干,具体细节暂略
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 这种使用 Delegate 进行处理的方法, 是为了避免单个类太长 + 功能太多吗?单一职责?有时候一些类我会命名为 Helper
    // 注意这里的 getBeanFactoryPostProcessors, 也就是我们也可以在 refresh 容器前将自定义的 BeanFactoryPostProcess add 进入 ApplicationContext
    //    至于容器内部自己注册进去的那些,会在内部自己发现(因为可以从传入的 BeanFactory 中查)
    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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

下面这个也只是大体流程,具体的 BeanFactoryPostProcessor 没有具体解析流程
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // WARNING: Although it may appear that the body of this method can be easily
    // refactored to avoid the use of multiple loops and multiple lists, the use
    // of multiple lists and multiple passes over the names of processors is
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
    // and Ordered processors. Specifically, we must NOT cause processors to be
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
    // in the wrong order.
    //
    // Before submitting a pull request (PR) to change this method, please review the
    // list of all declined PRs involving changes to PostProcessorRegistrationDelegate
    // to ensure that your proposal does not result in a breaking change:
    // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    // 下面先调用的是 BeanDefinitionRegistryPostProcessors,这个主要是发现 BeanDefinition 并将 BeanDefinition 注入 BeanFactory
    // 而与其类似的(其父接口)为 BeanFactoryPostProcessor,这个主要是对 BeanDefinition 进行进一步修饰和处理,一般不会再将 BeanDefinition 注入 BeanFactory
    Set<String> processedBeans = new HashSet<>();

    // 这个不是 BeanFactory 继承链的,而是单独的一个接口,提供对容器 BeanDefinition 的增删查等操作
    // 会有不是的场景吗,后面不是就直接调用 BeanFactoryPostProcessor 操作 BeanDefinition 了(也即不能增删等操作,仅能查询并修改 BeanDefinition)
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 注意这里就已经执行了,但是 BeanFactoryPostProcessor 接口的方法还未执行(父接口就是 BeanFactoryPostProcessor)
                // 这里实际上就可以执行以下自己的 BeanDefinition 发现逻辑啊等等,MyBatis 实现了这个吗?
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 存储的实际是一已执行的,这种命名是否可以优化一下便于阅读
                registryProcessors.add(registryProcessor);
            }
            else {
                // BeanFactoryPostProcessor 类型,还未执行
                regularPostProcessors.add(postProcessor);
            }
        }

        // 注意下面执行 BeanFactory 内的 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor,因为需要实例化才能执行,所以在这里就 getBean 了
        //    包括如果我们也注入了这些类型的,那么也是在这里就被 getBean 了,还可能没经过整个生命周期,因此编写时要注意

        // 下面就是处理 BeanFactory 中的,内含
        // 1. 上面自定义执行后注入的
        // 2. Spring 容器内部自己注入的
        // 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.
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        // 先处理 PriorityOrdered 接口的,也先执行
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        // 处理 Ordered 接口的
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            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);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        // 处理其他的,内部进行了 while 处理,也即在上面执行后注入的如果未执行也会在下面执行,当然在下面执行后注入的也会被执行
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                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, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        // 这里就是执行  BeanFactoryPostProcessor 接口的,优先级也是先执行 BeanDefinitionRegistryPostProcessor 的,顺序也是上面执行的顺序
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        // 这里参数传入的优先级反而靠后了
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // Invoke factory processors registered with the context instance.
        // 注意了,这里仅执行了参数传入的,对于 BeanFactory 内部的没有执行
        // 当然同时由于 BeanFactory 类型的原因,认为是不可以向内注入 BeanDefinition 的,因此也没必要 while 关心是否有新的注入
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 下面就应该处理 BeanFactory 内部的 BeanFactoryPostProcessor 接口方法了,上面虽然执行了一些,但那是 BeanDefinitionRegistryPostProcessor 类型的(BeanFactoryPostProcessor 子接口)

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    // 获取 BeanFactory 内部所有的 BeanFactoryPostProcessor,注意入参传入的没有
    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) {
        // 上面已执行则略过
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
        // 分类且按照顺序执行
        // 问题: 为什么仅 priority 的在这里就获取了 Bean,而其他的后面才获取呢(倒不是逻辑问题,而是写的时候怎么想的)
        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.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    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<>(nonOrderedPostProcessorNames.size());
    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();
}
posted @ 2022-04-08 20:54  YangDanMua  阅读(147)  评论(0编辑  收藏  举报