1.参照 Spring Boot 自动配置包里面的web模块
EmbeddedServletContainerAutoConfiguration 嵌入式的 Servlet 容器自动配置


- @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
- @Configuration
- @ConditionalOnWebApplication
- @Import(BeanPostProcessorsRegistrar.class)
- //导入BeanPostProcessorsRegistrar:Spring注解版;给容器中导入一些组件
- //导入了EmbeddedServletContainerCustomizerBeanPostProcessor:
- //后置处理器:bean初始化前后(创建完对象,还没赋值赋值)执行初始化工作
- public class EmbeddedServletContainerAutoConfiguration {
- .....
- @Configuration
- @ConditionalOnClass({ Servlet.class, Tomcat.class })//判断当前是否引入了Tomcat依赖;
- @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)//判断当前容器没有用户自己定义EmbeddedServletContainerFactory:嵌入式的Servlet容器工厂;作用:创建嵌入式的Servlet容器
- 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();
- }
- }
2.EmbeddedServletContainerFactory(嵌入式Servlet容器工厂)
- public interface EmbeddedServletContainerFactory {
-
- //获取嵌入式的Servlet容器
- EmbeddedServletContainer getEmbeddedServletContainer(
- ServletContextInitializer... initializers);
- }
Ctrl+H 显示继承关系:

3.EmbeddedServletContainer(嵌入式的Servlet容器)

4.以TomcatEmbeddedServletContainerFactory为例
- @Override
- public EmbeddedServletContainer getEmbeddedServletContainer(
- ServletContextInitializer... initializers) {
- //创建一个Tomcat
- Tomcat tomcat = new Tomcat();
-
- //配置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);
-
- //将配置好的Tomcat传入进去,返回一个EmbeddedServletContainer;并且启动Tomcat服务器
- return getTomcatEmbeddedServletContainer(tomcat);
- }
5.嵌入式容器的配置修改生效原理
依次向下生效:
ServerProperties
:绑定配置文件里面的属性
EmbeddedServletContainerCustomizer
:嵌入式Servlet容器的定制器,修改Servlet容器配置
EmbeddedServletContainerCustomizerBeanPostProcessor
- //初始化之前
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName)
- throws BeansException {
- //如果当前初始化的是一个ConfigurableEmbeddedServletContainer类型的组件
- if (bean instanceof ConfigurableEmbeddedServletContainer) {
- //
- postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer) bean);
- }
- return bean;
- }
- private void postProcessBeforeInitialization(
- ConfigurableEmbeddedServletContainer bean) {
- //获取所有的定制器,调用每一个定制器的customize方法来给Servlet容器进行属性赋值;
- for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {
- customizer.customize(bean);
- }
- }
- private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
- if (this.customizers == null) {
- // Look up does not include the parent context
- this.customizers = new ArrayList<EmbeddedServletContainerCustomizer>(
- this.beanFactory
- //从容器中获取所有这葛类型的组件:EmbeddedServletContainerCustomizer
- //定制Servlet容器,给容器中可以添加一个EmbeddedServletContainerCustomizer类型的组件
- .getBeansOfType(EmbeddedServletContainerCustomizer.class,
- false, false)
- .values());
- Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
- this.customizers = Collections.unmodifiableList(this.customizers);
- }
- return this.customizers;
- }
- //ServerProperties也是定制器
步骤:
1、Spring Boot 根据导入的依赖情况,给容器中添加相应的EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
2、容器中某个组件要创建对象就会惊动后置处理器;EmbeddedServletContainerCustomizerBeanPostProcessor;只要是嵌入式的 Servlet 容器工厂,后置处理器就工作;
3、后置处理器,从容器中获取所有的 EmbeddedServletContainerCustomizer,调用定制器的定制方法
本文需结合代码片段内的文字注释浏览。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。