关于Spring Cloud Gateway网关运行前的环境检查

GatewayClassPathWarningAutoConfiguration配置类

@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore(GatewayAutoConfiguration.class)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
public class GatewayClassPathWarningAutoConfiguration {

    private static final Log log = LogFactory.getLog(GatewayClassPathWarningAutoConfiguration.class);

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    protected static class SpringMvcFoundOnClasspathConfiguration {

        public SpringMvcFoundOnClasspathConfiguration() {
            throw new MvcFoundOnClasspathException();
        }

    }

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler")
    protected static class WebfluxMissingFromClasspathConfiguration {

        public WebfluxMissingFromClasspathConfiguration() {
            log.warn(BORDER + "Spring Webflux is missing from the classpath, "
                    + "which is required for Spring Cloud Gateway at this time. "
                    + "Please add spring-boot-starter-webflux dependency." + BORDER);
        }

    }

}

从上面的配置类中我们可以看到,该配置类默认是生效的,切实在Gateway网关主配置类生效之前被注册,其中又有两个内部配置类,都有各自的生效条件,先看第一个内部配置类:

SpringMvcFoundOnClasspathConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
protected static class SpringMvcFoundOnClasspathConfiguration {

    public SpringMvcFoundOnClasspathConfiguration() {
        throw new MvcFoundOnClasspathException();
    }

}

从该配置类拥有的注解可以看到,它拥有如下注解:

@ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")

也就意味着,该配置类只有在ClassPath类路径下存在指定类

org.springframework.web.servlet.DispatcherServlet 时生效,一旦该配置生效被IOC容器注册,也就意味着该配置类会被构造初始化,从他的唯一构造函数可以看出,会抛一个MvcFoundOnClasspathException 异常。该异常无实际内容,只继承了 RuntimeException 但在另一处被处理: MvcFoundOnClasspathFailureAnalyzer

public class MvcFoundOnClasspathFailureAnalyzer extends AbstractFailureAnalyzer<MvcFoundOnClasspathException> {

    /**
     * Message for MvcFoundOnClasspathException.
     */
    public static final String MESSAGE = "Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.";

    /**
     * Action for MvcFoundOnClasspathException.
     */
    public static final String ACTION = "Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.";

    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, MvcFoundOnClasspathException cause) {
        return new FailureAnalysis(MESSAGE, ACTION, cause);
    }

}

从上图可以看出,该类会被SpringBoot的自动配置之 spring.factories 的类路径配置加载机制加载并注册生效,因此,一旦项目启动开始扫面类路径时,发现类路径存在 servlet 包下的DispatcherServlet 

核心分发控制器类,那么就会抛 MvcFoundOnClasspathException 异常并被 MvcFoundOnClasspathFailureAnalyzer 处理,同时控制台会打印错误信息 MESSAGE 和解决错误的建议提示 ACTION

WebfluxMissingFromClasspathConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler")
protected static class WebfluxMissingFromClasspathConfiguration {

    public WebfluxMissingFromClasspathConfiguration() {
        log.warn(BORDER + "Spring Webflux is missing from the classpath, "
                + "which is required for Spring Cloud Gateway at this time. "
                + "Please add spring-boot-starter-webflux dependency." + BORDER);
    }

}

这是 GatewayClassPathWarningAutoConfiguration的第二个内部配置类,可以看到只有当 ClassPath 类路径下没有 org.springframework.web.reactive.DispatcherHandler 类时才生效

DispatcherHandler 请求映射分发处理器,起作用和 DispatcherServlet 类似,当该类不存在会直接在控制台打印警告提示。

猜你喜欢

转载自blog.csdn.net/python15397/article/details/129351144