SpringBoot启动流程

SpringBoot启动类注解构成:

  • 需要一个添加了@SpringBootApplication注解的启动类。
  • 该注解由@EnableAutoConfiguration@SpringBootConfiguration@ComponentScan三个注解构成。
  • @EnableAutoConfiguration是最为核心的,启动时会导入"自动配置"AutoConfigurationImportSelector类,这个类会将所有符合条件的@Configuration配置都进行加载。
  • @SpringBootConfiguration等同于@Configuration,将这个类标记为配置类,会被加载到容器中。
  • @ComponentScan会自动扫描并加载符合条件的Bean。
  • 如果启动类中不需要增加配置内容,也不需要指定扫描路径,使用@EnableAutoConfiguration替代@SpringBootApplication,也可以完成启动。
  • 注解完成后,运行起点就是SpringApplication的run方法。

run方法启动后会经历如下四个阶段:

  1. 服务构建

    • 首先把传入的"资源加载器、主方法类"记录在内存中,然后逐一判断对应的服务类是否存在,来确定Web服务的类型。默认是servlet,即基于Servlet的web服务,如tomcat,还有响应式非阻塞服务reactive,如spring-webflux,什么都不是则是用的none。
      • 确定了选择哪个web服务后,开始加载初始化类。通过读取所有META-INF/spring.factories文件中的"注册初始化"、“上下文初始化”、"监听器"这三类配置,即BootStrapRegistryInitalizerApplicationContextInitializerApplicationListenter
      • spring-boot和spring-boot-autoconfigure这两个工程中配置了7个"上下文初始化"和8个"监听器",这些配置信息会在后续的启动流程中使用到。
      • 程序员可以自定义这三个配置,将其放到工程中的spring factories文件中,项目就会将其一并加载进来。
      • 接下来会通过"运行栈"stackTrace判断main方法所在的类,大概率就是启动类本身,此时spring服务SpringApplication就构造完成了。
  2. 环境准备

    • 先通过createBootstrapContext方法创建一个"启动上下文"BootstrapContext,同时逐一调用刚刚加载的"启动注册初始化器"BootstrapRegistryInitializer中的初始化initialize方法。
    • 然后启动"运行监听器"SpringApplicationRunListeners,同时发布"启动"事件,获取并加载spring-boot工程spring factories配置文件中的EventPublishingRunListener,启动时,也会将服务构建时的8个监听器ApplicationListener都引入进来,程序员便可以通过监听这些事件,然后在启动流程中加入自定义逻辑了。
    • 接下来通过prepareEnvironment方法"组装启动参数"。
      • 首先构造一个"可配置环境"ConfigurableEnvironment,根据不同的Web服务类型会构造不同的环境,同样默认是Servlet,构造之后会加载很多诸如"系统环境变量"systemEnvironment、"jvm系统属性"systemProperties等在内的4组配置信息,把这些配置信息都加载到propertySources的内存集合中,后续使用到这些信息就无须重新加载了。
      • 通过"配置环境"configureEnvironment方法将启动时传入的环境参数args进行设置,例如启动时传入的诸如"开发/生产"环境配置等都会在这一步进行加载。
      • propertySources集合的首个位置添加一个值为空的配置内容configurationProperties。
      • 发布"环境准备完成"这个事件,刚加载进来的8个Listener会监听到这个事件,其中的部分监听器会进行相应处理,诸如"环境配置后处理监听器"EnvironmentPostProcessorApplicationListener会去加载spring.factories配置文件中"环境配置后处理器"EnvironmentPostProcessor,这里监听器通过观察者模式设计,是逐一"串行"执行的,而不是异步"并行",需要等待所有监听器都处理完成之后,才会继续执行后续逻辑。
      • 由于刚创建的"可配置环境"在一系列过程中可能会有变化,通过二次更新保证匹配。
      • spring.beaninfo.ignore设为true,表示不加载Bean的元数据信息,同时打印Banner图,环境准备阶段完成。
  3. 容器创建

    容器:各种属性、集合及配套功能的结构体ApplicationContext 即"上下文"。

    • 通过createApplicationContext来创建容器
      • 首先根据服务类型创建容器ConfigurableApplicationContext,默认的服务类型是servlet,创建的是"注解配置的Servlet-Web服务容器",即AnnotationConfigServletWebServerApplicationContext,在这个过程中会构造诸如:存放和生产bean实例的"Bean工厂"DefaultListableBeanFactory,用来解析@Component@ComponentScan等注解的"配置类后处理器"ConfigurationClassPostProcessor、用来解析@Autowired@Value@Inject等注解的"自动注解Bean后处理器"AutowiredAnnotationBeanPostProcessor等在内的属性对象,并把它们都放入容器。
      • 通过prepareContext方法对容器中的部分属性进行初始化,先用postProcessApplicationContext方法设置"Bean名称生成器"、“资源加载器”、"类型转换器"等,接着执行之前加载进来的"上下文初始化"ApplicationContextInitializer,默认加载7个,容器ID、警告日志处理、日志监听都是在这里实现的,发布"容器准备完成"监听事件。
      • 陆续为容器注册"启动参数"、“Banner”、"Bean引用策略"和"懒加载策略"等等。
      • 通过Bean定义加载器将"启动类"在内的资源加载到"Bean定义池"BeanDefinitionMap中,以便后续根据Bean定义创建"Bean对象",然后发布"资源加载完成"事件, 容器就创建完成了。
  4. 填充容器

    • 生产自身提供的和程序员自定义的所有Bean对象,并存放在上一步创建好的容器中,这个过程被称为"自动装配"。
    • Bean生命周期管理,构造和启动一个Web服务器如tomcat。
    • 发布"启动完成"事件,回调程序员自定义实现的Runner接口,来处理一些执行后定制化需求,启动流程结束。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值