本文结论
源码基于spring boot2.6.6
项目的pom.xml中存在spring-boot-starter-web的时候,在项目启动时候就会自动启动一个Tomcat。
自动配置类ServletWebServerFactoryAutoConfiguration找到系统中的所有web容器。我们以tomcat为主。
构建TomcatServletWebServerFactory的bean。
SpringBoot的启动过程中,会调用核心的refresh方法,内部会执行onRefresh()方法,onRefresh()方法是一个模板方法,他会执行会执行子类ServletWebServerApplicationContext的onRefresh()方法。
onRefresh()方法中调用getWebServer启动web容器。
spring-boot-starter-web内部有什么?
在spring-boot-starter-web这个starter中,其实内部间接的引入了spring-boot-starter-tomcat这个starter,这个spring-boot-starter-tomcat又引入了tomcat-embed-core依赖,所以只要我们项目中依赖了spring-boot-starter-web就相当于依赖了Tomcat。
自动配置类:ServletWebServerFactoryAutoConfiguration
在spring-boot-autoconfigure-2.6.6.jar这个包中的spring.factories文件内,配置了大量的自动配置类,其中就包括自动配置tomcat的自动配置类:ServletWebServerFactoryAutoConfiguration
自动配置类的代码如下
ServletRequest是存在于tomcat-embed-core-9.0.60.jar中的的一个类,所以@ConditionalOnClass(ServletRequest.clas s)会满足。
spring-boot-starter-web中,间接的引入了spring-web、spring-webmvc等依赖,所以@ConditionalOnWebApplication(type = Type.SERVLET)条件满足。
上面的俩个条件都满足,所以spring回去解析这个配置类,在解析过程中会发现他import了三个类!我们重点关注EmbeddedTomcat。其他俩个的内部条件注解不满足!
对于另外的EmbeddedJetty和EmbeddedUndertow,逻辑类似,都是判断项目依赖中是否有Jetty和Undertow的依赖,如果有,那么对应在Spring容器中就会存在JettyServletWebServerFactory类型的Bean、或者存在UndertowServletWebServerFactory类型的Bean。
TomcatServletWebServerFactory的作用:获取WebServer对象
TomcatServletWebServerFactory他实现了ServletWebServerFactory这个接口。
ServletWebServerFactory接口内部只有一个方法是获取WebServer对象。
WebServer拥有启动、停止、获取端口等方法,就会发现WebServer其实指的就是Tomcat、Jetty、Undertow。
而TomcatServletWebServerFactory就是用来生成Tomcat所对应的WebServer对象,具体一点就是TomcatWebServer对象,并且在生成TomcatWebServer对象时会把Tomcat给启动起来。
在源码中,调用TomcatServletWebServerFactory对象的getWebServer()方法时就会启动Tomcat。
spring boot启动的时候启动tomcat
SpringBoot的启动过程中,会调用核心的refresh方法,内部会执行onRefresh()方法,onRefresh()方法是一个模板方法,他会执行会执行子类ServletWebServerApplicationContext的onRefresh()方法。
这个方法会调用createWebServer()方法。
getWebServerFactory控制项目组有且只能有一个web容器!
获取tomcat的配置
自动配置类ServletWebServerFactoryAutoConfiguration上除了import三个web容器,还import了BeanPostProcessorsRegistrar。
BeanPostProcessorsRegistrar实现了ImportBeanDefinitionRegistrar,所以他会在spring启动的时候调用registerBeanDefinitions方法。
registerBeanDefinitions会注册一个Bean:webServerFactoryCustomizerBeanPostProcessor。
webServerFactoryCustomizerBeanPostProcessor实现了BeanPostProcessor,所以他会在启动的时候调用postProcessBeforeInitialization方法。
postProcessBeforeInitialization中会调用WebServerFactoryCustomizer类customize方法,在系统中的唯一实现:ServletWebServerFactoryCustomizer的customize方法。
customize把配置中的内容设置到ConfigurableServletWebServerFactory对象中。他的实现TomcatServletWebServerFactory在启动的时候就会有值!
ServletWebServerFactoryCustomizer这个Bean是哪里的?
在我们自动配置类ServletWebServerFactoryAutoConfiguration中定义。
标签: # Tomcat
留言评论