跟踪springboot自启动tomcat
工作需要修改内置tomcat连接参数,将自己分析前后分享。
springboot 内置tomcat,tomcat为自动开启的配置,进入@SpringBootApplication注解。
@Target (ElementType.TYPE)
@Retention (RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan (excludeFilters = {
@Filter (type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter (type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
@SuppressWarnings ("deprecation" )
@Target (ElementType.TYPE)
@Retention (RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import (EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
springboot原理,就是使用SpingFactoriesLoader.loadFactoryNames 扫描具有META-INFO/spring.factories文件的jar包 。
加载容器的配置文件 EmbeddedServletContainerAutoConfiguration,在配置文件中,内置tomcat(满足tomcat容器条件的bean存在),只要满足Jetty、Undertow的条件,可以切换为其他容器。
@AutoConfigureOrder (Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication
@Import (BeanPostProcessorsRegistrar.class)
public class EmbeddedServletContainerAutoConfiguration {
/**
* Nested configuration if Tomcat is being used.
*/
@Configuration
@ConditionalOnClass ({ Servlet.class, Tomcat.class })
@ConditionalOnMissingBean (value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedTomcat {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory () {
return new TomcatEmbeddedServletContainerFactory();
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration
@ConditionalOnClass ({ Servlet.class, Server.class, Loader.class,
WebAppContext.class })
@ConditionalOnMissingBean (value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedJetty {
@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory () {
return new JettyEmbeddedServletContainerFactory();
}
}
/**
* Nested configuration if Undertow is being used.
*/
@Configuration
@ConditionalOnClass ({ Servlet.class, Undertow.class, SslClientAuthMode.class })
@ConditionalOnMissingBean (value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedUndertow {
@Bean
public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory () {
return new UndertowEmbeddedServletContainerFactory();
}
}
以tomcat为例,继续看如何加载并配置servlet容器 TomcatEmbeddedServletContainerFactory 获取容器
@Override
public EmbeddedServletContainer getEmbeddedServletContainer (
ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (this .baseDirectory != null ? this .baseDirectory
: createTempDir("tomcat" ));
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this .protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false );
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this .additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatEmbeddedServletContainer(tomcat);
}
继续跟踪查看customizeConnector(connector);
查看此方法源码 所以有两种方式可以实现个性化的connector
1.继承 TomcatEmbeddedServletContainerFactory 重写此方法,加入个性化配置
2.实现TomcatConnectorCustomizer 接口,将实现类加入到TomcatEmbeddedServletContainerFactory
for (TomcatConnectorCustomizer customizer : this .tomcatConnectorCustomizers) {
customizer.customize(connector);
}
public void addConnectorCustomizers (
TomcatConnectorCustomizer... tomcatConnectorCustomizers) {
Assert.notNull(tomcatConnectorCustomizers,
"TomcatConnectorCustomizers must not be null" );
this .tomcatConnectorCustomizers.addAll(Arrays.asList(tomcatConnectorCustomizers));
}
TomcatConnectorCustomizer 自定义个性化connector(实现此类后,将实现类接入到factory中即可)
public interface TomcatConnectorCustomizer {
/**
* Customize the connector.
* @param connector the connector to customize
*/
void customize(Connector connector);
}