1. 概述

在本快速教程中,我们将仔细研究Spring Boot错误“ ApplicationContextException:由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext ”。

首先,我们将阐明此错误背后的主要原因。然后,我们将深入研究如何使用实际示例来重现它,最后如何解决它。

2. 可能原因

首先,让我们尝试了解错误消息的含义。 “ 由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext ” 说明了一切。它只是告诉我们 ApplicationContext 中没有配置 ServletWebServerFactory bean

该错误主要出现在 Spring Boot 无法启动 ServletWebServerApplicationContext 时。为什么? 因为 ServletWebServerApplicationContext 使用包含的 ServletWebServerFactory bean 来引导自身。

一般来说,Spring Boot 提供 SpringApplication.run 方法来引导 Spring 应用程序。

SpringApplication 类将尝试为我们创建正确的 ApplicationContext具体取决于我们是否正在开发 Web 应用程序

例如,用于确定 Web 应用程序是否来自某些依赖项(例如 spring-boot-starter-web)的算法。 话虽如此,缺乏这些依赖关系可能是我们错误背后的原因之一。

另一个原因是 Spring Boot 入口点类中缺少 @SpringBootApplication 注解。

3. 重现错误

现在,让我们看一个可以产生 Spring Boot 错误的示例。实现这一点的最简单方法是 创建一个不带 @SpringBootApplication 注解的主类

首先,让我们创建一个入口点类,并故意忘记用 @SpringBootApplication 注释它:

public class MainEntryPoint {

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

现在,让我们运行示例 Spring Boot 应用程序,看看会发生什么:

22:20:39.134 [main] ERROR o.s.boot.SpringApplication - Application run failed
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 com.baeldung.applicationcontextexception.MainEntryPoint.main(MainEntryPoint.java:10)
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)
    ... 

如上所示,我们得到“ ApplicationContextException:由于缺少ServletWebServerFactory bean而无法启动ServletWebServerApplicationContext ”错误。

4. 修复错误

修复错误的简单解决方案是使用 @SpringBootApplication 注释 *.* 注释我们的 MainEntryPoint

通过使用此注释, 我们告诉 Spring Boot 自动配置必要的 bean 并将它们注册到 context 中

同样,我们可以通过禁用 Web 环境来避免非 Web 应用程序的错误。为此,我们可以使用 spring.main.web-application-type 属性。

application.properties 中:

spring.main.web-application-type=none

同样,在我们的 application.yml 中:

spring: 
    main: 
        web-application-type: none

none 表示应用程序不应作为 Web 应用程序运行。它用于禁用网络服务器

请记住,从Spring Boot 2.0开始,我们还可以使用 SpringApplicationBuilder 显式定义特定类型的 Web 应用程序:

@SpringBootApplication
public class MainClass {

    public static void main(String[] args) {
        new SpringApplicationBuilder(MainClass.class)
          .web(WebApplicationType.NONE)
          .run(args);
    }
}

对于WebFlux 项目,我们可以使用 WebApplicationType.REACTIVE 另一个解决方案可能是排除 spring-webmvc 依赖项。

类路径中存在的这种依赖关系告诉 Spring Boot 将项目视为 servlet 应用程序,而不是响应式 Web 应用程序。结果*,* Spring Boot 无法启动 ServletWebServerApplicationContext

5. 结论

在这篇短文中,我们详细讨论了导致 Spring Boot 在启动时失败并出现以下错误的原因:“ ApplicationContextException: 由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext ”。

一路上,我们通过一个实际的例子解释了如何产生错误以及如何修复它。

与往常一样,示例的完整源代码可在 GitHub 上获取。