Установите Spring.main.web-application-type=reactive или удалите зависимость Spring-boot-starter-web.

1. Проблема

При запуске модуля шлюза Springcloud возникает ошибка. Установите Spring.main.web-application-type=reactive или удалите зависимость Spring-boot-starter-web.

2. Причины проблемы

Компонент шлюзаspring-boot-starter-webflux и Springboot необходимы для запуска веб-проектов Spring-boot-starter-web Произошел конфликт.

3. Решение (просто выберите любое)

3.1 Комментирование содержимого pom.xml

В pom-файле шлюзаЗакомментируйтеspring-boot-starter-webкод а>

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

3.2 Изменение файла конфигурации

Добавляем в файл конфигурации

spring:
    main:
        web-application-type: reactive

Объяснение: Это включает процесс запуска Springboot, посколькуspring-boot-starter-webflux Package, представленный в типе запуска Springboot, является реактивным. Мы можем посмотреть исходный код, чтобы понять процесс запуска Springboot

Нажмите шаг за шагом

Это метод построения SpringApplication. Давайте сначала рассмотрим метод построения.

Нажмите

3.2.1 Объяснение через исходный код Springboot

Исходный код конструкции SpringApplication (В разных версиях будут различия, текущая версия – 2.6.1)

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

Все упомянутые выше META-INF/spring.factories находятся в пакете Springboot.jar, но BootstrapRegistryInitializer находится в контексте Spring-cloud.

3.2.2 Понимание метода getSpringFactoriesInstances

Просто выберите любую точку и заходите

  private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        /** SpringFactoriesLoader.loadFactoryNames(type, classLoader)这里才是核心,
          *这个方法会扫描所有jar包类路径下 META-INF/spring.factories
          */
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

Guess you like

Origin blog.csdn.net/qq_36138652/article/details/128947605