背景
最近要做一些Web容器(Tomcat
、Jetty
、Undertow
)相关的线程池监听以及动态配置,所以借此机会就研究了一下Spring Boot Web容器的自动装配过程
Spring Boot 版本
2.4.2
入口
熟悉Spring Boot
Spi机制的同学就不会知道Spring Boot
自动装配的起点spring.factories
这个文件
可以看到装配了一个ServletWebServerFactoryAutoConfiguration
类
ServletWebServerFactoryAutoConfiguration
进入ServletWebServerFactoryAutoConfiguration
我们就看到又通过@Import
注解导入了三个我们熟悉的Bean:
- EmbeddedTomcat
- EmbeddedJetty
- EmbeddedUndertow
这里有点奇怪的是为啥Jetty的JettyServletWebServerFactory要用大写开头哈哈
可以看到他们都有条件注解,只有在指定的Class存在才会加载,这也就是我们添加了比如Jetty依赖,他会自动装配使用Jetty服务器的原因装载的三个Bean分别是
- TomcatServletWebServerFactory
- JettyServletWebServerFactory
- UndertowServletWebServerFactory
而这三个Bean都是继承AbstractServletWebServerFactory
同时这三个xxxServletWebServerFactory
都实现了ServletWebServerFactory
接口
然后再通过ServletWebServerApplicationContext
加载不同的ServletWebServerFactory
其中在getWebServerFactory()
又会调用一个比较核心的方法就是WebServerFactoryCustomizer
接口的customize()
用来对容器做一些定制化配置
至于Tomcat
线程池是在哪里创建的呢
调用入口是哪里呢 主要还是ServletWebServerApplicationContext
中的refresh()
方法
总结
总的来说是通过Spring Boot 的SPI机制加载了配置类ServletWebServerFactoryAutoConfiguration
,然后配置类通过不同的class加载不同的ServletWebServerFactory
而容器启动后会获取ServletWebServerFactory
,然后通过WebServerFactoryCustomizer
作一些同期的定制化配置。同时在ServletWebServerApplicationContext
的 refresh()
方法中创建Tomcat线程池。大致原理就是这样,后续有机会可以继续深入研究