gateway网关启动报错 uable to start web server; nested exception is org.springframework.context.Application

9 篇文章 0 订阅
9 篇文章 0 订阅

gateway网关启动报错

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

找不到bean服务

 看网上很多教程说是因为缺少web依赖,但是发现依赖的父依赖中都包含了

 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-web</artifactId>
 </dependency>

 <dependency>
    <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
 </dependency>

所以解决办法是排除父依赖中的如上两个依赖

<dependency>
    <groupId>com.XX.project</groupId>
    <artifactId>parent</artifactId>
    <version>2.0.4-SNAPSHOT</version>
    <exclusions>
        <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

但是启动的时候发现还是报错

所以加上spring-boot-web的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

之后发现又报另外一个错误

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-09-17 16:53:20.207 ERROR 2752 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.

Action:

Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.

二、问题分析

从报错内容上来看是找不到ServletWebServerFactory这个bean导致的错误。从Spring Framework 5.0开始,引入的新的响应式Web框架(Spring WebFlux),与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞。Spring Cloud Gateway 运用了响应式编程(WebFlux),因此它需要依赖于Servlet API,但是启动的时候为什么还是去找Servlet呢?百思不得其解。
 

按照报错信息在yml中spring: main: web-application-type: reactive就成功了

spring:
  main:
    web-application-type: reactive

划重点:

1.在pom文件中引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.在yml文件中加上

spring: main: web-application-type: reactive


知识点:

WebApplicationType 的三种启动方式的描述

我们一般采用的是SERVLET。

public enum WebApplicationType {

	/**
	 * 不启动内嵌的WebServer,不是运行web application
	 */
	NONE,

	/**
	 * 启动内嵌的基于servlet的web server
	 */
	SERVLET,

	/**
	 * 启动内嵌的reactive web server,这个application是一个reactive web application
	 */
	REACTIVE;
    
    private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
			"org.springframework.web.context.ConfigurableWebApplicationContext" };

	private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";

	private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";

	private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";

	private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";

	private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";

    
    static WebApplicationType deduceFromClasspath() {
        // 尝试加载org.springframework.web.reactive.DispatcherHandler,如果成功并且加载org.springframework.web.servlet.DispatcherServlet和org.glassfish.jersey.servlet.ServletContainer失败,则这个application是WebApplicationType.REACTIVE类型。
		if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
				&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
			return WebApplicationType.REACTIVE;
		}
		for (String className : SERVLET_INDICATOR_CLASSES) {
            // 如果ClassLoader里面同时加载这两个 javax.servlet.Servlet和 org.springframework.web.context.ConfigurableWebApplicationContext成功。则application是WebApplicationType.NONE 类型。
			if (!ClassUtils.isPresent(className, null)) { 
				return WebApplicationType.NONE;
			}
		}
        // application是 WebApplicationType.SERVLET 类型。
		return WebApplicationType.SERVLET;
	}

	static WebApplicationType deduceFromApplicationContext(Class<?> applicationContextClass) {
		if (isAssignable(SERVLET_APPLICATION_CONTEXT_CLASS, applicationContextClass)) {
			return WebApplicationType.SERVLET;
		}
		if (isAssignable(REACTIVE_APPLICATION_CONTEXT_CLASS, applicationContextClass)) {
			return WebApplicationType.REACTIVE;
		}
		return WebApplicationType.NONE;
	}
  1. WebApplicationType.REACTIVE  classpath下存在org.springframework.web.reactive.DispatcherHandler

  2. WebApplicationType.SERVLET classpath下存在javax.servlet.Servlet或者org.springframework.web.context.ConfigurableWebApplicationContext

  3. WebApplicationType.NONE 不满足以上条件。

推荐看一下这篇博客

彻底找到Spring Webflux与WebMVC 冲突原因_努力码农的博客-CSDN博客_webflux和webmvc共存 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值