我们一起学学嵌入式Web容器

网站建设4年前发布
67 0 0

开始之前呢,我们带着几个问题去学习:,1、Spring Boot 嵌入式Web容器是什么?,2、整体流程或结构是怎样的?,3、核心部分是什么?,4、怎么实现的?,在当今的互联网场景中,与终端用户交互的应用大多数是 Web 应用,其中 Java Web 应用尤为突出,其对应的 Java Web 容器发展至今也分为 Servlet Web 容器和 Reactive Web 容器,前者的使用率大概占比是百分之九十左右,其具体的实现有 Tomcat、Jetty 和 Undertow;而后者出现较晚,且技术栈体系并未完全成熟,还有待时间验证可行性,它的默认实现为 Netty Web Server。其中的 Servlet 规范与三种 Servlet 容器的版本关系如下:,以上 Web 容器均被 Spring Boot 嵌入至其中作为其核心特性,来简化 Spring Boot 应用启动流程。Spring Boot 通过 Maven 依赖来切换应用的嵌入式容器类型,其对应的 Maven jar 分别是:,前三者是 Servlet Web 实现,最后则是 Reactive Web 的实现。值得注意的是,当我们引用的是 Servlet Web 功能模块时,它会自动集成 Tomcat ,里面包含了 Tomcat 的 Maven 依赖包,也就是说 Tomcat 是默认的 Servlet Web 容器。Servlet Web 模块的 Maven 依赖如下:,而如果引用的是 Reactive Web 功能模块时,则会默认集成 netty Web Server 。Reactive Web 模块的依赖如下:,不过,上面的三种 Servlet Web 容器也能作为 Reactive Web 容器 ,并允许替换默认实现 Netty Web Server,因为 Servlet 3.1+容器同样满足 Reactive 异步非阻塞特性。,接下来,我们重点讨论嵌入式 Web 容器的启动流程。,Spring Boot 嵌入式容器启动时会先判断当前的应用类型,是 Servlet Web 还是 Reactive Web ,之后会创建相应类型的 ApplicationContext 上下文,在该上下文中先获取容器的工厂类,然后利用该工厂类创建具体的容器。接下来,我们进行详细讨论。,从 Spring Boot 启动类开始:,先来看看,获取应用类型的过程,进入 run 的重载方法:,以上,在 SpringApplication 的构造阶段确定了当前应用的类型,该类型名称存储在 webApplicationType 字段中。,接着进入容器启动流程,进入重载的 run 方法中:,AbstractApplicationContext 是 Spring 应用上下文的核心启动类,Spring 的 ioc 从这里就开始进入创建流程。在后续在 Spring 系列的文章中会进行详细讨论,我们这里只关注容器创建的部分。,这里以 Servlet web 为例,具体上下文对象是
AnnotationConfigServletWebServerApplicationContext,该类实现了 ServletWebServerApplicationContext 类,onRefresh 方法由该类进行重写。,TomcatServletWebServerFactory 是创建 Tomcat 的 Web 容器工厂类,但这个工厂类是如何被创建的呢?这里将会在文章的第三部分进行详细讨论。,TomcatWebServer 是具体的容器对象,在其对应的工厂类中进行创建,其实现了 WebServer 接口,并在该对象中进行 Tomcat 的启动流程。,到这里,Web 容器的启动流程就结束了,以上是以 Servlet Web 及其具体的 Tomcat 容器为例子进行的讨论,这也是大部分开发者常用的体系。接着来对整个过程做一个总结。,上面说过, Web 容器对象是由其对应的工厂类进行创建的,那容器工厂类又是怎么创建呢?我们这里就来看一看。在《Spring Boot 自动装配(二)》的 1.2 小节说过, Spring Boot 启动时,会读取所有 jar 包中 META-INF 文件夹下的 spring.factories 文件,并加载文件中定义好的类,如:,其中有一个
ServletWebServerFactoryAutoConfiguration 类:,该类通过 @Import 导入了
ServletWebServerFactoryConfiguration 中的三个内部类,这三个内部类就是用来创建容器工厂,我们进入其中查看具体实现:,可以看到,主要是通过引入相应 Web 容器的 Maven 依赖,来判断容器对应的 Class 是否存在,存在则创建相应的容器工厂类。,最后,来对 Spring Boot 嵌入式 Web 容器做一个整体的总结。Spring Boot 支持的两大 Web 容器体系,一个是 Servlet Web ,另一个是 Reactive Web ,它们都有其具体的容器实现,相信大多数开发者使用的都是前者,且最常用的容器实现也是 Tomcat,所以这篇文章主要讨论的也是 Spring Boot 启动 Tomcat 嵌入式容器的流程。

© 版权声明

相关文章