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

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法