SpringBoot源码解析

1.启动的过程:

  • 首先在main函数中启动当前应用程序(SpringApplication启动)
  • 创建SpringApplication对象(new SpringApplication()).在对象的构造方法中进行参数的初始化工作,最主要的是判断当前应用程序的类型以及初始化器和监听器,在此过程中会加载整个应用程序中的spring.factories文件,将文件的内容放在缓存对象中,方便后续获取,具体步骤如下:
    • 配置resourceloader
    • 判断当前应用程序的类型
    • 获取初始化器的实例对象
    • 获取监听器的实例对象
    • 找到当前应用程序的主类,开始执行
  • SpringApplication对象创建完成之后开始执行run()方法,来完成整个启动过程.而run方法中主要的步骤如下:
    • 设置启动时间
    • 设置上下文
    • 设置异常报告器
    • 创建监听器并从中获取符合监听事件的几个监听器
    • 配置命令行参数
    • 准备应用程序运行的环境
    • 接着是核心的上下文部分,分为prepareContext()上下文的前置处理,refreshContext()核心方法,就是spring中的refresh()方法,其中的beanFactoryPostProcessor()完成自动装配的核心,afterRefresh()上下文后置结束处理
    • 之后就是发布应用上下文启动,执行runner()运行器
    • 发布应用上下文就绪并返回
    • SpringApplication启动结束

2.具体的run()方法源码如下:

