版本说明:
- Spring Boot 2.x 版本:嵌入式Servlet容器自动配置是通过
WebServerFactoryCustomizer
定制器 来定制的; - Spring Boot 1.x 版本:是通过
EmbeddedServletContainerCustomizer
嵌入式的Servlet容器定制器来定制的。
SpringBoot官方文档:
Embedded Web Servers、
Embedded Servlet Container Support
参考博客:https://cloud.tencent.com/developer/article/1551867
0 嵌入式Servlet容器自动配置原理以及启动原理的步骤
步骤:
-
SpringBoot 启动时,根据导入的依赖信息,自动创建对应的
WebServerFactoryCustomizer
(web服务工厂定制器); -
WebServerFactoryCustomizerBeanPostProcessor
(web服务工厂定制器组件的后置处理器)获取所有类型为web服务工厂定制器的组件(包含实现WebServerFactoryCustomizer接口,自定义的定制器组件),依次调用customize
方法,定制Servlet容器配置; -
嵌入式的Servlet容器工厂创建Tomcat容器,初始化并启动容器。
1 嵌入式Servlet容器自动配置原理(以Tomcat为例)
1.1 简单介绍
SpringBoot默认使用Tomcat
作为嵌入式的Servlet容器,
这里所谓的嵌入式服务器就是,SpringBoot使用 apache组织 提供的Tomcat的API来配置和定制Tomcat服务。
SpringBoot在启应用动时都会加载各个jar包下的/META-INF/spring.factories
文件,读取其中的org.springframework.boot.autoconfigure.EnableAutoConfiguration
类型的所有自动配置类,从而达到自动配置的效果。
而我们的servlet容器的自动配置也是从这个配置文件着手,在spring-boot-autoconfigure-2.3.1.RELEASE.jar
包下的/META-INF/spring.factories
配置文件中,有一个自动配置类,是用于Servlet容器的自动配置的。
// ServletWebServerFactoryAutoConfiguration 就是嵌入式servlet容器的自动配置类
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
ServletWebServerFactoryAutoConfiguration
是嵌入式Servlet容器的自动配置类,这个类的主要作用是
创建TomcatServletWebServerFactory
工厂类,
创建TomcatServletWebServerFactoryCustomizer
定制器类,
创建FilterRegistrationBean
注册ForwardedHeaderFilter
(ForwardedHeaderFilter会从Forwarded,X-Forwarded-Host,X-Forwarded-Port或者X-Forwarded-Proto中获取跳转信息),
同时很关键的一步是注册后置处理器webServerFactoryCustomizerBeanPostProcessor
,
只要Application
类一启动,就会执行run
方法,
run经过一系列调用会通过ServletWebServerApplicationContext
的onRefresh
方法创建ioc容器,
然后通过createWebServer
方法,createWebServer方法会去ioc容器里扫描是否有对应的ServletWebServerFactory
工厂类(TomcatServletWebServerFactory
是其中一种),
扫描得到,就会触发webServerFactoryCustomizerBeanPostProcessor
后置处理器类,
这个处理器类会获取TomcatServletWebServerFactoryCustomizer
定制器,并调用customize
方法进行定制,
这时候工厂类起作用,调用getWebServer
方法进行Tomcat属性配置和引擎设置等等,
再创建TomcatWebServer启动Tomcat容器。
2 嵌入式Servlet容器启动原理(以Tomcat为例)
2.1 SpringBoot启动时,启动Tomcat的原理
主要 是 围绕
ServletWebServerApplicationContext
类进行
(1)我们启动springboot应用时,都是直接运行主程序的main
方法,然后调用里面的SpringApplication
类的run
方法。
(2)调用run方法时,会调用该类自己的 refreshContext
方法,这个方法的作用是创建IOC容器对象,并且初始化IOC容器,创建容器中的每一个组件。
(3)在该类的reflesh
方法中,再调用了ServletWebServerApplicationContext
类的 reflesh
方法,刷新刚才的IOC容器后(这个方法其实是继承AbstractApplicationContext
类的),在该方法中又调用onreflesh
方法(这个方法则是ServletWebServerApplicationContext
类重写AbstractApplicationContext
类的),最后在onreflesh
中调用createWebServer
方法,创建 WebServer对象。
(4)createWebServer
方法,该方法最终能够获取到一个与当前应用(根据我们导入的依赖来获取)所导入的Servlet类型相匹配的web服务工厂TomcatServletWebServerFactory
,通过该工厂就可以获取到相应的 WebServerFactoryCustomizer
(Web服务工厂定制器),在调用该工厂的getWebServer
方法,创建->初始化->启动Tomcat。
注:createWebServer
方法执行期间,我们其实会来到EmbeddedWebServerFactoryCustomizerAutoConfiguration
,然后根据条件(配置的依赖)配置哪一个Web服务器。
* 在SpringBoot的run启动时,会判断当前所处环境。
* 如果是Web环境则通过创建一个`ServletWebServerApplicationContext`,执行构造函数的refresh方法,
* 在refresh方法内执行onRefresh方法,执行createWebServer方法,这个方法会根据当前应用是内置还是外置发布方式来决定以何种方式获取web服务器。
* 如果是内置方式则通过`TomcatServletWebServerFactory`工厂类来获取一个首选的web服务器,然后进行服务器的初始化配置,应用加载生效以及服务器启动的操作。
2.2 嵌入式的Servlet容器工厂创建tomcat容器,初始化并启动容器
2.2.1 嵌入式Servlet容器工厂的自动配置类
ServletWebServerFactoryAutoConfiguration
// 标注这是一个配置类
@Configuration(
proxyBeanMethods = false
)
// 决定配置类的加载顺序的,当注解里的值越小越先加载
@AutoConfigureOrder(-2147483648)
// 表示当前必须有 servlet-api 依赖存在
@ConditionalOnClass({
ServletRequest.class})
// 仅仅基于Servlet的web应用程序
@ConditionalOnWebApplication(
type = Type.SERVLET
)
// 向IOC容器中添加ServerProperties组件
@EnableConfigurationProperties({
ServerProperties.class})
// 向IOC容器中注入一些组件
@Import({
ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
EmbeddedTomcat.class,
EmbeddedJetty.class,
EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
//略
}
从@Import
注解可以看到,这个配置类向容器中批量添加组件,支持添加三种web服务器(Tomcat、Jetty、Undertow),而具体要配置哪个服务器,由ServletWebServerFactoryConfiguration
决定,同时还定义了配置的顺序Tomcat>Jetty>Undertow,意思就是当环境中有Tomcat满足的依赖时就会优先使用Tomcat,依次往后推。
综合来看,ServletWebServerFactoryConfiguration
自动配置类作了以下几件事:
-
向IOC容器中添加了内部类
BeanPostProcessorsRegistrar
这个bean后置处理器注册器组件,这个组件也是向IOC容器中添加组件后置处理器,这里添加的是WebServerFactoryCustomizerBeanPostProcessor
服务器工厂的定制器的后置处理器 ,对于xxxBeanPostProcessor
来说,都是bean的后置处理器,即在bean创建完成后,在其初始化前后进行拦截处理。注册的后置处理器类WebServerFactoryCustomizerBeanPostProcessor
,在ioc容器启动的时候会调用。 -
向IOC容器中添加了
ServletWebServerFactoryConfiguration.EmbeddedTomcat
等嵌入容器相关配置(这里以 tomcat 相关的配置为例)。 -
向IOC容器中添加了
ServletWebServerFactoryCustomizer
、TomcatServletWebServerFactoryCustomizer
两个WebServerFactoryCustomizer
类型的 bean。
1> 注册后置处理器(BeanPostProcessorsRegistrar)
部分代码
// ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class
public static class BeanPostProcessorsRegistrar implements Impor