Springboot启动流程

简介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};

@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};

@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};

@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
}

总结

SpringBoot启动的时候,不论调用什么方法,都会构造一个SpringApplication的实例,然后调用这个实例的run方法,这样就表示启动SpringBoot。
在run方法调用之前,也就是构造SpringApplication的时候会进行初始化的工作,初始化的时候会做以下几件事:

把参数sources设置到SpringApplication属性中,这个sources可以是任何类型的参数。本文的例子中这个sources就是MyApplication的class对象
判断是否是web程序,并设置到webEnvironment这个boolean属性中
找出所有的初始化器,默认有5个,设置到initializers属性中
找出所有的应用程序监听器,默认有9个,设置到listeners属性中
找出运行的主类(main class)

SpringApplication构造完成之后调用run方法,启动SpringApplication,run方法执行的时候会做以下几件事:

构造一个StopWatch,观察SpringApplication的执行
找出所有的SpringApplicationRunListener并封装到SpringApplicationRunListeners中,用于监听run方法的执行。监听的过程中会封装成事件并广播出去让初始化过程中产生的应用程序监听器进行监听
构造Spring容器(ApplicationContext),并返回
3.1 创建Spring容器的判断是否是web环境,是的话构造AnnotationConfigEmbeddedWebApplicationContext,否则构造AnnotationConfigApplicationContext
3.2 初始化过程中产生的初始化器在这个时候开始工作
3.3 Spring容器的刷新(完成bean的解析、各种processor接口的执行、条件注解的解析等等)
从Spring容器中找出ApplicationRunner和CommandLineRunner接口的实现类并排序后依次执行