我们上3个篇章写了springboot的自动装配、servlet组件的注入以及web容器实现内嵌的原理,现在我们来看springboot启动过程中到底做了些什么,也就是打开我们的run方法:

这里我们可以看到我们的run方法会new出一个springboot自己的一个容器,然后执行里面的run方法,这个args参数就是我们运行项目时所带的参数;因为这里new了一个springboot容器,所以我们打开SpringApplication,看里面初始化了什么东西:

可以看到,其实springboot容器里并没有做什么事,无非是做些判断,这些判断大多是通过判断容器里是否有某个类从而进行确定,比如判断是web应用里面检查的就是容器里是否有servlet类,是否加载了spring-web这个spring源码项目;而这里的初始化文件我们可以打开:

这两个初始化大类大致上的作用是初始化监听器,下面的这个类是全局的一个监听器,通过观察者的一个设计模式,我们可以发布各种各样的事件,然后进行监听,这里就不做过长的讲解(毕竟到现在我们的run方法还没讲==!),有兴趣的可以打开这些初始化类并学习spring里的监听器内容;

最后的这个找配置类其实就是通过拿到异常方法的调用栈,找到是否有main方法,再通过main方法返回你的主配置类名:

至此,我们应该大致知道在run方法运行前springboot做了哪些操作,接下来打开springboot容器里的这个run方法:

这里挑选我觉得比较实用的内容来讲:

首先是这个从配置文件读取的SpringApplicationRunListener接口的实现类,

这里我们自定义一个MyRunListener继承这个接口,重写接口原本的方法starting、started、running等等的方法即可让容器在启动前做一些自定义的操作,注意要把这个类写进

这个配置文件中;

其实在准备初始化阶段springboot做的就是发布监听;

我们打开refreshContext(context);看看在spring容器的初始化方面springboot做了哪些改进:

可以看到这里调用的super.refresh其实就是spring里本身的refresh()极度不要脸的照搬过来哈,我们再看里面的onRefresh方法

因为这个方法是spring容器在初始化后提供我们可以对容器做出修改的方法

可以看到,springboot在初始化时做的唯一改变就是添加了对web容器的判断,看其是否内嵌:

这里就很好地结合了之前讲的内嵌web容器以及注入servlet组件的原理了;先看一下web容器,如果是外部容器,即war包启动,通过web容器带动IOC启动,想想之前的java Config技术,其实就是利用WebApplicationInitializer这个接口,实现这个接口的类在tomcat运行时会调用里面的onStartup方法,我们重写这个onStartup方法,在里面创建web应用上下文,并加入监听器,在初始化context的时候会运行run方法,即启动IOC容器,所以判断项目是jar包启动还是war包启动,如果没拿到servletcontext,那就是以jar包启动:

看这里的getSelfInitializer(),初始化的正好对应开启的就是我们之前将servlet组件注入的里的onStartup方法,我们从spring容器里拿到所有实现了SevletContextInitializer的bean,再运行onStartup方法,把这些组件加入到servletcontext中,最后再通过getWebServer方法启动和获取web容器;也就是内嵌web容器和外部容器正好相反,内嵌的web容器是通过IOC来启动web容器,而外部容器是通过web容器来启动IOC;

至此,springboot在初始化Spring容器所作的贡献已然结束,我们再回到run方法里,可以看到后面无非就是打印一些日志输出以及一些容器启动后的监听器监听事件,所有简单总结下run方法里的作用:一、初始化springboot容器(1、判断上下文环境;2、加载Spring.factories配置文件里的ApplicationContextInitializer和ApplicationListener;3、找到main方法所在类);二、启动Sring容器(发布各式各样的监听器监听、重写Spring里的onReference方法:判断是否启动内嵌tomcat)

最后,再附上一张在网上找的Springboot的启动流程图:

