上一篇说了启动类注解@SpringBootApplication大致的作用,这篇文章主要对启动注解做一些了解,如果需要,可以点击超链接。
我们创建spingboot项目后,都会有一个启动类,里面有这样一行代码:
SpringApplication.run(DemoApplication.class,args)
他调用了SpringApplication的静态run方法。下面让我们简单看看它都做了什么
我们简单的跟了一下源码,下面是流程图:
先看它new了一个SpringApplication,调用了有参构造,构造方法如下:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
// 设置一些资源加载器
this.resourceLoader = resourceLoader;
// 加载类资源不能为空
Assert.notNull(primarySources, "PrimarySources must not be null");
// 做一个数据结构的转换
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
// 判断当前项目类型是什么
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置初始化器
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 设置监听器,springfactories 想要寻找的话,就是通过spring.factory
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
// 根据class 推断应用的入口类 通过run方法调用main方法
this.mainApplicationClass = this.deduceMainApplicationClass();
}
其主要的方法有两个:
WebApplicationType.deduceFromClasspath()
this.getSpringFactoriesInstances(ApplicationContextInitializer.class)
下面我们简单看一下这两个方法的作用:
WebApplicationType.deduceFromClasspath():
源码:
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
return REACTIVE;
} else {
String[] var0 = SERVLET_INDICATOR_CLASSES;
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
String className = var0[var2];
if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
return NONE;
}
}
return SERVLET;
}
}
通过代码我们可以看出,这个方法是判断了我们的工程到底是个什么类型(web工程,基本的spring工程等)
getSpringFactoriesInstances(ApplicationContextInitializer.class)
这个方法我们需要往里跟一下,上流程图
经过跟进了以下代码,看到了熟悉的META-INF/spring.factories,得知spring是在这时候把EnableAutoConfiguration注解配置的bean都注册进springioc容器里了
第一小节把新建对象干的事就大致说完了,下一篇说说run方法。