public ConfigurableApplicationContext run(String... args) {//设置启动时间long startTime = System.nanoTime();//设置上下文DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();ConfigurableApplicationContext context = null;this.configureHeadlessProperty();//创建监听器并从中获取符合监听事件的几个监听器SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {//配置命令行参数ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);//准备应用程序运行的环境ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);this.configureIgnoreBeanInfo(environment);//打印banner(也就是那个p用没有的图标)Banner printedBanner = this.printBanner(environment);context = this.createApplicationContext();context.setApplicationStartup(this.applicationStartup);//prepareContext和refreshContext是自动装配的核心方法 而且这个refreshContext方法就是spring中的refresh()方法 使用的就是里面的beanFactoryPostProcessor()来实现的自动装配this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);this.refreshContext(context);this.afterRefresh(context, applicationArguments);Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);//发布应用上下文启动,执行runner()运行器if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);}listeners.started(context, timeTakenToStartup);this.callRunners(context, applicationArguments);} catch (Throwable var12) {this.handleRunFailure(context, var12, listeners);throw new IllegalStateException(var12);}//发布应用上下文就绪并返回try {Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);return context;} catch (Throwable var11) {this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);throw new IllegalStateException(var11);}}

3.自动装配的原理

自动装配的实现就是为了从spring.factories文件中获取到对应的bean对象,并且由spring容器帮我们进行管理.

  • 当启动SpringBoot应用程序的时候会先创建SpringApplication对象,在对象的构造方法中进行参数的初始化工作,最主要的是判断当前应用程序的类型以及初始化器和监听器,在此过程中会加载整个应用程序中的spring.factories文件,将文件的内容放在缓存对象中,方便后续获取
  • SpringBoot对象创建完成之后,开始执行run()方法来完成整个启动过程.启动过程中主要包括的两个方法:prepareContext()和refreshContext()方法,在这两个关键的步骤中完成自动装配的核心功能
  • 在prepareContext()方法中主要完成的是对上下文对象的初始化操作,包括属性值的设置,在整个过程中最重要的方法是load(),主要完成将当前启动类作为一个beanDefinition注册到registry(注册表)中,方便后续进行BeanFactoryPostProcesser调用执行的时候,找到对应的主类,来完成对@SpringBootApplication,@EnableAutoConfiguration等注解的解析工作(注意:要完成这些注解的解析工作,必须要获取到启动类)
  • 在refreshContext()方法中,会调用spring中的refresh()方法(refresh()方法一共有13个非常关键的方法来完成整个spring应用程序的启动),在自动装配中会调用invokeBeanFactoryPostProcessor()方法,在此方法中主要是对ConfigurationClassPathPostProcessor类的处理(它是BeanFactoryPostProcessor的子类,也是BeanDefinitionReaderPostProcessor的子类).在调用的时候会先调用BeanDefinitionReaderPostProcessor中的postProcessorBeanDefinitionRegistry方法,然后调用PostProcessBeanFactory()方法,在执行postProcessorBeanDefinitionRegistry方法的时候会解析处理各种注解,最主要的是对@Import注解的解析
  • 在解析@Impo注解的时候,会有一个getInstance()方法,从主类中递归解析注解,把所有@Import的注解都解析到,然后在processImport()方法中对Import的类进行分类,此处主要识别的是@Import(AutoConfigurationImportSelect.class)中的AutoConfigurationImportSelect,在后续的过程中调用deferredImportSelectorHandler()中的方法来完成EnableAutoConfiguration对象的加载,之后获取到spring.factories找到大量的自动装配的类(并不是所有的类都会用到),将不适用的装配类移除,过滤掉多余的装配类(starter的作用就是确定那些配置类是需要的,哪些是不需要的)

SpringBoot源码解析相关推荐

  1. springboot源码解析-管中窥豹系列之BeanFactoryPostProcessor(十一)

    一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...

  2. springboot源码解析autoconfigure之WebMvcAutoConfiguration

    2019独角兽企业重金招聘Python工程师标准>>> 说在前面 本次开始spring-boot-autoconfigure源码解析之WebMvcAutoConfiguration ...

  3. maven 公共模块依赖_「spring-boot 源码解析」spring-boot 依赖管理

    问题 maven 工程,依赖管理是非常基本又非常重要的功能,现在的工程越来越庞大,依赖越来越多,各种二方包.三方包太多太多,依赖冲突处理起来真是让人头疼,经常需要涉及到多个地方需要调整. 微信公众号: ...

  4. 【java】spring-boot源码解析之应用启动

    spring boot 项目使用默认配置的思想,极大的简化了 spring 项目的开发.下面的代码就是一个最简单的 spring 项目: @SpringBootApplication public c ...

  5. SpringBoot源码解析(十一)@Primary

    在SpringBoot中有许多类使用到了@Primary注解,关于用法,请看这篇博客:在spring中常被忽视的注解 @Primary. 这次我们不说用法,从源码层面来看下: 一.入口 在创建bean ...

  6. SpringBoot 源码解析——如何进行源码环境调试?

    已经分析过 spring-boot-tests/spring-boot-smoke-tests 下的冒烟测试和很早之前版本的 sample 是一样的,所以我们想直接利用这些 sample code 来 ...

  7. spring-boot源码解析之AnnotationConfigServletWebServerApplicationContext

    文章目录 主要功能 Factory Constructor Additional Component Candidates Parent Class ServletWebServerApplicati ...

  8. SpringBoot源码解析(七)EnvironmentPostProcessor

    本文将重点介绍SpringBoot提供给我们的另一个扩展点EnvironmentPostProcessor,它允许我们到任意的指定目录.以任意的方式加载一组配置,并赋予任意的优先级 上文对prepar ...

  9. SpringBoot 源码解析 —— SpringApplication 源码分析

    正常的 SpringBoot 应用程序 一个正常的 SpringBoot 项目的启动类中常见代码如下: @SpringBootApplication public class SpringbotApp ...

最新文章

  1. IKE phase 2
  2. 那些年我用过的SAP IDE
  3. synchronized的理解
  4. 3-间隔插入排序C实现(希尔排序铺垫)
  5. ORACLE基础应用学习-- 各种故障的恢复方法总结
  6. Deep Learning基础--各个损失函数的总结与比较
  7. 单片机c语言数码显示实验报告,单片机c语言版数码动态显示实验报告.doc
  8. pat03-树3. Tree Traversals Again (25)
  9. 判断连个单链表是否交叉,并找到交叉点
  10. 冲刺第二阶段工作总结01
  11. jQuery:设置body的背景
  12. 算法笔记_面试_0.刷leetcode攻略
  13. 【verilog教程】第9篇:verilog常见问题合集
  14. 数字通信系统相关基本概念(一)
  15. 学校网站模板s1_中学学校网站源码_学校网站管理系统
  16. 百度网盘 api抓包
  17. 在Ubuntu 8.10 中安装使用新一代输入法ibus Deb包下载_Ubuntu,Linux,ibus输入法,拼音,五笔,搜狗
  18. 【机器学习开放项目】安然公司电子邮件数据集
  19. maximo跟java_maximo中直接应用得到数据库联接
  20. 此计算机将网络限制为,解决win7无法连接wifi提示“此计算机当前已将连接限制为...”的方法...

热门文章

  1. ORACLE认证考试之ocjp 考试题之四
  2. 玩转华为ENSP模拟器系列 | 两个网关之间利用Tunnel接口实现IPSec VdPdNd隧道多链路备份
  3. LaTeX数学公式的矩阵、多行公式
  4. 关于游戏中的Ambient Occlusion 环境光遮罩(AO)
  5. 深入理解JVM虚拟机14:JVM性能调优的6大步骤,及关键调优参数详解
  6. java pdf 用系统字体大小_java 用itext设置pdf纸张大小操作_Java_软件编程
  7. 任贤齐专辑 43 合集
  8. stm32 adc输入电压范围_正点原子【STM32-F407探索者】第二十五章 光敏传感器实验...
  9. MyBatis08:ResultMap 的结果集映射,java编程题面试题
  10. 知道小编告诉你税务处理流程的方法