讲一讲Springboot的启动流程

Springboot启动流程主要分为两个部分:
第一部分进行SpringBootApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器
第二部分实现了SpringApplication.run() 方法,主要调用了spring容器启动方法扫描配置,加载bean到spring容器中,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块,自动注入等功能

一、Spring Boot 的main方法

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

二、核心注解

2.1 @SpringBootApplication
@SpringBootApplication 是最常用也几乎是必用的注解,其实@SpringBootApplication相当于 @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan

2.2 @SpringBootConfiguration
@SpringBootConfiguration 是继承自Spring的 @Configuration 注解,@SpringBootConfiguration 作用相当于 @Configuration,@Configuration相当于一个spring的xml文件,配合@Bean注解,可以在里面配置需要Spring容器管理的bean

2.3 @ComponentScan
@ComponentScan通常与@Configuration一起配合使用,相当于xml里面的context:component-scan,用来告诉Spring需要扫描哪些包或类。如果不设值的话默认扫描@ComponentScan注解所在类的同级类和同级目录下的所有类,所以对于一个Spring Boot项目,一般会把入口类放在顶层目录中,这样就能够保证源码目录下的所有类都能够被扫描到。

2.4 @EnableAutoConfiguration
@EnableAutoConfiguration 从classpath中搜寻所有的 META-INF/spring.factories 配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration 对应的配置项通过反射实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。

2.5 @Import
相当于xml里面的,允许导入 Configuration注解类 、ImportSelector 和 ImportBeanDefinitionRegistrar的实现类,以及普通的Component类。

2.6 @Conditional
Spring Boot的强大之处在于使用了 Spring 4 框架的新特性:@Conditional注释,此注解使得只有在特定条件满足时才启用一些配置。这也 Spring Boot “智能” 的关键注解

2.7 总结
上面的注解都在做一件事:注册bean到spring容器
@SpringBootConfiguration 通过与 @Bean 结合完成Bean的 JavaConfig配置;
@ComponentScan 通过范围扫描的方式,扫描特定注解注释的类,将其注册到Spring容器;
@EnableAutoConfiguration 通过 spring.factories 的配置,并结合 @Condition 条件,完成bean的注册;
@Import 通过导入的方式,将指定的class注册解析到Spring容器;

三. Spring Boot 启动流程
3.1 SpringApplication的实例化

3.1.1 推断应用类型是否是Web环境
这里通过判断是否存在 Servlet 和 ConfigurableWebApplicationContext 类来判断是否是Web环境,上文提到的 @Conditional 注解也有基于 class 来判断环境

3.1.2 设置初始化器(Initializer)
因此,所谓的初始化器就是 org.springframework.context.ApplicationContextInitializer 的实现类,这个接口是这样定义的:ApplicationContextInitializer是一个回调接口,它会在 ConfigurableApplicationContext 容器 refresh() 方法调用之前被调用,做一些容器的初始化工作

3.1.3. 设置监听器(Listener)
设置完了初始化器,下面开始设置监听器:个接口基于JDK中的 EventListener 接口,实现了观察者模式。对于 Spring 框架的观察者模式实现,它限定感兴趣的事件类型需要是 ApplicationEvent 类型的子类,而这个类同样是继承自JDK中的 EventObject 类

3.1.4. 推断应用入口类(Main)
它通过构造一个运行时异常,通过异常栈中方法名为main的栈帧来得到入口类的名字

3.2 SpringApplication.run方法
完成了实例化,下面开始调用run方法:

3.2.1 获取RunListeners
从 META-INF/spring.factories 中读取Key为 org.springframework.boot.SpringApplicationRunListener 的Values,从类文档可以看出,它主要是负责发布SpringApplicationEvent事件的,它会利用一个内部的ApplicationEventMulticaster在上下文实际被刷新之前对事件进行处理

3.2.2 准备Environment环境

配置 Property Sources
配置 Profiles,为应用程序环境配置哪些配置文件处于active(活动)状态。
对于Web应用而言,得到的environment变量是一个StandardServletEnvironment的实例。得到实例后,SpringApplicationRunListeners 的用途和目的也比较明显了,它实际上是一个事件中转器,它能够感知到Spring Boot启动过程中产生的事件,然后有选择性的将事件进行中转

3.2.3 创建Spring Context

3.2.4 Spring Context前置处理
配置Bean生成器以及资源加载器(如果它们非空):

3.2.5 Spring Context刷新

3.2.6 Spring Context后置处理
CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调(类似开机自启动)

你可能感兴趣的:(中间件框架)