spring-boot如何得到⼀个tomcat实例(基于spring-
boot_v2.0.。。。
spring-boot加载tomcat的过程如下:
(1) springboot的主函数有⼀个注解 @SpringBootApplication,⽽这个注解⾥有⼀个@EnableAutoConfiguration
@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 {
(2) 相⽐于1.x版本,2.x版本废弃了⾃动配置类EmbeddedServletContainerAutoConfiguration,⽽使⽤了ServletWebServerFactoryAutoConfiguration和EmbeddedWebServerFactoryCustomizerAutoConfiguration两个⾃动配置类,下⾯我们分别来介绍⼀下这两个autoConfiguration
(3) 我们先看⼀下⽐较简单的TomcatWebServerFactoryCustomizer吧
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
@Configuration
//默认使⽤tomcat,因此条件满⾜
@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
public static class TomcatWebServerFactoryCustomizerConfiguration {
// 实例化⼀个TomcatWebServerFactoryCustomizer实例bean,
//这个bean实现了WebServerFactoryCustomizer接⼝,
//它的customize⽅法负责对ConfigurableTomcatWebServerFactory进⾏配置
@Bean
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
}
// 由于 Server.class, Loader.class, WebAppContext.class
//默认情况下不存在,因此JettyWebServerFactoryCustomizerConfiguration不会⽣效
@Configuration
@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
public static class JettyWebServerFactoryCustomizerConfiguration {
@Bean
public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
}
}
// 由于Undertow.class, SslClientAuthMode.class默认情况下不存在,
// 因此UndertowWebServerFactoryCustomizerConfiguration不会⽣效
@Configuration
@ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
public static class UndertowWebServerFactoryCustomizerConfiguration {
@Bean
public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
}
}
}
(4)然后看⼀下 ServletWebServerFactoryAutoConfiguration
@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,  ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
// 实例化⼀个 ServletWebServerFactoryCustomizer,它的泛型参数是ConfigurableServletWebServerFactory  @Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(
springboot是啥
ServerProperties serverProperties) {
return new ServletWebServerFactoryCustomizer(serverProperties);
}
// 实例化⼀个TomcatServletWebServerFactoryCustomizer,它的泛型参数是TomcatServletWebServerFactory  @Bean
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
ServerProperties serverProperties) {
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
}
// 通过上⾯的@import引⼊
public static class BeanPostProcessorsRegistrar
implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
if (this.beanFactory == null) {
return;
}
//这边的处理跟v1.x版本是⼀致的,
//从beanFactory中获取⼀个WebServerFactoryCustomizerBeanPostProcessor实例bean,
//如果不存在,则主动new⼀个
registerSyntheticBeanIfMissing(registry,
"webServerFactoryCustomizerBeanPostProcessor",
WebServerFactoryCustomizerBeanPostProcessor.class);
registerSyntheticBeanIfMissing(registry,
"errorPageRegistrarBeanPostProcessor",
ErrorPageRegistrarBeanPostProcessor.class);
}
private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry,
String name, Class<?> beanClass) {
if (ObjectUtils.isEmpty(
BeanNamesForType(beanClass, true, false))) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
beanDefinition.setSynthetic(true);
}
}
}
}
ServletWebServerFactoryAutoConfiguration 主要做了四件事:
注1:通过@import引⼊ServletWebServerFactoryConfiguration的⼏个⼦类:EmbeddedTomcat、EmbeddedJetty和EmbeddedUndertow,⽽事实上最终只有EmbeddedTomcat起作⽤了,如下图,EmbeddedJetty和EmbeddedUndertow缺少依赖的java类,因此不会⽣效,⽽唯⼀⽣效的EmbeddedTomcat只做了⼀件事:实例化了⼀个TomcatServletWebServerFactory的bean,这个bean在 注4 会⽤到
注2:实例化⼀个 ServletWebServerFactoryCustomizer的bean(它实现了WebServerFactoryCustomizer接⼝),它对ConfigurableServletWebServerFactory(它继承了WebServerFactory接⼝)进⾏配置
// ServletWebServerFactoryCustomizer实现了WebServerFactoryCustomizer接⼝
// ConfigurableServletWebServerFactory继承了WebServerFactory接⼝
// 之所以强调这些,因为在注4 总会⽤到哦
public class ServletWebServerFactoryCustomizer implements
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
private final ServerProperties serverProperties;
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
@Override
public int getOrder() {
return 0;
}
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
PropertyMapper map = ().alwaysApplyingWhenNonNull();
map.from(this.serverProperties::getPort).to(factory::setPort);
map.from(this.serverProperties::getAddress).to(factory::setAddress);
map.from(Servlet()::getContextPath)
.to(factory::setContextPath);
map.from(Servlet()::getApplicationDisplayName)
.to(factory::setDisplayName);
map.from(Servlet()::getSession).to(factory::setSession);
map.from(this.serverProperties::getSsl).to(factory::setSsl);
map.from(Servlet()::getJsp).to(factory::setJsp);
map.from(this.serverProperties::getCompression).to(factory::setCompression);
map.from(this.serverProperties::getHttp2).to(factory::setHttp2);
map.from(this.serverProperties::getServerHeader).to(factory::setServerHeader);
map.from(Servlet()::getContextParameters)
.to(factory::setInitParameters);
}
注3:实例化⼀个 TomcatServletWebServerFactoryCustomizer的bean,它对TomcatServletWebServerFactory(它是WebServerFactory的⼀个实现类)进⾏配置

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。