spring boot 启动源码解析系列五:找到程序入口类并实例化

SpringApplication initialize 方法:

1
2
3
4
5
6
7
8
9
10
private void (Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}

this.webEnvironment = this.deduceWebEnvironment();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}

deduceMainApplicationClass 方法即用于查找 main 方法类,并实例化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
StackTraceElement[] var2 = stackTrace;
int var3 = stackTrace.length;

for(int var4 = 0; var4 < var3; ++var4) {
StackTraceElement stackTraceElement = var2[var4];
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
} catch (ClassNotFoundException var6) {
;
}

return null;
}

该方法是通过构造一个运行时异常,然后通过异常栈中的方法名是否是 main 来得到启动类的名字。