SpringBoot——嵌入式Servlet容器自动配置原理以及启动原理

本文详细介绍了SpringBoot中嵌入式Servlet容器(如Tomcat)的自动配置和启动原理,包括自动配置类如何注册后置处理器、创建定制器并初始化容器,以及启动过程中对Tomcat的配置和启动流程。通过分析Spring Boot不同版本的差异,展示了SpringBoot如何根据依赖创建并启动Tomcat服务器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

版本说明:

  • Spring Boot 2.x 版本:嵌入式Servlet容器自动配置是通过 WebServerFactoryCustomizer定制器 来定制的;
  • Spring Boot 1.x 版本:是通过 EmbeddedServletContainerCustomizer 嵌入式的Servlet容器定制器来定制的。

SpringBoot官方文档
Embedded Web Servers
Embedded Servlet Container Support

参考博客https://cloud.tencent.com/developer/article/1551867

0 嵌入式Servlet容器自动配置原理以及启动原理的步骤

步骤:

  • SpringBoot 启动时,根据导入的依赖信息,自动创建对应的 WebServerFactoryCustomizer(web服务工厂定制器);

  • WebServerFactoryCustomizerBeanPostProcessor(web服务工厂定制器组件的后置处理器)获取所有类型为web服务工厂定制器的组件(包含实现WebServerFactoryCustomizer接口,自定义的定制器组件),依次调用customize方法,定制Servlet容器配置;

  • 嵌入式的Servlet容器工厂创建Tomcat容器,初始化并启动容器。

1 嵌入式Servlet容器自动配置原理(以Tomcat为例)

1.1 简单介绍

SpringBoot默认使用Tomcat作为嵌入式的Servlet容器,
这里所谓的嵌入式服务器就是,SpringBoot使用 apache组织 提供的Tomcat的API来配置和定制Tomcat服务。

SpringBoot在启应用动时都会加载各个jar包下的/META-INF/spring.factories文件,读取其中的org.springframework.boot.autoconfigure.EnableAutoConfiguration类型的所有自动配置类,从而达到自动配置的效果。

而我们的servlet容器的自动配置也是从这个配置文件着手,在spring-boot-autoconfigure-2.3.1.RELEASE.jar包下的/META-INF/spring.factories配置文件中,有一个自动配置类,是用于Servlet容器的自动配置的。

// ServletWebServerFactoryAutoConfiguration 就是嵌入式servlet容器的自动配置类
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\

ServletWebServerFactoryAutoConfiguration是嵌入式Servlet容器的自动配置类,这个类的主要作用是
创建TomcatServletWebServerFactory工厂类,
创建TomcatServletWebServerFactoryCustomizer定制器类,
创建FilterRegistrationBean注册ForwardedHeaderFilter(ForwardedHeaderFilter会从Forwarded,X-Forwarded-Host,X-Forwarded-Port或者X-Forwarded-Proto中获取跳转信息),
同时很关键的一步是注册后置处理器webServerFactoryCustomizerBeanPostProcessor

只要Application类一启动,就会执行run方法,
run经过一系列调用会通过ServletWebServerApplicationContextonRefresh方法创建ioc容器

然后通过createWebServer方法,createWebServer方法会去ioc容器里扫描是否有对应的ServletWebServerFactory工厂类(TomcatServletWebServerFactory是其中一种),

扫描得到,就会触发webServerFactoryCustomizerBeanPostProcessor后置处理器类,
这个处理器类会获取TomcatServletWebServerFactoryCustomizer定制器,并调用customize方法进行定制,

这时候工厂类起作用,调用getWebServer方法进行Tomcat属性配置和引擎设置等等,
创建TomcatWebServer启动Tomcat容器

2 嵌入式Servlet容器启动原理(以Tomcat为例)

2.1 SpringBoot启动时,启动Tomcat的原理

主要 是 围绕 ServletWebServerApplicationContext 类进行

(1)我们启动springboot应用时,都是直接运行主程序的main方法,然后调用里面的SpringApplication类的run方法。

(2)调用run方法时,会调用该类自己的 refreshContext 方法,这个方法的作用是创建IOC容器对象,并且初始化IOC容器,创建容器中的每一个组件。

(3)在该类的reflesh方法中,再调用了ServletWebServerApplicationContext类的 reflesh 方法,刷新刚才的IOC容器后(这个方法其实是继承AbstractApplicationContext类的),在该方法中又调用onreflesh 方法(这个方法则是ServletWebServerApplicationContext类重写AbstractApplicationContext类的),最后在onreflesh中调用createWebServer方法,创建 WebServer对象。

(4)createWebServer方法,该方法最终能够获取到一个与当前应用(根据我们导入的依赖来获取)所导入的Servlet类型相匹配的web服务工厂TomcatServletWebServerFactory,通过该工厂就可以获取到相应的 WebServerFactoryCustomizer (Web服务工厂定制器),在调用该工厂的getWebServer方法,创建->初始化->启动Tomcat

注:createWebServer方法执行期间,我们其实会来到EmbeddedWebServerFactoryCustomizerAutoConfiguration,然后根据条件(配置的依赖)配置哪一个Web服务器。

* 在SpringBoot的run启动时,会判断当前所处环境。

* 如果是Web环境则通过创建一个`ServletWebServerApplicationContext`,执行构造函数的refresh方法,

* 在refresh方法内执行onRefresh方法,执行createWebServer方法,这个方法会根据当前应用是内置还是外置发布方式来决定以何种方式获取web服务器。

