2.0之前 EmbeddedServletContainerCustomizerAutoConfiguration
2.0之后
EmbeddedWebServerFactoryCustomizerAutoConfiguration
ServletWebServerFactoryAutoConfiguration
嵌入式Servlet容器自动配置
1)EmbeddedWebServerFactoryCustomizerAutoConfiguration
判断容器中引入的依赖 来导入不容的Servlet容器
主要引入了ServerProperties.class 配置文件类
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({ServerProperties.class})//配置文件类
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
//Tomcat为例
@Configuration
@ConditionalOnClass({Tomcat.class, UpgradeProtocol.class})//判断当前是否引入了Tomcat依赖
public static class TomcatWebServerFactoryCustomizerConfiguration {
public TomcatWebServerFactoryCustomizerConfiguration() {
}
//配置tomcat的主要信息
//包含remoteIpValue、connector(最大/最小可接收线程、最大可接收头部大小等等)、uriEncoding、connectionTimeout、maxConnection等属性
@Bean
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
}
2)ServletWebServerFactoryAutoConfiguration
具体的Servlet容器的配置
@Configuration
@AutoConfigureOrder(-2147483648)
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
//BeanPostProcessorsRegistrar.class 给容器中导入一些组件
//导入了WebServerFactoryCustomizerBeanPostProcessor.class
//BeanPostProcessor 后置处理器 :bean初始化前后(刚创建完对象,还没属性赋值) 执行初始化工作
public class ServletWebServerFactoryAutoConfiguration {
//主要配置tomcat的servlet的信息,
//包含端口、上下文路径、应用名、Session配置、Servlet携带的初始变量等等
//他是继承WebServerFactoryCustomizer的 也就是上一个博客说的个性化定制配置信息的时候提到的
@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
return new ServletWebServerFactoryCustomizer(serverProperties);
}
// 配置tomcat的额外信息
//redirectContextRoot(是否在请求根上下文时转发,true则转发路径为/demoWeb/)和useRelativeRedirects(是否使用相对路径)等路径跳转问题处理
@Bean
@ConditionalOnClass(
name = {"org.apache.catalina.startup.Tomcat"}
)
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
}
TomcatWebServerFactoryCustomizer
ServletWebServerFactoryCustomizer
TomcatServletWebServerFactoryCustomizer
这三个类基本完成了Tomcat的配置,他们都是WebServerFactoryCustomizer的实现类,
那么谁来统一调用以完成上述的配置呢?
- 引入了WebServerFactory工厂类,创建了TomcatServletWebServerFactory的tomcat容器
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
//上边 EmbeddedTomcat.class
@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();
}
}
- 通过beanPostProcessor接口来完成相应的容器初始化,
注册了webServerFactoryCustomizerBeanPostProcessor类来完成相应的tomcat个性化配置
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
//上边ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class
public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
public BeanPostProcessorsRegistrar() {
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
}
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (this.beanFactory != null) {
this.registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", WebServerFactoryCustomizerBeanPostProcessor.class);
this.registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor", ErrorPageRegistrarBeanPostProcessor.class);
}
}
private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class<?> beanClass) {
if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
beanDefinition.setSynthetic(true);
registry.registerBeanDefinition(name, beanDefinition);
}
}
}
WebServerFactoryCustomizerBeanPostProcessor:
public class WebServerFactoryCustomizerBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
private ListableBeanFactory beanFactory;
private List<WebServerFactoryCustomizer<?>> customizers;
public WebServerFactoryCustomizerBeanPostProcessor() {
}
public void setBeanFactory(BeanFactory beanFactory) {
Assert.isInstanceOf(ListableBeanFactory.class, beanFactory, "WebServerCustomizerBeanPostProcessor can only be used with a ListableBeanFactory");
this.beanFactory = (ListableBeanFactory)beanFactory;
}
//调用所有实现了WebServerFactoryCustomizer接口的对象 可能会包含自己定制的
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebServerFactory) {
this.postProcessBeforeInitialization((WebServerFactory)bean);
}
return bean;
}
// // 查找当前bean工厂中所有类型为WebServerFactoryCustomizer接口对象集合
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
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 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();
}
}
步骤:
- SpringBoot根据导入依赖情况 ,给容器中添加相应的嵌入式工厂
- ServletWebServerFactoryAutoConfiguration
ServletWebServerFactoryCustomizer 和 TomcatServletWebServerFactoryCustomizer 配置其他配置 - WebServerFactoryCustomizerBeanPostProcessor 后置处理器
从容器中获取所有的ConfigurableListableBeanFactory
有有有有有点儿乱 就是简单了解以下
嵌入式Servlet容器启动原理
什么时候创建嵌入式的Servlet容器工厂 什么时候获取嵌入式的Servlet容器并启动Tomcat
- SpringBoot应用启动运行run方法
- refreshContext 刷新IOC容器【创建IOC容器对象 并初始化容器 创建容器中每一个组件】
- refresh刷新刚才创建的IOC容器
- onRefresh();web的ioc容器 重写了onRefresh方法
- WEB IOC容器创建嵌入式Servlet容器 createEmbededServletContainer
6.获取嵌入式Servlet容器工厂 这个工厂就是上边自动注入放进去的 - Servlet容器工厂创建了 就会配置相关配置 然后会触发后置处理器 ,后置处理器会获取所有定制器 定制Servlet相关配置
- 容器工厂获取完 用容器工厂获取嵌入式的Servlet容器
- 嵌入式Servlet容器创建Tocmat对象 并启动
先启动嵌入式Servlet容器 再将IOC容器中剩下没有创建的对象获取出来