Springboot启动原理

Springboot启动原理

一、 开始

启动一个springboot项目,最简单的就是配置一个springboot启动类,然后运行即可

@SpringBootApplication
public class SpringBoot {
	public static void main(String[] args) {
		SpringApplication.run(SpringBoot.class, args);
	}
}

二、@SpringBootApplication原理解析

1. @SpringBootApplication组成

(1) @EnableAutoConfiguration(核心)

在启动时会自动导入“自动配置”AutoConfigurationlmportSelector类,该类会将所有符合条件的 @Configuration 配置都进行加载

(2)@SpringBootConfiguration

等价于@Configuration,将这个类标记为配置类会被加载到容器中

(3)@ComponentScan

自动扫描并加载符合条件的Bean

2. run(SpringBoot.class, args)原理解析

当执行run方法后,会进行四个阶段

(1)服务构建

首先要把传入的“资源加载器、主方法类”记录在栈内存中
然后我会逐一判断对应的服务类是否存在来确定web服务的类型(默认Servlet,Reactive,None)

  • 基于Servlet的web服务有 Tomcat,响应式非阻塞服务Reactive(spring-webflux),啥也不是的None
    去读取所有META-INF/spring.factories文件中的“注册初始化”(BootstrapRegistryinitializer)、“上下文初始化”(ApplicationContextinitializer)和“监听器”(ApplicationListener)这三类配置
    接下来会通过“运行栈”stackTrace判断出main方法所在的类(启动类本身)
(2)环境准备
  1. new一个后续会陆续使用到的“启动上下文”(BootstrapContext)
  2. 同时逐一调用刚刚加载的“启动注册初始化器”BootstrapRegistrylnitializer中的初始化initialize方法
  3. 接下来将"java.awt.headless”这个设置改为true,表示缺少显示器、键盘等输入设备也可以正常启动
  4. 启动“运行监听器”(SpringApplicationRunListeners)
  5. 发布“启动”事件,获取并加载sping-boot工程spring gactories配置文件中的EventPublishingRunListener,从而会将监听器引入,从而我们可以通过监听事件在启动流程中加入自定义逻辑
  6. 通过prepareEnvironment方法“组装启动参数”
    - 第一步 构造一个“可配置环境”ConfigurableEnvironment,根据不同的web服务类型会构造不同的环境,同样默认servlet
    - 构造之后会加载很多诸如“系统环境变量”systemEnvironment,“jvm系统属性” systemProperties等在内的4组配置信息,把这些配置信息都加载到一个叫做propertySources的内存集合
    - 通过“配置环境” configureEnvironment方法将我们启动时传入的环境参数args进行设置,列如启动时传入的诸如“开发/生产”环境配置等都会在这一步进行加载
    - 同时在propertySources集合的首个位置添加一个值为空的配置内容“configurationProperties”
    - 发布“环境准备完成”这个事件会被监听器监听后会进行相应处理,例如“环境配置后处理监听器”EnvironmentPostProcessorApplicationListener会去加载spring.factories配置文件中“环境配置后处理器”EnvironmentPostProcessor(“监听器”通过观察者模式设计是逐一“串行”执行,不是“异步并行”,需要等待所有监听器都处理完之后才去执行后续的逻辑)
  7. 通过二次更新保证匹配,紧接着将Spring.beaninfo.ignore"设为true,同时打印banner图
(3)容器搭建(内部的属性、集合以及配套功能的结构体ApplicationContext)

通过createApplicationContext来创建容器

  1. 单先根据服务类型创建"容器"ConfigurableApplicationContext,创建“注解配置的Servlet-Web服务容器”Annotationconfig ServletWebServerApplicationContext
    - 构造存放和生产我们bean实例的"Bean工厂”DefaultListableBeanFactory
    - 用来解析@Component、@ComponentScan等注解的“配置类后处理器”ConfigurationClassPostProcessor
    - 用来解析@Autowired、@Value、@lnject等注解的“自动注解Bean后处理器”AutowiredAnnotationBeanPostProcessor等在内的属性对象
  2. 通过prepareContext方法对容器中的部分属性进行初始化
    - 先用postProcessApplicationContext方法设置"Bean名称生成器"、“资源加载器”、"类型转换器"等
    - 执行之前我们加载进来的“上下文初始化”ApplicationContextinitializer(默认7个),实现容器ID、“警告自志处理、日志监听
  3. 发布“容器准备完成”监听事件,陆续为容器注册“启动参数、"Banner”、"Banner引用策略”和“懒加载策略”等等
  4. 通过Bean定义加载器将“启动类”在内的资源加载到“Bean定义池”BeanDefinitionMap中,以便后续根据Bean定义创建"Bean对象"
  5. 发布 “资源加载完成”事件
(4)填充容器
  1. 生成自身提供的Bean对象,与自定义的所有Bean对象,并放在“容器”器官中 ==(自动装配)
    (12个小步骤 - Bean的生命周期管理,构造和启动一个web服务器)
    第一步、通过prepareRefresh方法,在己有的“系统环境”基础上,准备servlet相关的环境Environment,其他的环境配置在“环境准备”中已经注册完成,通过“初始化属性资源” initServletPropertySources方法,对"Servlet初始化参数” servletContextInitParams和servletConfiginitParams进行赋值,然后通过validateRequiredProperties方法,检验是否有必填的环境变量,可以在自定义“初始化属性资源”initPropertySources方法中,通过setRequiredProperties將某些环境变量设置为必填,最后,完成监听器和事件初始化之后,环境准备就完成了
    第二步、通过obtainFreshBeanFactory和prepareBeanFactory方法,在获取容器同时在使用 BeanFactory 之前进行一些准备工作,由于Springboot选择了ServletWebServerApplicationContext作为容器,在之前步骤已经构造好beanFactory了,所以obtainFreshBeanFactory中不进行任何处理
  2. 发布“启动完成事件的同时”,会回调自定义实现的Runner接口,来处理一些执行后定制化需求
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值