Spring Boot 启动异常:ApplicationContextException
1、概览
本文将会带你了解在 Spring Boot 启动时出现 ApplicationContextException
异常的原因,以及解决办法:
ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean
2、可能的原因
异常信息,“由于缺少 ServletWebServerFactory Bean,无法启动 ServletWebServerApplicationContext” 说明了一切。ApplicationContext
中没有配置 ServletWebServerFactory
Bean。
该异常主要出现在 Spring Boot 无法启动 ServletWebServerApplicationContext 时。为什么会这样?因为 ServletWebServerApplicationContext
使用包含的 ServletWebServerFactory
Bean 来启动自身。
一般来说,Spring Boot 通过 SpringApplication.run
方法来启动 Spring 应用。
SpringApplication
类会根据应用类型(如,Web 应用),尝试创建正确的 ApplicationContext
。
用于确定是否是 Web 应用的算法来自于一些依赖,如 spring-boot-starter-web
。缺少这些依赖,可能是导致异常的原因之一。
另一个原因是 Spring Boot 启动类中缺少 @SpringBootApplication
注解。
3、重现异常
创建一个示例应用,故意在 main 类上不添加 @SpringBootApplication
注解。
public class MainEntryPoint {
public static void main(String[] args) {
SpringApplication.run(MainEntryPoint.class, args);
}
}
启动应用,会抛出异常。如下:
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)
<strong>Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.</strong>
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: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean” 异常。
4、修复异常
修复异常的简单方法是在 MainEntryPoint
启动类上添加 @SpringBootApplication
注解。
通过此注解,告诉 Spring Boot 自动配置必要的 Bean 并将其注册到上下文中。
也可以通过禁用 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 应用运行,用于禁用 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
依赖。
由于 classpath 中存在该依赖,Spring Boot 会将该项目视为 Servlet 应用,而不是响应式 Web 应用。因此 Spring Boot 无法启动 ServletWebServerApplicationContext
。
5、总结
本文介绍了 Spring Boot 启动时出现 “ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean” 异常的原因,以及解决办法。
Ref:https://www.baeldung.com/spring-boot-application-context-exception