SpringBoot嵌入Tomcat原理
内嵌Tomcat启动原理
- 首先,来到启动SpringBoot项目的地方,也就是朱配置类.
@SpringBootApplication
public class InakiApplication {
public static void main(String[] args) {
SpringApplication.run(InakiApplication.class, args);
}
}
- 点击@SpringBootApplication注解,进入
- 上图中使用**@Import注解对AutoConfigurationImportSelector** 类进行了引入,该类做了什么 事情呢?进入源码,首先调用**selectImport()**方法,在该方法中调用了 **getAutoConfigurationEntry()方法,在之中又调用了getCandidateConfigurations()**方法, getCandidateConfigurations()方法就去META-INF/spring.factories配置文件中加载相关配置类。
META-INF/spring.factories: SpringBoot的SPI机制。SpringBoot在启动的时候会扫描所有该名称的文件,拿到所有需要自动装配的类,对其进行扫描。
META-INF/spring.factories在spring-boot-autoconfiguration:XXX.release包中
继续查看改配置类的org.springframework.boot.autoconfigure.EnableAutoConfiguration的值
tomcat服务器的自动配置类就是这个ServletWebServerFactoryAutoConfigutation,点击进入该类。
- 首先看下该类的注释
Auto-configuration for servlet web servers.
翻译:servlet web 服务器的自动配置
-
继续看下该类的注解
进入该类,里面也通过@Import注解将EmbeddedTomcat、EmbeddedJetty、 EmbeddedUndertow等嵌入式容器类加载进来了,springboot默认是启动嵌入式tomcat容器, 如果要改变启动jetty或者undertow容器 -
看下EnableConfigurationProperties这个注解中的ServerProperties类
// 去配置文件中找以server开头的配置信息
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
/**
* 设置服务器 端口号
*/
private Integer port;
/**
* 设置web服务器 地址
*/
private InetAddress address;
这也就验证了我们为什么要在application.properties/application.yml文件中配置server.port、server.address就会生效的原因。
- 我们点击进入EmbeddedTomcat这个类
主要看tomcatServletWebServerFactory这个方法
@Configuration(proxyBeanMethods = false)
class ServletWebServerFactoryConfiguration {
// 该类生效必须满足@ConditionalOnClass和@ConditionalOnMissingBean注解中所声明的条件
// @Con@ConditionalOnMissingBeanditionalOnClass,由于我们导入了tomcat的依赖包,所有上下文中肯定存在这三个类
// @ConditionalOnMissingBean, 上下文中不存在ServletWebServerFactory类
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({
Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedTomcat {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
// 1. 创建tomcatwebServer 工厂
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
// 以下几个方法都是设置tomcatwebServeFactory的属性值
factory.getTomcatConnectorCustomizers()
.addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));
factory