首页 > 编程语言 >springboot源码剖析(四) 上下文启动

springboot源码剖析(四) 上下文启动

时间:2022-10-30 17:00:36浏览次数:46  
标签:springboot ppName currentRegistryProcessors beanFactory 源码 context 2.1 上下文 class

  概念

           springboot在启动流程中最重要的事情便是加载启动spring组件,比如加载IOC容器,启动springMVC等。


  实现原理

      使用AnnotationConfigServletWebServerApplicationContext(下面简称为上下文)加载和启动spring组件。其中注册的bean都会存储在defalutListableBeanFactory中。

   uml类图

   上下文启动流程

 


 

  源码剖析  

           上下文启动

/** SpringApplication.class */
// 启动流程
public ConfigurableApplicationContext run(String... args) {
        // 根据应用类型实例化AnnotationConfigServletWebServerApplicationContext类
        context = this.createApplicationContext();
        // 异常报告类
        exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
        // ★1.启动准备
        this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        // ★2.刷新上下文
        this.refreshContext(context);
        // 空操作
        this.afterRefresh(context, applicationArguments);
}
// 1.启动准备
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    // ★ 1.1上下文设置环境配置
    context.setEnvironment(environment);
    // 上下文的bean工厂列表设置转换服务
    this.postProcessApplicationContext(context);
    // ★ 1.2 initializers初始化(调用对应的initialize方法,其中加载了beanFactoryPostProcessors)
    this.applyInitializers(context);
    // 1.3 事件发布器:通知监听器web服务初始化好了
    listeners.contextPrepared(context);
    // 启动日志,默认为true
    if (this.logStartupInfo) {
        // 启动日志(第一条springboot日志)
        this.logStartupInfo(context.getParent() == null);
        // 开发环境日志
        this.logStartupProfileInfo(context);
    }

    // 1.4 获取bean工厂列表提前注册实例一些单例bean
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    if (printedBanner != null) {
        beanFactory.registerSingleton("springBootBanner", printedBanner);
    }
    // springboot默认不允许bean定义覆盖
    if (beanFactory instanceof DefaultListableBeanFactory) {
        ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    // springboot默认不是懒初始化
    if (this.lazyInitialization) {
        context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
    }
    
    // 获取启动类
    Set<Object> sources = this.getAllSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    // 1.5 启动类注册进beanDefinitionMap当中
    this.load(context, sources.toArray(new Object[0]));
    // 1.6 事件发布器:通知监听器上下文准备好了
    listeners.contextLoaded(context);
}
// 2.刷新上下文
private void refreshContext(ConfigurableApplicationContext context) {
    // 2.1 调用上下文基类refresh方法
    this.refresh((ApplicationContext)context);
    if (this.registerShutdownHook) {
        try {
            context.registerShutdownHook();
        } catch (AccessControlException var3) {
        }
    }

}
/** AnnotationConfigServletWebServerApplicationContext.class 上下文 */
// 2.1 refresh核心逻辑
public void refresh() throws BeansException, IllegalStateException {
    synchronized(this.startupShutdownMonitor) {
        // 准备工作,初始化context的一些属性
        this.prepareRefresh();
        // 获取bean工厂列表
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        // 2.1.1 初始化bean工厂列表,如忽略依赖的接口,添加特定的beanPostProcessor,注册并实例化环境相关的bean
        this.prepareBeanFactory(beanFactory);


        try {
            // 2.1.2 同样还是给beanFactory添加beanPostProcessor以及registerResolvableDependency
            this.postProcessBeanFactory(beanFactory);
            // ★ 2.1.3 对BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor类型的类按照优先级进行解析(spring扩展点,读取修改bean定义)
            this.invokeBeanFactoryPostProcessors(beanFactory);
            // ★ 2.1.4 同上,将BeanPostProcessors类型注册到bean工厂列表的BeanPostProcessors中。其中AutoWiredAnnotationBeanPostProcessor也在此注册。(穿插到实例化bean的前后)
            this.registerBeanPostProcessors(beanFactory);
            // 初始化MessageSource
            this.initMessageSource();
            // 初始化ApplicationEventMulticaster(广播器)
            this.initApplicationEventMulticaster();
            // ★ 2.1.5 创建web容器(启动tomcat,加载mvc,开启一个非守护线程保证springboot不会运行完终止)
            this.onRefresh();
            // 注册监听者
            this.registerListeners();
            // ★ 2.1.6 实例化所有剩余的非懒加载单例 bean
            this.finishBeanFactoryInitialization(beanFactory);
            // 2.1.7 context发布上下文已刷新事件
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

    bean定义注册解析

/** PostProcessorRegistrationDelegate.class */
// 2.1.3 对BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor类型的类进行解析(有优先级顺序)。
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    Set<String> processedBeans = new HashSet();
    ArrayList regularPostProcessors;
    ArrayList registryProcessors;
    int var9;
    ArrayList currentRegistryProcessors;
    String[] postProcessorNames;
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
        regularPostProcessors = new ArrayList();
        registryProcessors = new ArrayList();
        Iterator var6 = beanFactoryPostProcessors.iterator();

        // 2.1.3.1 对context里beanFactoryPostProcessors的BeanDefinitionRegistryPostProcessor类解析 (环境准备阶段,initializers/事件发布 加载beanPostProcessors到context中)监听器/初始化器的优先级还是很高的
        while(var6.hasNext()) {
            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                // 注册bean定义后置处理器 
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 加到已注册处理器数组
                registryProcessors.add(registryProcessor);
            } else { // 常规处理
                regularPostProcessors.add(postProcessor);
            }
        }

        // 2.1.3.2 查找beanDefinitionNames中BeanDefinitionRegistryPostProcessor类(context构造reader成员变量时生成) 
        currentRegistryProcessors = new ArrayList();
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        String[] var16 = postProcessorNames;
        var9 = postProcessorNames.length;
        int var10;
        String ppName;
        for(var10 = 0; var10 < var9; ++var10) {
            ppName = var16[var10];
            // 类型需要为PriorityOrdered.class
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 得到的ConfigurationClassPostProcessor配置类后置处理器
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 加入到已处理bean
                processedBeans.add(ppName);
            }
        }         
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        // 加入到已注册处理器数组
        registryProcessors.addAll(currentRegistryProcessors);
        // ★ 2.1.3.3调用对应的注册方法,实现了各种spring核心注解的解析。从主类入口按照次序对@componentscan @import @bean等各种注解开始循环递归解析并生成beanDefination
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();
        
        // 2.1.3.4 再次查找beanDefinitionNames中BeanDefinitionRegistryPostProcessor类
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        var16 = postProcessorNames;
        var9 = postProcessorNames.length;

        for(var10 = 0; var10 < var9; ++var10) {
            ppName = var16[var10];
            // 剔除掉上次已处理bean && 类型需要为PriorityOrdered.class
            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);
        // 2.1.3.5 注册bean定义
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();
        boolean reiterate = true;


        while(reiterate) {
            reiterate = false;
            // 2.1.3.6 再次查找beanDefinitionNames中BeanDefinitionRegistryPostProcessor类
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var19 = postProcessorNames;
            var10 = postProcessorNames.length;
            // 类型不再需要为PriorityOrdered.class
            for(int var26 = 0; var26 < var10; ++var26) {
                String ppName = var19[var26];
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            // 2.1.3.7 注册bean定义
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }

        // 2.1.3.8 调用已注册的BeanDefinitionRegistryPostProcessor父类的BeanFactoryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
        invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    } else {
        invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    }

    // 2.1.3.9 同上,只是变成查找BeanFactoryPostProcessor类型
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    regularPostProcessors = new ArrayList();
    registryProcessors = new ArrayList();
    currentRegistryProcessors = new ArrayList();
    postProcessorNames = postProcessorNames;
    int var20 = postProcessorNames.length;

    // 2.1.3.10 排列BeanFactoryPostProcessor的优先级:实现了PriorityOrdered > 实现了Ordered > 普通
    String ppName;
    for(var9 = 0; var9 < var20; ++var9) {
        ppName = postProcessorNames[var9];
        if (!processedBeans.contains(ppName)) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                registryProcessors.add(ppName);
            } else {
                currentRegistryProcessors.add(ppName);
            }
        }
    }
    
    // 2.1.3.11 下面就是按优先级执行postProcessBeanFactory方法
    sortPostProcessors(regularPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size());
    Iterator var21 = registryProcessors.iterator();
    while(var21.hasNext()) {
        String postProcessorName = (String)var21.next();
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());
    Iterator var24 = currentRegistryProcessors.iterator();
    while(var24.hasNext()) {
        ppName = (String)var24.next();
        nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    beanFactory.clearMetadataCache();
}

 

