在SpringBoot中,SpringBoot对应用程序进行了3种类型的区分,使用了一个枚举类WebApplicationType,而deduceFromClasspath方法就在这个枚举类中。
WebApplicationType的值有以下3个
/**
* The application should not run as a web application and should not start an
* embedded web server.
*/
NONE,
/**
* The application should run as a servlet-based web application and should start an
* embedded servlet web server.
*/
SERVLET,
/**
* The application should run as a reactive web application and should start an
* embedded reactive web server.
*/
REACTIVE;
具体的区别可以阅读注释,英语不好的我做个简单解释:
NONE就是什么都没有,按照正常的代码走即可不需要额外启动web容器如tomcat等;SERVLET则代表这是一个传统的servlet的web程序,对应SpringMVC,表示需要启动对应的web容器支持如tomcat等;REACTIVE则是一种比较新的非阻塞的web框架,对应spring-webflux,需要启动支持reactive的web容器,这里我对webflux不太熟悉不过多解释。
deduceFromClasspath方法的源码如下:
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
常量我就不进行粘贴,代码中频繁使用到ClassUtils.isPresent()这个方法,通过这个方法来判断常量中的类是否存在。该方法的最终实现原理是通过Class.forName尝试加载某个类,如果能够成功加载,则证明这个类存在,反之发生异常则代表类不存在。
所以deduceFromClasspath方法的实现原理也很好理解,通过判断webflux相关的类是否存在,存在则认为是REACTIVE类型,不存在继续判断servlet相关的类是否存在,都存在则认为是SERVLET类型,都不存在则认为是NONE类型。具体的类的类型可以直接查看源码,不过多赘述。