Spring Boot 中嵌入式 Servlet 容器自动配置原理解析

网友投稿 319 2022-09-16


Spring Boot 中嵌入式 Servlet 容器自动配置原理解析

目录1.参照 Spring Boot 自动配置包里面的web模块2.EmbeddedServletContainerFactory(嵌入式Servlet容器工厂)3.EmbeddedServletContainer(嵌入式的Servlet容器)4.以TomcatEmbeddedServletContainerFactory为例5.嵌入式容器的配置修改生效原理

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.EmbedfkgMbkdedServletContainer(嵌入式的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 getCustomizers() {

if (this.customizers == null) {

// Look up does not include the parent context

this.customizers = new ArrayList(

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,调用定制器的定制方法

本文需结合代码片段内的文字注释浏览。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:HuaWei ❀ MPLS对TTL的处理(华为mate40pro)
下一篇:HuaWei ❀ MPLS的转发(华为mate40pro)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~