标签:springboot,ppName,currentRegistryProcessors,beanFactory,源码,context,2.1,上下文,class
From: https://www.cnblogs.com/Duikerdd/p/16841571.html

相关文章

  • springboot源码剖析(三) 环境配置
    概念      springboot在启动流程中会把环境配置都加载进应用当中。实现原理     使用环境配置器用来加载和解析所有配置文件。配置文件......
  • springboot2
    学习文档:https://blog.csdn.net/ttxbgjj/article/details/122881011---尚硅谷课程笔记https://www.yuque.com/atguigu/springboot  ---尚硅谷官网文档学习视频:https:......
  • springboot源码剖析(二) 事件发布
    概念      springboot在启动流程中会发布一些事件通知依赖组件进行主动更新。      原理是springboot使用到的一种设计模式:观察者模式。优......
  • Spring源码-context:component-scan解析
    调用AbstractApplicationContext.refresh()刷新容器,会调用obtainFreshBeanFactory()获取ConfigurableListableBeanFactory。会去调用loadBeanDefinitions()方法解析xml文件......
  • springboot源码剖析(一) 总体启动流程
    前言  之前阅读STL(C++)源码的时候,有所感悟:大佬的代码总会实践到部分设计模式、新型语法特性,亦或是精巧的算法和数据结构。     读源码的技巧:大......
  • Spring源码分析之AOP
    AOP是什么面向切面的程序设计(Aspect-orientedprogramming,AOP,又译作面向方面的程序设计、剖面导向程序设计),是计算机科学中的一种程序设计思想,旨在将横切关注点与业务主体进......
  • SpringMVC源码-DispatcherServlet初始化
    web容器启动后会实例化Servlet,会执行Servlet的init方法且只会执行一次。后续调用doService处理客户请求。DispatcherServlet的构造方法publicDispatcherServlet(){ su......
  • 第四章 SpringBoot 底层机制
    搭建SpringBoot底层机制开发环境1、创建Maven项目lzw-springboot2、导入相关依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.o......
  • Springboot centos7 启动
     1、java-jardemo.jar说明:用这种方法启动后,不能继续执行其它命令了,如果想要继续执行其它命令,就都打断,打断一般用ctrl+c。2、java-jardemo.jar&第2种在第1种方式的基础......
  • redisson分布式限流[RRateLimiter]源码分析
    接下来在讲一讲平时用的比较多的限流模块--RRateLimiter1.简单使用publicstaticvoidmain(String[]args)throwsInterruptedException{RRateLimiterrateLimit......