关于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 类似,当该类不存在会直接在控制台打印警告提示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值