WebServer的自动装配
Springboot处理一次http请求时需要依赖WebServer,本次研究也是基于如下的父Pom。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
创建这个项目时,我仅仅就是引入了web模块。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Springboot为我们自动内嵌了webServer。在server的选择上自动配置的方案上有三种选择,如下图可见TomcatServletWebServerFactory的Conditional条件是存在Servelet、Tomcat和UpgradeProtocol类,环境也不存在ServletWebServerFactory类型的bean。这样会自动注册生产TomcatServer实例的Bean工厂。反观其他两种服务容器Jetty和UnderTow,Conditional条件就不满足。
Tomcat何时实例化和启动?
在分析springboot项目启动过程中我们知道(不知道的可以从org.springframework.boot.SpringApplication#run开始debug,你会收获很大:)!),作为web应用在SpringApplication构造函数中,会确定WebApplicationType为org.springframework.boot.WebApplicationType#SERVLET,这个也是在run方法中用来创建应用容器时默认选择容器类型的参数。
补充:Tomcat内部容器大致分为Engine、Host、Context和Wrapper。这四个容器之间是父子关系,Engine容器包含Host,Host包含Context,Context包含Wrapper。层层调用,最终调用Wrapper,Wrapper的具体调用方法invoke中其实是为request创建ApplicationFilterChain,在这个过滤器链中调用servlet.service方法。(invoke方法很长,以后可以深究)。