• 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();
    }
    
  • 相关阅读:
    django学习笔记
    django配置setting文件
    django用mysql数据库出现的问题解决
    hadoop本地集群搭建
    生成器
    Java自动装箱的陷阱
    LeetCode 89. Gray Code
    LeetCode 476. Number Complement
    Javac编译与JIT编译
    LeetCode 462. Minimum Moves to Equal Array Elements II
  • 原文地址:https://www.cnblogs.com/chenxingyang/p/16119703.html
Copyright © 2020-2023  润新知