SpringBoot过程描述图
查看它的源码实现
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
SpringApplication.run(ZhStateApplication.class, args);
}
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class[]{primarySource}, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
由上面源码可以看到,启动run方法其实分两部分
一是创建一个SpringApplication对象,二是调用run方法
new SpringApplication(primarySources),其中primarySources就是启动类的Class对象
public SpringApplication(Class<?>... primarySources) {
this((ResourceLoader)null, primarySources);
}
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 = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// primarySources: 代表主要资源的Set<Class>集合,将传入的启动类资源加入到primarySources
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
// webApplicationType:应用程序类型,默认为Servlet
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
// 1. 设置初始化,根据ApplicationContextInitializer去spring.factories文件中找到对应的数据,通过反射创建对象集合,然后赋值给initializers集合
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 2. 设置监听器,根据ApplicationListener去spring.factories文件中找到对应的数据,通过反射创建对象集合,然后赋值给listeners集合,他的逻辑根上面方法一样
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
// 找到包含main函数的启动类的Class对象赋值给mainApplicationClass
this.mainApplicationClass = this.deduceMainApplicationClass();
}
- 设置初始化
// SpringApplication类
// 1. 设置初始化
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
// 1.1 获取SpringFactories中指定的集合对象
return this.getSpringFactoriesInstances(type, new Class[0]);
}
1.1 获取SpringFactories中指定的集合对象
// SpringApplication类
// 1.1 获取SpringFactories中指定的集合对象
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
// 获取类加载器
ClassLoader classLoader = this.getClassLoader();
// 1.1.1 获取加载工厂的名称
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// 根据names集合来通过反射创建对象集合
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
1.1.1 获取加载工厂的名称
// SpringFactoriesLoader 类
// 1.1.1 获取加载工厂的名称
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoader == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
// loadSpringFactories(classLoaderToUse): 加载META-INF/spring.factories文件里面的数据
// getOrDefault(factoryTypeName, Collections.emptyList()): 根据指定的工厂类型名称过滤
return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
// 根据指定类加载器,来加载META-INF/spring.factories文件里面的数据
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
Map<String, List<String>> result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
HashMap result = new HashMap();
try {
Enumeration urls = classLoader.getResources("META-INF/spring.factories");
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
String[] var10 = factoryImplementationNames;
int var11 = factoryImplementationNames.length;
for(int var12 = 0; var12 < var11; ++var12) {
String factoryImplementationName = var10[var12];
((List)result.computeIfAbsent(factoryTypeName, (key) -> {
return new ArrayList();
})).add(factoryImplementationName.trim());
}
}
}
result.replaceAll((factoryType, implementations) -> {
return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
});
cache.put(classLoader, result);
return result;
} catch (IOException var14) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
}
}
}
第二部分
run(args)
// SpringApplication类
// 2. 运行Spring应用程序,创建并刷新一个新的ApplicationContext
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
// 异常报告信息
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty(); // 向当前系统设置了一个属性
// 1.1 获取SpringFactories中指定的集合对象SpringApplicationRunListener
SpringApplicationRunListeners listeners = this.getRunListeners(args);
// 遍历监听器集合执行
listeners.starting();
try {
// 将入参的数组包装成一个DefaultApplicationArguments对象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 准备环境对象
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
// 配置忽略的Bean信息
this.configureIgnoreBeanInfo(environment);
// 打印Banner图案,也可以自定义图案
Banner printedBanner = this.printBanner(environment);
// 创建应用程序上下文对象
context = this.createApplicationContext();
// 获取SpringFactories中指定的集合对象SpringBootExceptionReporter
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
// 准备上下文,也就是向上下文设置一些值
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文,也就是调用了Spring的 refresh方法
this.refreshContext(context);
// 刷新之后的操作
this.afterRefresh(context, applicationArguments);
stopWatch.stop(); // 执行结束
// 打印日志
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}