1 SpringBoot支持的容器
Tomcat:
默认使用
Jetty:
长连接,eg:聊天系统
Undertow:
不支持jsp
高性能,非阻塞
2 将默认容器设为jetty
<?xml version="1.0" encoding="UTF-8"?>
< project xmlns = " http://maven.apache.org/POM/4.0.0" xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation= " http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
< modelVersion> 4.0.0</ modelVersion>
< groupId> com.springboot</ groupId>
< artifactId> springboot-21</ artifactId>
< version> 0.0.1-SNAPSHOT</ version>
< packaging> jar</ packaging>
< name> springboot-21</ name>
< description> Demo project for Spring Boot</ description>
< parent>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-parent</ artifactId>
< version> 2.1.0.RELEASE</ version>
< relativePath/>
</ parent>
< properties>
< project.build.sourceEncoding> UTF-8</ project.build.sourceEncoding>
< project.reporting.outputEncoding> UTF-8</ project.reporting.outputEncoding>
< java.version> 1.8</ java.version>
</ properties>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-web</ artifactId>
< exclusions>
< exclusion>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-tomcat</ artifactId>
</ exclusion>
</ exclusions>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-jetty</ artifactId>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-test</ artifactId>
< scope> test</ scope>
</ dependency>
</ dependencies>
< build>
< plugins>
< plugin>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-maven-plugin</ artifactId>
</ plugin>
</ plugins>
</ build>
</ project>
3 嵌入式Servlet容器自动配置原理
@Configuration
@AutoConfigureOrder ( - 2147483648 )
@ConditionalOnClass ( { ServletRequest. class } )
@ConditionalOnWebApplication (
type = Type. SERVLET
)
@EnableConfigurationProperties ( { ServerProperties. class } )
@Import ( { ServletWebServerFactoryAutoConfiguration. BeanPostProcessorsRegistrar. class , EmbeddedTomcat. class , EmbeddedJetty. class , EmbeddedUndertow. class } )
public class ServletWebServerFactoryAutoConfiguration {
. . .
}
EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class
@Configuration
class ServletWebServerFactoryConfiguration {
ServletWebServerFactoryConfiguration ( ) {
}
@Configuration
@ConditionalOnClass ( { Servlet. class , Undertow. class , SslClientAuthMode. class } )
@ConditionalOnMissingBean (
value = { ServletWebServerFactory. class } ,
search = SearchStrategy. CURRENT
)
public static class EmbeddedUndertow {
public EmbeddedUndertow ( ) {
}
@Bean
public UndertowServletWebServerFactory undertowServletWebServerFactory ( ) {
return new UndertowServletWebServerFactory ( ) ;
}
}
@Configuration
@ConditionalOnClass ( { Servlet. class , Server. class , Loader. class , WebAppContext. class } )
@ConditionalOnMissingBean (
value = { ServletWebServerFactory. class } ,
search = SearchStrategy. CURRENT
)
public static class EmbeddedJetty {
public EmbeddedJetty ( ) {
}
@Bean
public JettyServletWebServerFactory JettyServletWebServerFactory ( ) {
return new JettyServletWebServerFactory ( ) ;
}
}
@Configuration
@ConditionalOnClass ( { Servlet. class , Tomcat. class , UpgradeProtocol. class } )
@ConditionalOnMissingBean (
value = { ServletWebServerFactory. class } ,
search = SearchStrategy. CURRENT
)
public static class EmbeddedTomcat {
public EmbeddedTomcat ( ) {
}
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory ( ) {
return new TomcatServletWebServerFactory ( ) ;
}
}
}
TomcatServletWebServerFactory
public WebServer getWebServer ( ServletContextInitializer. . . initializers) {
Tomcat tomcat = new Tomcat ( ) ;
File baseDir = this . baseDirectory != null ? this . baseDirectory : this . createTempDir ( "tomcat" ) ;
tomcat. setBaseDir ( baseDir. getAbsolutePath ( ) ) ;
Connector connector = new Connector ( this . protocol) ;
tomcat. getService ( ) . addConnector ( connector) ;
this . customizeConnector ( connector) ;
tomcat. setConnector ( connector) ;
tomcat. getHost ( ) . setAutoDeploy ( false ) ;
this . configureEngine ( tomcat. getEngine ( ) ) ;
Iterator var5 = this . additionalTomcatConnectors. iterator ( ) ;
while ( var5. hasNext ( ) ) {
Connector additionalConnector = ( Connector) var5. next ( ) ;
tomcat. getService ( ) . addConnector ( additionalConnector) ;
}
this . prepareContext ( tomcat. getHost ( ) , initializers) ;
return this . getTomcatWebServer ( tomcat) ;
}
4 嵌入式容器的配置修改原理
4.1 通过application.properties修改
org.springframework.boot.autoconfigure.web.ServerProperties
4.2 通过WebServerFactoryCustomizer修改
org.springframework.boot.web.server.ConfigurableWebServerFactory
5 BeanPostProcessorsRegistrar(后置处理器)
public void registerBeanDefinitions ( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if ( this . beanFactory != null) {
this . registerSyntheticBeanIfMissing ( registry, "webServerFactoryCustomizerBeanPostProcessor" , WebServerFactoryCustomizerBeanPostProcessor. class ) ;
this . registerSyntheticBeanIfMissing ( registry, "errorPageRegistrarBeanPostProcessor" , ErrorPageRegistrarBeanPostProcessor. class ) ;
}
}
WebServerFactoryCustomizerBeanPostProcessor
public Object postProcessBeforeInitialization ( Object bean, String beanName) throws BeansException {
if ( bean instanceof WebServerFactory ) {
this . postProcessBeforeInitialization ( ( WebServerFactory) bean) ;
}
return bean;
}
private void postProcessBeforeInitialization ( WebServerFactory webServerFactory) {
( ( Callbacks) LambdaSafe. callbacks ( WebServerFactoryCustomizer. class , this . getCustomizers ( ) , webServerFactory, new Object [ 0 ] ) . withLogger ( WebServerFactoryCustomizerBeanPostProcessor. class ) ) . invoke ( ( customizer) - > {
customizer. customize ( webServerFactory) ;
} ) ;
}
private void postProcessBeforeInitialization (
ConfigurableEmbeddedServletContainer bean) {
for ( EmbeddedServletContainerCustomizer customizer : getCustomizers ( ) ) {
customizer. customize ( bean) ;
}
}
private Collection< WebServerFactoryCustomizer< ? >> getCustomizers ( ) {
if ( this . customizers == null) {
this . customizers = new ArrayList ( this . getWebServerFactoryCustomizerBeans ( ) ) ;
this . customizers. sort ( AnnotationAwareOrderComparator. INSTANCE) ;
this . customizers = Collections. unmodifiableList ( this . customizers) ;
}
return this . customizers;
}
private Collection< WebServerFactoryCustomizer< ? >> getWebServerFactoryCustomizerBeans ( ) {
return this . beanFactory. getBeansOfType ( WebServerFactoryCustomizer. class , false , false ) . values ( ) ;
}
6 总结
1: 自动配置类生效ServletWebServerFactoryAutoConfiguration,根据依赖添加嵌入式容器工厂TomcatServletWebServerFactory
2: 容器中组件创建对象时,会调用后置处理器,WebServerFactoryCustomizerBeanPostProcessor
3: 后置处理器,从容器中获取所有的WebServerFactoryCustomizer.class,调用定制器的定制方法