news 2026/6/10 15:42:45

SpringBoot Servlet 容器全解析:嵌入式配置与外置容器部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot Servlet 容器全解析:嵌入式配置与外置容器部署

在 SpringBoot Web 开发中,Servlet 容器是核心基础设施。SpringBoot 提供了两种容器使用方式:嵌入式容器(默认)和外置容器,前者便捷轻量,后者适配传统 Web 场景(如 JSP 开发)。本文将从配置、实战、原理三个维度,完整讲解嵌入式容器的定制、Servlet 三大组件注册,以及外置容器的部署流程与底层逻辑。

一、嵌入式 Servlet 容器(Jar 包方式)

嵌入式容器是 SpringBoot 的默认方式,将 Tomcat/Jetty/Undertow 内置到应用中,打成可执行 Jar 包,通过java -jar即可启动。核心优势是简单、便携,但默认不支持 JSP,精细化定制需额外配置。

1.1 定制 Servlet 容器核心配置

SpringBoot 通过ServerProperties类封装所有容器配置,支持配置文件和编程式两种方式修改,最常用的是配置文件方式。

1.1.1 配置文件定制(application.properties/yml)

直接在配置文件中通过server前缀修改容器参数,覆盖默认值:

# 基础容器配置 server.port=8081 # 服务端口(默认8080) server.context-path=/tx # 应用上下文路径(SpringBoot2.0后推荐server.servlet.context-path) server.tomcat.uri-encoding=UTF-8 # Tomcat URI编码(解决中文乱码) # Tomcat精细化配置(可选) server.tomcat.max-threads=200 # 最大工作线程数 server.tomcat.connection-timeout=20000 # 连接超时时间(毫秒)

若使用 YAML 格式,配置更易读:

server: port: 8081 servlet: context-path: /tx tomcat: uri-encoding: UTF-8 max-threads: 200 connection-timeout: 20000
1.1.2 核心配置说明
  • server.port:指定访问端口,避免端口冲突;
  • server.context-path:设置访问前缀,配置后访问地址为http://localhost:8081/tx/xxx
  • server.tomcat.*:Tomcat 专属配置,SpringBoot 对 Jetty/Undertow 也提供了对应的前缀(如server.jetty.*)。

1.2 注册 Servlet 三大组件(无 web.xml)

SpringBoot 以 Jar 包启动时无web.xml文件,需通过@Bean注解将 Servlet、Filter、Listener 注册到容器中。

1.2.1 先定义自定义组件
① 自定义 Servlet
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/html;charset=UTF-8"); resp.getWriter().write("自定义Servlet响应"); } }
② 自定义 Filter
import javax.servlet.*; import java.io.IOException; public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("MyFilter拦截请求..."); chain.doFilter(request, response); // 放行请求 } }
③ 自定义 Listener
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("Servlet容器初始化完成"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("Servlet容器销毁"); } }
1.2.2 注册组件到 Spring 容器

创建配置类,通过ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean封装组件并注册:

