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 上获取。