SpringBoot启动源码解析(一)
特殊说明:第一章只包含了 初始化上下文,初始化监听器列表,发布springboot启动事件 相关内容
其中一部分代码
/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
}
1、初始化一个计时器,并开始计时
StopWatch stopWatch = new StopWatch();
stopWatch.start();
其实是用来统计应用启动耗时的。
实现原理为记录下开始时间和结束时间,相减即可。
2、初始化启动上下文
private DefaultBootstrapContext createBootstrapContext() {
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));
return bootstrapContext;
}
new一个默认的上下文
3、设置该应用程序,即使没有检测到显示器,也允许其启动
configureHeadlessProperty();
private void configureHeadlessProperty() {
System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}
设置了一个名为java.awt.headless的系统属性。
为true时,即使没有显示器,也可以启动。
例如linux服务器。
4、获取SpringApplicationRunListener的实现类
SpringApplicationRunListeners listeners = getRunListeners(args);
进入getRunListeners方法
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
this.applicationStartup);
}
①、获取了一个class数组types
其中的元素分别为:SpringApplication和String数组的class对象。在后续反射初始化对象时,types用于获取到目标的构造方法。
②、获取SpringApplicationRunListener实例对象
其中,调用了getSpringFactoriesInstances方法。该方法的目的为:获取SpringApplicationRunListener接口的所有实现类对象。
在后续的启动过程中,交由listeners发布的事件,实际上是遍历其内部管理的SpringApplicationRunListener对象列表进行发布的。
需要注意的是,通过getSpringFactoriesInstances方法获取到的SpringApplicationRunListener类型的对象有且仅有一个:EventPublishingRunListener实例对象。
③、通过获取到的SpringApplicationRunListener实例,创建一个SpringApplicationRunListeners对象并返回。
第一和第三步比较简单。
让我们关注下第二步,getSpringFactoriesInstances方法:
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
首先通过getClassLoader方法,获取到默认的类加载器,
然后通过SpringFactoriesLoader.loadFactoryNames(type, classLoader),获取SpringApplicationRunListener所有的实现类名称,
最后创建SpringApplicationRunListener接口的所有实现类对象,排序并返回。