StackTraces
Spring Boot已验证

Spring Boot missing ServletWebServerFactory bean

@debug_master32 天前更新阅读 6 min00

这个异常的本质是:Spring Boot 判断应用是 Web 应用,决定启动 ServletWebServerApplicationContext,但容器里没有一个能生成 Web 服务器的 ServletWebServerFactory bean。要么少了 spring-boot-starter-web,要么主类缺了 @SpringBootApplication,要么它本就不该当 Web 应用跑。

Issue & Env(案发现场与环境)

  • 现象:应用启动到一半直接失败,控制台报 ApplicationContextException,进程退出。
  • 环境:Spring Boot 2.x / 3.x。常见于写批处理、CLI 工具却引进了 Web 依赖,或单元测试没开启自动配置。

StackTrace(堆栈日志)

标准启动失败堆栈:

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:596)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1307)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1296)
	at com.example.demo.MainEntryPoint.main(MainEntryPoint.java:12)
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:209)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:158)
	... 9 more

Reproduce(复现代码)

主类漏写 @SpringBootApplication,SpringApplication.run 找不到自动配置入口:

public class MainEntryPoint {
    public static void main(String[] args) {
        SpringApplication.run(MainEntryPoint.class, args);
    }
}

运行后就会在启动阶段抛上面那段异常。

Root Cause(根因分析)

SpringApplication 启动时,会先根据 classpath 推断应用类型:有 servlet 相关类就当作 SERVLET,有响应式就当作 REACTIVE,都没有就是 NONE。一旦推断成 SERVLET,它会创建 ServletWebServerApplicationContext。这个上下文要启动内嵌容器,必须先从容器里拿到一个 ServletWebServerFactory bean。

正常 Web 应用里,@SpringBootApplication 的自动配置会根据 spring-boot-starter-web 注册一个 TomcatServletWebServerFactory。三条路都会让这个 bean 缺失:

  1. 主类缺 @SpringBootApplication,自动配置根本没启动。
  2. classpath 有 servlet API 或 spring-webmvc,却没带 spring-boot-starter-web。典型是批处理、CLI 项目被动引进了 Web 相关依赖,被误判成 Web 应用。
  3. 测试里用了 @SpringBootTest 或 @ContextConfiguration,但只加载了局部配置类,没触发自动配置。

The Fix(解决方案)

Web 应用就该有 Web 依赖和主类注解。检查两件事:主类补上 @SpringBootApplication;pom.xml 里确认有 spring-boot-starter-web。

非 Web 应用(批处理、定时任务、CLI),明确告诉 Spring Boot 别启动 Web 服务器:

spring.main.web-application-type=none

或 YAML 写法:

spring:
  main:
    web-application-type: none

测试场景,给配置类或测试类补上 @EnableAutoConfiguration,或手动提供一个 ServletWebServerFactory bean。最省事的是让 @SpringBootTest 走完整自动配置,而不是只拼少数几个配置类。

References(参考来源)

最后更新于 2026-09-09

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法