使用其他Servlet容器
-Jetty(长连接)
-Undertow(不支持jsp)
替换为其他嵌入式Servlet容器
默认支持:
Tomcat(默认使用)
Jetty:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <!--引入其他的Servlet --> <dependency> <artifactId>spring‐boot‐starter‐jetty</artifactId> <groupId>org.springframework.boot</groupId> </dependency>
Undertow:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <!--引入其他的Servlet --> <dependency> <artifactId>spring‐boot‐starter‐undertow<</artifactId> <groupId>org.springframework.boot</groupId> </dependency>
右键排除依赖
嵌入式Servlet配置原理:
Servelt容器的自动配置类
@Configuration @ConditionalOnWebApplication @EnableConfigurationProperties({ServerProperties.class}) public class EmbeddedWebServerFactoryCustomizerAutoConfiguration { public EmbeddedWebServerFactoryCustomizerAutoConfiguration() { } @Configuration @ConditionalOnClass({HttpServer.class}) public static class NettyWebServerFactoryCustomizerConfiguration { public NettyWebServerFactoryCustomizerConfiguration() { } @Bean public NettyWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { return new NettyWebServerFactoryCustomizer(environment, serverProperties); } } @Configuration @ConditionalOnClass({Undertow.class, SslClientAuthMode.class}) public static class UndertowWebServerFactoryCustomizerConfiguration { public UndertowWebServerFactoryCustomizerConfiguration() { } @Bean public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { return new UndertowWebServerFactoryCustomizer(environment, serverProperties); } } @Configuration @ConditionalOnClass({Server.class, Loader.class, WebAppContext.class}) public static class JettyWebServerFactoryCustomizerConfiguration { public JettyWebServerFactoryCustomizerConfiguration() { } @Bean public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { return new JettyWebServerFactoryCustomizer(environment, serverProperties); } } @Configuration @ConditionalOnClass({Tomcat.class, UpgradeProtocol.class}) public static class TomcatWebServerFactoryCustomizerConfiguration { public TomcatWebServerFactoryCustomizerConfiguration() { } @Bean public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { return new TomcatWebServerFactoryCustomizer(environment, serverProperties); } } }
Tomcat 的Server的定制(Jetty、Netty、Undertow 类似)
TomcatWebServerFactoryCustomizer.java
public class TomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered { private final Environment environment; private final ServerProperties serverProperties; public TomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { this.environment = environment; this.serverProperties = serverProperties; } public int getOrder() { return 0; } public void customize(ConfigurableTomcatWebServerFactory factory) { ServerProperties properties = this.serverProperties; Tomcat tomcatProperties = properties.getTomcat(); PropertyMapper propertyMapper = PropertyMapper.get(); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getBasedir).whenNonNull().to(factory::setBaseDirectory); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull().as(Duration::getSeconds).as(Long::intValue).to(factory::setBackgroundProcessorDelay); this.customizeRemoteIpValve(factory); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxThreads).when(this::isPositive).to((maxThreads) -> { this.customizeMaxThreads(factory, tomcatProperties.getMaxThreads()); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive).to((minSpareThreads) -> { this.customizeMinThreads(factory, minSpareThreads); }); propertyMapper.from(this::determineMaxHttpHeaderSize).whenNonNull().asInt(DataSize::toBytes).when(this::isPositive).to((maxHttpHeaderSize) -> { this.customizeMaxHttpHeaderSize(factory, maxHttpHeaderSize); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull().asInt(DataSize::toBytes).to((maxSwallowSize) -> { this.customizeMaxSwallowSize(factory, maxSwallowSize); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxHttpPostSize).asInt(DataSize::toBytes).when((maxHttpPostSize) -> { return maxHttpPostSize != 0; }).to((maxHttpPostSize) -> { this.customizeMaxHttpPostSize(factory, maxHttpPostSize); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getAccesslog).when(Accesslog::isEnabled).to((enabled) -> { this.customizeAccessLog(factory); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getUriEncoding).whenNonNull().to(factory::setUriEncoding); properties.getClass(); propertyMapper.from(properties::getConnectionTimeout).whenNonNull().to((connectionTimeout) -> { this.customizeConnectionTimeout(factory, connectionTimeout); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxConnections).when(this::isPositive).to((maxConnections) -> { this.customizeMaxConnections(factory, maxConnections); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getAcceptCount).when(this::isPositive).to((acceptCount) -> { this.customizeAcceptCount(factory, acceptCount); }); this.customizeStaticResources(factory); this.customizeErrorReportValve(properties.getError(), factory); } ....... }
步骤:
1)、SpringBoot根据导入的依赖情况,给容器中添加相应的
EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
2)、容器中某个组件要创建对象就会惊动后置处理器;
EmbeddedServletContainerCustomizerBeanPostPro
只要是嵌入式的Servlet容器工厂,后置处理器就工作;
3)、后置处理器,从容器中获取所有的EmbeddedServletContainerCustomizer,调
用定制器的定制方法
嵌入式Servlet容器启动原理;
什么时候创建嵌入式的Servlet容器工厂?什么时候获取嵌入式的Servlet容器并启动Tomcat;
获取嵌入式的Servlet容器工厂:
断点
1)、SpringBoot应用启动运行run
2)、refreshContext(context);SpringBoot刷新IOC容器【创建IOC容器对象,并初始化容器
创建容器中的每一个组件】
3)、refresh(context);刷新刚才创建好的ioc容器
private void refreshContext(ConfigurableApplicationContext context) { this.refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException var3) { ; } } }
4)、 onRefresh(); web的ioc容器重写了onRefresh方法
5)、webioc容器会创建嵌入式的Servlet容器;ServletWebServerApplicationContext(
6)、获取嵌入式的Servlet容器工厂
7)、使用容器工厂获取嵌入式的Servlet容器
8)、嵌入式的Servlet容器创建对象并启动Servlet容
先启动嵌入式的Servlet容器,再将ioc容器中剩下没有创建出的对象获取出来;
IOC容器启动创建嵌入式的Servlet容器