1. Обзор
В этом кратком руководстве мы подробно рассмотрим ошибку Spring Boot « ApplicationContextException: невозможно запустить ServletWebServerApplicationContext из-за отсутствия bean-компонента ServletWebServerFactory
».
Прежде всего, мы собираемся пролить свет на основные причины этой ошибки. Затем мы углубимся в то, как воспроизвести его на практическом примере, и, наконец, как его решить.
2. Возможные причины
Во-первых, давайте попробуем понять, что означает сообщение об ошибке. « Невозможно запустить ServletWebServerApplicationContext из-за отсутствия bean-компонента ServletWebServerFactory
» говорит само за себя. Он просто говорит нам, что в ApplicationContext
нет настроенного bean-компонента ServletWebServerFactory
.
`` ``
Ошибка возникает в основном, когда Spring Boot не удается запустить ServletWebServerApplicationContext
. Почему? Поскольку ServletWebServerApplicationContext
использует содержащийся bean-компонент ServletWebServerFactory
для самозагрузки.
Как правило, Spring Boot предоставляет метод SpringApplication.run
для начальной загрузки приложений Spring.
Класс SpringApplication
попытается создать для нас правильный ApplicationContext в
зависимости от того, разрабатываем мы веб-приложение или нет .
Например, алгоритм, используемый для определения того, исходит ли веб-приложение от некоторых зависимостей, таких как spring-boot-starter-web.
При этом отсутствие этих зависимостей может быть одной из причин нашей ошибки.
Другой причиной может быть отсутствие аннотации @SpringBootApplication
в классе точки входа Spring Boot.
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.foreach.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: невозможно запустить ServletWebServerApplicationContext из-за отсутствия bean-компонента ServletWebServerFactory
».
4. Исправление ошибки
Простым решением исправить нашу ошибку было бы аннотировать наш класс MainEntryPoint
аннотацией @SpringBootApplication
.
Используя эту аннотацию, мы сообщаем Spring Boot о необходимости автоматической настройки необходимых bean-компонентов и регистрации их в контексте .
Точно так же мы можем избежать ошибки для не-веб-приложений, отключив веб-среду. Для этого мы можем использовать свойство spring.main.web-application-type
.
В application.properties
:
spring.main.web-application-type=none
Аналогично в нашем application.yml
:
spring:
main:
web-application-type: none
none
означает, что приложение не должно работать как веб-приложение. Он используется для отключения веб-сервера .
Имейте в виду, что, начиная с Spring Boot 2.0 , мы также можем использовать SpringApplicationBuilder
для явного определения определенного типа веб-приложения:
@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 рассматривать проект как приложение сервлета, а не как реактивное веб-приложение. В результате Spring Boot не может
запустить ServletWebServerApplicationContext
.
5. Вывод
В этой короткой статье мы подробно обсудили, что вызывает сбой Spring Boot при запуске с этой ошибкой: « ApplicationContextException: невозможно запустить ServletWebServerApplicationContext из-за отсутствия bean-компонента ServletWebServerFactory
».
Попутно мы объяснили на практическом примере, как вызвать ошибку и как ее исправить.
Как всегда, полный исходный код примеров доступен на GitHub .