spring boot源码及流程

为什么用springboot?

springboot是一个脚手架项目,提供了自动装配的功能,不用像以前一样自己去找少哪个包,配置复杂问题,现在只要引入对应的starter,修改yml就可以添加对应的功能。

SpringBoot自动配置原理:

1、@EnableAutoConfiguration这个注解会”猜”你将如何配置spring,前提是你已经添加了jar依赖项,如果spring-boot-starter-web已经添加Tomcat和SpringMVC,这个注释就会自动假设您在开发一个web应用程序并添加相应的spring配置,会自动去maven中读取每个starter中的spring.factories文件,该文件里配置了所有需要被创建spring容器中bean
2、在main方法中加上@SpringBootApplication和@EnableAutoConfiguration
SpringBoot starter工作原理:
1、SpringBoot在启动时扫描项目依赖的jar包,寻找包含spring.factories文件的jar
2、根据spring.factories配置加载AutoConfigure
3、根据@Conditional注解的条件,进行自动配置并将bean注入到Spring Context

如何找到spring.factories文件并初始化其中的类

1
2
3
4
getSpringFactoriesInstances方法
SpringFactoriesLoader.loadFactoryNames方法从spring.factories文件中获取全路径名
createSpringFactoriesInstances 实例化这些类
AnnotationAwareOrderComparator.sort 排序

spring boot 启动流程(带devtools):

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
39
40
41
42
43
44
45
46
47
48
49
50
51
1.SpringApplication.run(xx.class, args);
2.加载listener,这个listener中包含了RestartApplicationListener(devtools包的spring.factories)
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
3.监听器执行,发送应该开始启动事件
listener.starting();
4.RestartApplicationListener的方法就可以收到事件。
public void onApplicationEvent(ApplicationEvent event)
5.Restarter的初始化(单例的)
Restarter.initialize(args, false, initializer, restartOnInitialize);

6.Restarter.initialize(restartOnInitialize)的执行

7.Restarter.immediateRestart()的执行
8.LeakSafeThread.callAndWait(),这里是个线程,打断点需要用线程断点,启动线程并让主线程等待.这里入参是个匿名类
9.执行Restarter.doStart()至Restarter.relaunch()方法
10.创建RestartLauncher,这是个线程,看run方法,里面是执行的xx.class的run方法
11.重复以上步骤,执行至Restarter的初始化,这时localInstance是空,所以不会死循环
12.这时候就扫行到
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
13.根据webApplicationType=SERVLET实例化
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
14.因为main方法中传入了启动类,SpringApplication.getAllSources()方法,相当于配置文件xml
15.SpringApplication.load(ApplicationContext context, Object[] sources)
16.SpringApplication.getBeanDefinitionRegistry(ApplicationContext context)
17.BeanDefinitionLoader.load()方法 加载启动类到容器
18.BeanDefinitionLoader.isComponent方法,判断这个资源是否带有component注解
19.一路下来最终会调用refresh()方法
20.调用invokeBeanFactoryPostProcessors()执行BenFactoryPostProcessors
21.ConfigurationClassParser.processConfigurationClass()
22.ConfigurationClassParser.doProcessConfigurationClass()方法,根据启动类查找所有bean,
如果这些类里还有配置类,则会递归一直找全所有的bean,这里会转成bean的对象beanDefinition
23.ConfigurationClassParser.collectImports()递归获取注解import,注解上标有两个类
AutoConfigurationImportSelector.class、AutoConfigurationPackages.Registrar.class
AutoConfigurationImportSelector为自动装配的处理类


24.ConfigurationClassParser.getImports()

DeferredImportSelectorGroupingHandler.processGroupImports()
DeferredImportSelectorGrouping.getImports()
AutoConfigurationImportSelector.process()
AutoConfigurationImportSelector.getAutoConfigurationMetadata()
这里获取到

AutoConfigurationImportSelector.getAutoConfigurationEntry()
这里获取到所有EnableAutoConfiguration.class的AutoConfiguration类

AutoConfigurationImportSelector.getSpringFactoriesLoaderFactoryClass()
得到EnableAutoConfiguration.class

AutoConfigurationImportSelector.filter()方法会过滤不存在的自动装配类

spring boot 自动装配

1.load启动类(run方法传入的class)
2.根据启动类找到启动类上的注解import的AutoConfigurationImportSelector
3.获取到所有的自动装配类

spring boot mvc模块自动装配

1.DispatcherServletAutoConfiguration 自动装配类加载
2.初始化DispatcherServlet
3.客户端发送请求后,httpServlet中init方法,直到 dispatcherServlet中initStrategies


spring boot源码及流程
http://hanqichuan.com/2021/03/09/spring/spring boot源码及流程/
作者
韩启川
发布于
2021年3月9日
许可协议