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