本文以一个基础的springboot,mvc服务如何启动加载。进行探究,做一下源码探究记录
首先搭建一个能正常启动的springboot的mvc项目。
@EnableFeignClients @EnableEurekaClient @SpringBootApplication @RestController public class AuthServiceApplication { @RequestMapping("/health") public String home() { return "Hello World"; } public static void main(String[] args) { SpringApplication.run(AuthServiceApplication.class, args); } }
点击进入
SpringApplication.run(AuthServiceApplication.class, args);
run方法,继续点击进入 SpringApplication,构造方法。
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); }
可以看到进入如下构造方法public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader;//类加载器,从上面点击进入发现此时类加载器是null,后面代码会指定默认类加载器
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();//获取当前启动项目的类型,枚举有三种类型:NONE,SERVLET(通常的Java服务器项目),REACTIVE(是一个完全的reactive并且非阻塞的web框架,后续再做探究)
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//获取当前程序的上下文初始化类
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//获取当前程序的所有监听器
this.mainApplicationClass = deduceMainApplicationClass();
}
咱们先着重看一下this.webApplicationType = WebApplicationType.deduceFromClasspath();进入代码会看到如下代码(代码片段)
1 static WebApplicationType deduceFromClasspath() { 2 if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null) 3 && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) { 4 return WebApplicationType.REACTIVE; 5 } 6 for (String className : SERVLET_INDICATOR_CLASSES) { 7 if (!ClassUtils.isPresent(className, null)) { 8 return WebApplicationType.NONE; 9 } 10 } 11 return WebApplicationType.SERVLET; 12 }
如上ClassUtils.isPresent方法,进入内部查看代码发现,会去加载指定的 WEBFLUX_INDICATOR_CLASS等类,如果查找不到就返回false.然后我们看下图,通过spring官方下载的快速启动的webclent项目,可以知道pom文件需要配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
查看源代码类图,可以找到如下图,而且查看项目引用jar可以得到上面代码片段中的类,经过判断最终返回的是SERVLET
同样,我们如果配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
经过查找和判断最终会得到REACTIVE。感兴趣的同学可以自己尝试,查看。