前言
- springBoot版本 2.2.2-release
思考
springBoot要整合tomcat,参考springMvc项目。有3点需要做
- tomcat 启动
- tomcat怎么加载DispatcherServlet(把dispatcherServlet加入到tomcat容器中)
- mvc自动配置(mvc的一些类,要自动装配到spring容器中)
DispatcherServlet是springMvc中提供的一个转发调度所有的http请求的类,我们所有的controller的请求都会先经过这里。它实现了javax.servlet.Servlet接口,是javaEE的规范。其中定义了几个接口,这几个接口就是为我们定义servlet编程规范。servlet规范最开始的时候是为用户和厂家定义的,渐渐的被各种厂家进行封装,我们用户接触的也越来越少。
tomcat启动
tomcat为了占有市场,迎合spring,开发出了内嵌的tomcat。回忆下之前我们的项目启动,其实不是启动自己的类,而是把自己的代码发布到tomcat中。有了内嵌的tomcat,我们就不需要去启动tomcat了,可以在自己的项目中去new一个tomcat。spring-boot就是这样。
代码入口
- org.springframework.context.support.AbstractApplicationContext#refresh
这个方法是spring启动的核心方法
其中着重需要注意的是onRefresh方法,这个方法在spring的单独环境是没有用的,但是在springboot-web中,它的实现容器是AnnotationConfigServletWebServerApplicationContext,它的父类
ServletWebServerApplicationContext重写了这个方法,这个方法实现了tomcat的启动
- org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#onRefresh
很简单,直接创建webServer,这里不一定是tomcatServer,如果你引入了其他的Server,则创建其他的
-
创建tomcat
下面这个代码就很简单了,直接new一个tomcat,然后设置一些属性,包装到webServer中。
-
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration
引入的创建tomcat的工厂
tomcat怎么加载DispatcherServlet
dispatcherServlet 怎么创建的
首先springboot引入了一个配置,自动加载了一个类DispatcherServletAutoConfiguration
我们进入这个类,看下面这个
ok,到这里我们就知道这个类是怎么创建并且加入到spring容器了
怎么加载DispatcherServlet到tomcat
这里先聊下servlet的另一个规范,javax.servlet.ServletContainerInitializer这个方法定义了所有的servlet容器启动之后都必须调用这个方法。我们来看看spring这方面tomcat的实现
注意这是springboot的实现,不是tomcat的实现,tomcat会找到所有实现ServletContainerInitializer的Class类,来调用它们的onStart方法
org.springframework.boot.web.embedded.tomcat.TomcatStarter
下面这个调用是比较新的写法,可以看做是这个onStart方法的实现,最终调用selfInitalize方法
这里使用了模版设计模式,onstart方法在RegistrationBean中实现,但是它调用了一个自己的抽象方法org.springframework.boot.web.servlet.RegistrationBean#register
- org.springframework.boot.web.servlet.RegistrationBean#onStartup 调用这个方法
org.springframework.boot.web.servlet.RegistrationBean#onStartup
上面说到这个register是一个抽象方法,所以我们找它的实现
- org.springframework.boot.web.servlet.DynamicRegistrationBean#register
又是一个模版设计模式,我们继续看它的实现
- org.springframework.boot.web.servlet.ServletRegistrationBean#addRegistration
最终调用了这个实现
mvc自动配置
- spring.factories自动配置
在spring-boot-autoconfigure 项目下有一个文件
src/main/resources/META-INF/spring.factories
这里我单独把web相关的配置复制出来。还有其他的很多配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
- 这个类启动的时候就会加入到spring容器里面,加载一些我们需要的类,我们简单看看
- 配置tomcat工厂
我们为什么创建的是一个tomcat,
- 首先配置里第一个引入的是tomcat
- 其次我们引入的spring-boot-web-starer中依赖的是tomcat,只有tomcat才满足启动条件
- 其他的还有一些其他的引入:
错误信息
过滤器,requestMapping,解析器
总结,spring提供了强大的扩展能力,spring-boot在spring提供的这些扩展能力之上进行了默认配置的开发。这些自动配置已经覆盖了市面上的绝大多数主流的项目。包括数据库,消息中间件等。我们只需要更专注于业务开发即可!