import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Arrays; @Configuration public class WebComponentConfig { // 1. 注册Servlet @Bean public ServletRegistrationBean<MyServlet> myServlet() { ServletRegistrationBean<MyServlet> registrationBean = new ServletRegistrationBean<>( new MyServlet(), "/myServlet"); // 拦截路径 return registrationBean; } // 2. 注册Filter @Bean public FilterRegistrationBean<MyFilter> myFilter() { FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MyFilter()); registrationBean.setUrlPatterns(Arrays.asList("/hello", "/myServlet")); // 拦截路径 return registrationBean; } // 3. 注册Listener @Bean public ServletListenerRegistrationBean<MyListener> myListener() { ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>( new MyListener()); return registrationBean; } }

1.3 DispatcherServlet 的自动注册

SpringBoot 自动配置 SpringMVC 时,会通过DispatcherServletAutoConfiguration自动注册核心前端控制器DispatcherServlet,核心逻辑如下:

@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) { ServletRegistrationBean registration = new ServletRegistrationBean( dispatcherServlet, this.serverProperties.getServletMapping()); // 默认拦截路径:/ (拦截所有请求,包含静态资源,但不拦截JSP) // /* 会拦截JSP,开发中避免使用 registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup()); return registration; }
  • 默认拦截路径为/,可通过server.servletPath修改;
  • 无需手动注册,SpringBoot 自动完成。

二、外置 Servlet 容器(War 包方式)

嵌入式容器虽便捷,但存在默认不支持 JSP、定制复杂等问题。外置容器需独立安装 Tomcat,将应用打成 War 包部署,适配传统 Web 开发场景。

2.1 嵌入式 VS 外置容器对比

特性嵌入式容器(Jar)外置容器(War)
打包方式可执行 Jar 包War 包
JSP 支持默认不支持原生支持
定制难度较高(编程式)较低(容器配置)
部署便捷性极高(java -jar)需先启动容器
适用场景微服务、小型应用传统 Web、JSP 开发

2.2 外置 Tomcat 部署完整步骤

以 IDEA + Maven 为例,演示从项目创建到部署的全流程:

步骤 1:创建 War 类型项目
  • IDEA 新建 SpringBoot 项目时,Packaging 选择 War
  • 若已有 Jar 项目,修改pom.xml<packaging>jar</packaging><packaging>war</packaging>
步骤 2:排除嵌入式 Tomcat

将嵌入式 Tomcat 标记为provided(编译时依赖,运行时由外置容器提供),避免冲突:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
步骤 3:编写 SpringBootServletInitializer 子类

外置容器无法执行main方法,需通过此类桥接 SpringBoot 应用:

import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { // 传入SpringBoot主程序类 return application.sources(SpringBoot04WebJspApplication.class); } }
步骤 4:规范项目目录结构

War 项目需符合 Java EE 标准结构,核心目录如下:

spring-boot-war-demo/ ├── src/main/java/ # 源码目录 ├── src/main/resources/ # 配置文件目录 └── src/main/webapp/ # Web根目录(Jar项目无此目录) └── WEB-INF/ # 受保护目录 └── jsp/ # JSP页面目录(可选)
步骤 5:部署并启动外置 Tomcat
  1. IDEA 中配置本地 Tomcat:「Add Configuration」→ 「Tomcat Server」→ 「Local」;
  2. 切换到「Deployment」标签,添加当前项目的 War 包;
  3. 设置「Application context」(访问前缀),启动 Tomcat 即可。

2.3 启动原理对比

① Jar 包(嵌入式容器)启动流程
执行main方法 → 启动SpringApplication → 创建IOC容器 → 初始化嵌入式Tomcat → 启动容器并提供服务

核心:应用主导,SpringBoot 启动时先创建 IOC 容器,再启动容器。

② War 包(外置容器)启动流程
启动外置Tomcat → 扫描webapps目录下的War包 → 触发SpringBootServletInitializer → 加载SpringBoot主类 → 创建IOC容器 → Tomcat提供服务

核心:容器主导,Tomcat 启动后,通过SpringBootServletInitializer加载 SpringBoot 应用。

三、总结

核心要点

  1. 嵌入式容器
    • 配置文件通过server.*定制端口、上下文路径等参数;
    • 无 web.xml 时,通过RegistrationBean注册 Servlet/Filter/Listener;
    • DispatcherServlet 由 SpringBoot 自动注册,默认拦截/路径。
  2. 外置容器
    • 需创建 War 项目,排除嵌入式 Tomcat,编写SpringBootServletInitializer子类;
    • 启动逻辑为 “容器主导”,适配 JSP、传统 Web 部署场景。
  3. 场景选择
    • 微服务、无 JSP 场景优先用嵌入式容器(Jar 包);
    • 需 JSP、精细化定制容器时用外置容器(War 包)。

通过本文的配置和原理讲解,你可根据实际场景灵活选择 Servlet 容器方式,既享受 SpringBoot 的便捷性,又能适配传统 Web 开发需求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 10:04:11

AI读脸术企业落地案例:连锁门店顾客画像系统搭建

AI读脸术企业落地案例&#xff1a;连锁门店顾客画像系统搭建 1. 为什么连锁门店需要“读懂”顾客的脸&#xff1f; 你有没有注意过&#xff0c;走进一家奶茶店&#xff0c;店员会下意识观察你是学生、上班族还是带孩子的家长&#xff1f;再比如&#xff0c;路过一家美妆专柜&…

作者头像 李华
网站建设 2026/6/10 11:30:54

springboot基于JavaWeb商品销售管理系统-开题报告

目录项目背景与意义系统功能概述技术选型优势预期成果创新点项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作项目背景与意义 随着电子商务的快速发展&#xff0c;传统商品销售管理方式效率低下、数据易丢失…

作者头像 李华
网站建设 2026/6/10 11:29:16

springboot基于JavaWeb的人事管理系统-开题报告

目录 项目背景与意义技术选型与优势系统功能模块预期成果 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 项目背景与意义 随着企业规模扩大&#xff0c;传统纸质或Excel管理人事信息效率低下&#xff0c…

作者头像 李华
网站建设 2026/6/10 11:30:38

Z-Image-Turbo实战:用简单英文描述秒出专业级壁纸

Z-Image-Turbo实战&#xff1a;用简单英文描述秒出专业级壁纸 你有没有试过——输入一句话&#xff0c;三秒后&#xff0c;一张堪比摄影大师作品的高清壁纸就出现在屏幕上&#xff1f;不是渲染十分钟等得心焦&#xff0c;不是调参半小时还黑图连连&#xff0c;而是真正“敲下回…

作者头像 李华
网站建设 2026/6/10 11:30:39

300M参数大能量!EmbeddingGemma本地部署实战指南

300M参数大能量&#xff01;EmbeddingGemma本地部署实战指南 1. 为什么你需要一个“能装进笔记本”的嵌入模型&#xff1f; 你有没有试过在自己的MacBook Air上跑一个文本嵌入服务&#xff1f;打开终端&#xff0c;输入ollama run bge-m3&#xff0c;然后等——等三分钟&…

作者头像 李华
网站建设 2026/6/10 11:23:36

OFA视觉问答模型惊艳效果:支持否定式提问如‘Is there no dog?’

OFA视觉问答模型惊艳效果&#xff1a;支持否定式提问如‘Is there no dog&#xff1f;’ 1. 为什么这个VQA模型让人眼前一亮 你有没有试过对着一张图问&#xff1a;“这张照片里没有狗吗&#xff1f;”——不是“有狗吗”&#xff0c;而是明确用否定句式提问。大多数视觉问答…

作者头像 李华