您现在的位置是:首页 > 技术教程 正文

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

admin 阅读: 2024-03-29
后台-插件-广告管理-内容页头部广告(手机)

一、问题

在启动springcloud的gateway模块的时候报错Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.

二、问题产生的原因

gateway组件中的 spring-boot-starter-webflux 和 springboot作为web项目启动必不可少的 spring-boot-starter-web 出现冲突。

三、解决方案(任选一种就可以)

3.1 注释pom.xml内容

在gateway的pom文件上注释掉spring-boot-starter-web代码

  1.         <dependency>
  2. <groupId>org.springframework.bootgroupId>
  3. <artifactId>spring-boot-starter-webartifactId>
  4. dependency>

3.2修改配置文件

在配置文件上加上

  1. spring:
  2. main:
  3. web-application-type: reactive

解释:这里面涉及到springboot的启动流程因为spring-boot-starter-webflux包,在springboot启动类型里面表示的就是reactive。我们可以看源码,了解一下springboot启动流程

一步一步点进去

这是springApplication构造方法,我们先看构造方法

点进去

3.2.1通过springboot源码解释

springApplication构造源码(不同版本会有差异,当前版本是2.6.1)

  1. public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
  2.        
  3. this.sources = new LinkedHashSet();
  4.         // 在控制台打印banner.txt文本内容
  5. this.bannerMode = Mode.CONSOLE;
  6. this.logStartupInfo = true;
  7. this.addCommandLineProperties = true;
  8. this.addConversionService = true;
  9. this.headless = true;
  10. this.registerShutdownHook = true;
  11. this.additionalProfiles = Collections.emptySet();
  12. this.isCustomEnvironment = false;
  13. this.lazyInitialization = false;
  14. this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
  15. this.applicationStartup = ApplicationStartup.DEFAULT;
  16.         // 开始输resourceLoader注入了属性null
  17. this.resourceLoader = resourceLoader;
  18. Assert.notNull(primarySources, "PrimarySources must not be null");
  19.         //将启动类从数组重新封装Set,注入到primarySources当中
  20. this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
  21.         /**
  22.           *webApplicationType有三种类型,REACTIVE,SERVLET,NONE
  23.           *  引入spring-boot-starter-web就是SERVLET
  24.           *  引入spring-boot-starter-webflux就是REACTIVE
  25.           *  没有就是NONE
  26.         */
  27. this.webApplicationType = WebApplicationType.deduceFromClasspath();
  28.         /**
  29.           *从spring-cloud-context的jar包的META-INF/spring.factories文件中得到key为org.springfra          *mework.boot.BootstrapRegistryInitializer的全类名集合,进行实例化,然后注入 bootstrapRegi
  30.           *stryInitializers 属性,其中核心方法getSpringFactoriesInstances
  31.           *下面有getSpringFactoriesInstances方法源码详解
  32.           *这里简单的解释一下getSpringFactoriesInstances方法就是从META-INF/spring.factories读取配
  33.           *置文件           
  34.           */
  35. this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
  36.         /**
  37.           *依然调用getSpringFactoriesInstances方法
  38.           *从spring-boot的jar包的META-INF/spring.factories文件中得到key为org.springframework.        *context.ApplicationContextInitializer的全类名集合,然后进行实例化,然后注入initializers
  39.           *(初始化容器集合)属性 
  40.           */
  41. this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
  42.         //跟上面一样,这里是得到监听器的集合,并注入
  43. this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
  44.         //获取当前的main方法运行的类,也就是我们的主类
  45. this.mainApplicationClass = this.deduceMainApplicationClass();
  46. }

上面说的META-INF/spring.factories都是在springboot.jar包中,不过BootstrapRegistryInitializer是在spring-cloud-context中。

3.2.2了解getSpringFactoriesInstances方法

随便选一个点进去

  1. private Collection getSpringFactoriesInstances(Class type, Class<?>[] parameterTypes, Object... args) {
  2. ClassLoader classLoader = this.getClassLoader();
  3.         /** SpringFactoriesLoader.loadFactoryNames(type, classLoader)这里才是核心,
  4.           *这个方法会扫描所有jar包类路径下 META-INF/spring.factories
  5.           */
  6. Set names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
  7. List instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
  8. AnnotationAwareOrderComparator.sort(instances);
  9. return instances;
  10. }
标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