* 如果是内置方式则通过`TomcatServletWebServerFactory`工厂类来获取一个首选的web服务器,然后进行服务器的初始化配置,应用加载生效以及服务器启动的操作。

2.2 嵌入式的Servlet容器工厂创建tomcat容器,初始化并启动容器

2.2.1 嵌入式Servlet容器工厂的自动配置类

ServletWebServerFactoryAutoConfiguration

// 标注这是一个配置类
@Configuration(
    proxyBeanMethods = false
)
// 决定配置类的加载顺序的,当注解里的值越小越先加载
@AutoConfigureOrder(-2147483648)
// 表示当前必须有 servlet-api 依赖存在
@ConditionalOnClass({
   ServletRequest.class})
// 仅仅基于Servlet的web应用程序
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
// 向IOC容器中添加ServerProperties组件
@EnableConfigurationProperties({
   ServerProperties.class})
// 向IOC容器中注入一些组件
@Import({
   ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,  
            EmbeddedTomcat.class, 
            EmbeddedJetty.class, 
            EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
   
    //略
}

@Import注解可以看到,这个配置类向容器中批量添加组件,支持添加三种web服务器(Tomcat、Jetty、Undertow),而具体要配置哪个服务器,由ServletWebServerFactoryConfiguration决定,同时还定义了配置的顺序Tomcat>Jetty>Undertow,意思就是当环境中有Tomcat满足的依赖时就会优先使用Tomcat,依次往后推。

综合来看,ServletWebServerFactoryConfiguration 自动配置类作了以下几件事:

  • 向IOC容器中添加了内部类 BeanPostProcessorsRegistrar 这个bean后置处理器注册器组件,这个组件也是向IOC容器中添加组件后置处理器,这里添加的是 WebServerFactoryCustomizerBeanPostProcessor服务器工厂的定制器的后置处理器 ,对于xxxBeanPostProcessor来说,都是bean的后置处理器,即在bean创建完成后,在其初始化前后进行拦截处理。注册的后置处理器类WebServerFactoryCustomizerBeanPostProcessor,在ioc容器启动的时候会调用。

  • 向IOC容器中添加了 ServletWebServerFactoryConfiguration.EmbeddedTomcat 等嵌入容器相关配置(这里以 tomcat 相关的配置为例)。

  • 向IOC容器中添加了ServletWebServerFactoryCustomizerTomcatServletWebServerFactoryCustomizer 两个WebServerFactoryCustomizer 类型的 bean。

1> 注册后置处理器(BeanPostProcessorsRegistrar)

部分代码

// ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class
public static class BeanPostProcessorsRegistrar implements Impor
### Spring Boot 自动装配原理详解 #### 工作机制概述 Spring Boot 的自动装配是一种基于条件的配置机制,它能够根据项目类路径(classpath)中的依赖项和运行时环境动态创建并注册所需的 Bean。这种机制的核心在于 `@EnableAutoConfiguration` 注解,该注解默认由 `@SpringBootApplication` 提供[^5]。 当应用程序启动时,Spring Boot 会扫描类路径下的所有可用依赖,并尝试匹配预定义的一系列自动化配置规则。这些规则存储在 `spring-boot-autoconfigure` 包中,具体表现为一系列带有特定注解(如 `@ConditionalOnClass`, `@ConditionalOnMissingBean` 等)的 Java 配置类[^2]。 --- #### 核心实现流程 以下是自动装配的主要工作流程: 1. **加载元数据文件** 当应用启动时,Spring Boot 会在类路径下寻找名为 `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` 的文件。此文件列出了所有可能参与自动装配的候选配置类[^3]。 2. **解析条件注解** 对于每一个候选配置类,Spring Boot 将评估其上的条件注解。只有满足指定条件的配置类才会被激活。常见的条件注解包括但不限于: - `@ConditionalOnClass`: 只有当某些类存在于类路径上时才启用。 - `@ConditionalOnMissingBean`: 如果容器中不存在某个类型的 Bean,则自动注入相应的实例。 - `@ConditionalOnProperty`: 根据配置属性的存在与否决定是否启用某功能。 3. **注册 Bean 定义** 经过上述筛选后,符合条件的配置类会被用来初始化对应的 Bean 并将其加入到 Spring IoC 容器中。整个过程完全透明化,开发者只需引入必要的 Starter 即可完成大部分基础设置[^1]。 4. **优先级控制** 不同场景之间可能存在冲突或者重叠的情况,因此 Spring Boot 设计了一套完善的优先级处理方案来确保最终结果符合预期需求。例如,在 Web 开发领域,默认情况下嵌入式 Servlet 容器 (Tomcat) 被选为主服务器;但如果用户手动指定了其他替代品,则后者将取代前者成为实际使用的组件。 --- #### 示例代码展示 下面是一个简单的例子展示了如何利用 Spring Boot 的自动装配特性快速搭建 RESTful API 接口服务端点: ```java // 主程序入口 @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } // 控制层示例 @RestController @RequestMapping("/api") public class HelloController { @GetMapping("/hello") public String sayHello() { return "Hello from Auto Configuration!"; } } ``` 在这个案例里,我们并没有显式声明任何关于 DispatcherServlet 或者视图解析器之类的复杂设定——这一切都得益于内置框架所提供的智能化支持体系结构。 --- #### 最佳实践建议 为了充分利用好这项技术优势,这里给出几点推荐做法: - 明确区分通用型与定制化的部分界限; - 使用 Profile 功能针对不同部署目标调整行为表现; - 结合 Actuator 插件监控线上状态以便及时发现问题所在位置等等。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值