springboot源码(4)的更多相关文章

  1. springboot源码解读

    springboot源码从main函数开始 public static void main(String[] args) { ApplicationContext app = SpringApplic ...

  2. SpringBoot源码分析之SpringBoot的启动过程

    SpringBoot源码分析之SpringBoot的启动过程 发表于 2017-04-30   |   分类于 springboot  |   0 Comments  |   阅读次数 SpringB ...

  3. SpringBoot源码篇:深度分析SpringBoot如何省去web.xml

    一.前言 从本博文开始,正式开启Spring及SpringBoot源码分析之旅.这可能是一个漫长的过程,因为本人之前阅读源码都是很片面的,对Spring源码没有一个系统的认识.从本文开始我会持续更新, ...

  4. Springboot源码分析之项目结构

    Springboot源码分析之项目结构 摘要: 无论是从IDEA还是其他的SDS开发工具亦或是https://start.spring.io/ 进行解压,我们都会得到同样的一个pom.xml文件 4. ...

  5. SpringBoot源码学习系列之异常处理自动配置

    SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...

  6. SpringBoot源码学习系列之嵌入式Servlet容器

    目录 1.博客前言简单介绍 2.定制servlet容器 3.变换servlet容器 4.servlet容器启动原理 SpringBoot源码学习系列之嵌入式Servlet容器启动原理 @ 1.博客前言 ...

  7. 【spring-boot 源码解析】spring-boot 依赖管理梳理图

    在文章 [spring-boot 源码解析]spring-boot 依赖管理 中,我梳理了 spring-boot-build.spring-boot-parent.spring-boot-depen ...

  8. SpringBoot源码解析系列文章汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的SpringBoot源码解析系列文章的汇总,当你使用SpringBoot不仅仅满足于基本使用时.或者出去面试被面试官虐了时.或者说想要深入了解一下 ...

  9. 外部配置属性值是如何被绑定到XxxProperties类属性上的?--SpringBoot源码(五)

    注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 SpringBoot是如何实现自动配置的?--SpringBoot源码(四) 温故而知新,我们来简单回顾一下上 ...

  10. SpringBoot是如何实现自动配置的?--SpringBoot源码(四)

    注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三 ...

随机推荐

  1. zjnu1735BOB (单调队列,单调栈)

    Description Little Bob is a famous builder. He bought land and wants to build a house. Unfortunately ...

  2. 01背包记录路径 (例题 L3-001 凑零钱 (30分))

    题意: 就是找出来一个字典序最小的硬币集合,且这个硬币集合里面所有硬币的值的和等于题目中的M 题解: 01背包加一下记录路径,如果1硬币不止一个,那我们也不采用多重背包的方式,把每一个1硬币当成一个独 ...

  3. K8S(15)监控实战-ELK收集K8S内应用日志

    K8S监控实战-ELK收集K8S内应用日志 目录 K8S监控实战-ELK收集K8S内应用日志 1 收集K8S日志方案 1.1 传统ELk模型缺点: 1.2 K8s容器日志收集模型 2 制作tomcat ...

  4. Nginx基础 - 配置缓存web服务

    1.缓存配置语法 1)proxy_cache配置语法 Syntax: proxy_cache zone | off; Default: proxy_cache off; Context: http, ...

  5. Python模块——Openpyxl(EXCEL)操作

    一.安装模块 pip install openpyxl 二.文件的操作 2.1文件创建 from openpyxl import Workbook #创建新的excle文件 wk = Workbook ...

  6. 微软大楼设计方案(中等) 推公式+RMQ问题

    近日,微软新大楼的设计方案正在广泛征集中,其中一种方案格外引人注目.在这个方案中,大楼由 nn 栋楼组成,这些楼从左至右连成一排,编号依次为 11 到 nn,其中第 ii 栋楼有 h_ih​i​​层. ...

  7. hdu5693D++游戏 区间DP-暴力递归

    主要的收获是..如何优化你递推式里面不必要的决策 之前的代码 这个代码在HDU超时了,这就对了..这个复杂度爆炸.. 但是这个思路非常地耿直..那就是只需要暴力枚举删两个和删三个的情况,于是就非常耿直 ...

  8. sql-libs(5)

    直接只用floor报错注入  或者 update即可

  9. RT-Thread学习笔记1-启动顺序与线程创建

    目录 1. 启动顺序 2. 堆范围 3. 线程创建 3.1 线程代码(入口函数) 3.2 线程控制块 3.3 线程栈 4. 系统滴答时钟 5. GPIO驱动架构操作IO 6. 线程优先级 & ...

  10. 如何在 macOS 上进行滚动截屏

    如何在 macOS 上进行滚动截屏 Shift-Command-5 https://support.apple.com/zh-cn/guide/mac-help/mh26782/mac demo Xn ...