34

我在 maven pom 中使用spring-boot并添加了spring-web依赖项,以利用RestTemplate.

现在 spring 尝试初始化一个EmbeddedServletContext. 我该如何预防?

Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
    ... 8 more
4

5 回答 5

36

供参考:此用例记录在Spring Boot 参考指南中:

并非所有 Spring 应用程序都必须是 Web 应用程序(或 Web 服务)。如果你想在一个main方法中执行一些代码,同时还要引导一个 Spring 应用程序来设置要使用的基础设施,那么使用SpringApplicationSpring Boot 的特性就很容易了。A根据它是否认为它需要一个 Web 应用程序来SpringApplication更改它的类。ApplicationContext您可以做的第一件事就是将 servlet API 依赖项从类路径中移除。如果您不能这样做(例如,您正在从同一代码库运行 2 个应用程序),那么您可以显式调用SpringApplication.setWebEnvironment(false)或设置applicationContextClass属性(通过 Java API 或使用外部属性)。您希望作为业务逻辑运行的应用程序代码可以实现为 aCommandLineRunner并作为 a 放入上下文中@Bean定义。

应用程序属性:

spring.main.web-environment=false   #webEnvironment property
于 2015-04-22T14:40:20.840 回答
28

第一个技巧:

public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
                .web(false)
                .run(args);
}

第二:

@Configuration
@EnableAutoConfiguration(exclude = WebMvcAutoConfiguration.class)
public class Application {
于 2015-04-22T14:32:48.250 回答
16

尽管禁用 Web 环境的传统方式(如@Tim 的回答中所述)在 Spring Boot 2.x 中仍然有效,但是新的首选方式是设置以下属性

spring.main.web-application-type=none

是定义允许值的枚举

于 2017-10-04T15:44:18.940 回答
14

这适用于 Spring Boot 2.x

public static void main(String[] args) {
   new SpringApplicationBuilder(MyApplication.class)
            .web(WebApplicationType.NONE)
            .build()
            .run(args);
}
于 2018-04-25T10:39:19.717 回答
4

我试图用 Spring Boot 2.06 构建一个反应式 Web 应用程序并得到这个错误:

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 org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at com.vogella.springboot2.Test3Application.main(Test3Application.java:10) [main/:na]
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:204) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    ... 8 common frames omitted

这个链接解释了这个问题,并提供了两个建议:

https://vividcode.io/Fixing-Spring-Boot-error-Unable-to-start-ServletWebServerApplicationContext-due-to-missing-ServletWebServerFactory-bean/

我正在使用 Spring Boot 构建一个新的 Spring WebFlux 应用程序。从start.spring.io下载项目模板后,我添加了一些第三方依赖并尝试启动应用程序。然后我遇到了错误 org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean....

错误消息是解决方案的线索。它说无法启动 ServletWebServerApplicationContext,但我的项目使用的是 WebFlux,它是一个响应式 Web 项目,而不是基于 servlet 的 Spring Web MVC 项目。

调试 Spring 源代码帮助我找到了原因。在 org.springframework.boot.SpringApplication 的方法 deuceWebApplicationType 中,只有当 CLASSPATH 中不存在 Spring Web MVC 的类时,Web 应用程序类型才设置为 WebApplicationType.REACTIVE。

一旦确定了根本原因,解决方案就很容易了。我们可以:

更新 Maven 依赖项以排除 spring-webmvc,或者将 web 应用程序类型显式设置为 WebApplicationType.REACTIVE,如下所示。

@SpringBootApplication class MyApplication
fun main(args: Array<String>) {
    val app = SpringApplication(MyApplication::class.java)
    app.webApplicationType = WebApplicationType.REACTIVE
    app.run(*args)
}

不幸的是,这些解决方案都不适合我。相反,我调整了 geoand 的响应,并将其添加到我的application.properties

spring.main.web-application-type=reactive

瞧!问题解决了!

于 2018-10-27T23:50:59.590 回答