Перейти к основному содержимому

Ошибка загрузки Spring ApplicationContextException

· 3 мин. чтения

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 .