前言
本人其实一直想学习spring boot源码,但是由于一直没时间去弄,弄了也没有专心学习完,所以这里就记录学习源码实现的笔记。
一、什么是springBoot
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。约定大于配置。Spring Boot应用中这些第三方库几乎可以是零配置的开箱即用(out-of-the-box),大部分的 Spring Boot 应用都只需要非常少量的配置代码(基于 Java 的配置),开发者能够更加专注于业务逻辑。
二、SpringBoot特点
- 大量的starter框架组件开箱即用
- 零xml配置
- 内嵌Tomcat,无需外部容器War部署
- 一站式开发、快速构建一个项目
- 提供生产就绪型功能,如指标,健康检查和外部配置
- 自动集成springMvc、spring框架
三、SpringBoot优点
- 简化xml配置
- 简化依赖
- 简化部署
- 简化监控
- 丰富的其他工具组件生态圈
缺点:集成度较高,使用过程中不太容易了解底层。
四、SpringBoot核心理念
- 快速整合第三方框架(Spring、Redis)
(原理:Maven依赖整合和自定义starter) - 完全去除XML配置,采用注解形式
(原理:顾名思义根据spring框架原生注解实现包装) - 无需外部容器,内嵌Tomcat容器
(原理:Java语言创建Tomcat容器,将编译后class文件交给tomcat加载)
五、SpringBoot run方法源码解析
1)SpringBoot容器启动后其实会返回当前容器的上下文
2)SpringApplication.run(HelloApplication.class);等同于new SpringApplication(primarySources).run(args)
5.1、启动构造函数流程
new SpringApplication(primarySources).run(args)
- 1、new SpringApplication()
- 2、调用run方法
5.2、主要流程
- webApplicationType类型解析表示判断项目是不是走响应式运行
// 判断项目中所有jar包中有没有reactive.DispatcherHandler和有没有servlet.DispatcherServlet
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
// 判断当前环境中有木有servlet.Servlet
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
// 最后返回:WebApplicationType.SERVLET
- WebApplicationType
NONE:不会嵌入web服务器,最终通过外部tomcat启动
SERVLET:需要servlet服务器运行
REACTIVE:使用响应式web启动
- 获取当前项目需要加载的META-INF/spring.factories下的ApplicationContextInitializer和ApplicationListener
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
- 加载启动类到spring容器
六、@SpringBootApplication
6.1、@SpringBootConfiguration
- @Configuration作用:将其类指定为启动类
6.2、@ComponentScan
扫描包下的类文件
6.3、@EnableAutoConfiguration
加载第三方配置类
该注解引入了AutoConfigurationImportSelector.class类,采用选择器方式,读取spring-boot-autocongigure包下面spring.factories,再找到EnableAutoConfiguration下面的109个配置类,再接着注册到IOC容器
注意这109个并不是全部注册进去,部分的包只有引入相关依赖才会注册进去
七、SpringBoot如何创建springMvc和tomcat
使用@EnableAutoConfiguration就会去加载下面两个配置类
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
- DispatcherServletAutoConfiguration
会加载ServletWebServerFactoryAutoConfiguration.class
该类表示支持tomcat、jetty、Undertow三种服务器
这个时候就会设置tomcat端口、地址等默认信息
先创建tomcat再去加载DispatcherServlet整个springMvc
八、总结启动流程
8.1、核心步骤
1、创建SpringApplication对象
2、调用run方法实现启动,并返回当前容器的上下文
8.2、详细流程
-
1、创建SpringApplication对象,springboot容器初始化操作
-
2、获取当前启动类型 原理:判断classpath是否有加载servlet返回spring web启动方式
-
3、setInitializers读取spring boot包下面的spring.factories文件,获取对应的ApplicationContextInitializer装配到集合
-
4、setListeners读取…下spring.factories文件,获取到ApplicationListener装配到集合
-
5、mainApplicationClass获取当前运行的主函数
-
6、调用run方法实现启动
-
7、StopWatch stopWatch = new StopWatch(); 记录项目启动时间
-
8、SpringApplicationRunListeners listeners = getRunListeners(args);
读取META-INF/spring.factories文件SpringApplicationRunListener类型存入集合 -
9、listeners.Starting() 循环调用监听starting 方法
-
10、prepareEnvironment(listeners, applicationArguments);
prepareEnvironment 读取配置文件到SpringBoot 容器 -
11、Banner printedBanner = printBanner(environment);
打印Banner日志 -
12、context = createApplicationContext();
创建SpringBoot上下文对象 -
13、refreshContext(context); 刷新上下文
-
14、创建tomcat容器
-
15、加载SpringMvc
-
16、afterRefresh定义一个空的模块给其他之类实现
-
17、listeners.started 广播和回调机制通知监听器已经启动成功
-
18、listeners.runing 广播和回调机制通知监听器启动成功runing