当使用java命令运行一个jar包时 实际上是运行jar包中的一个主类的main方法,在jar包的MANIFEST.MF文件中的Main-Class指定的;
Spring boot项目打包后的目录结构如下:
BOOT-INF
META-INF
org
springframework
boot
loader
所以Spring boot项目启动靠
springframework.boot.loader
解压Spring boot的一个项目包,打开MANIFEST.MF,发现:
Main-Class: org.springframework.boot.loader.JarLauncher
说明java命令运行Spring boot项目时实际上是运行了JarLauncher类
下面看下JarLauncher类都做了些什么
1.JarLauncher 类的main方法:
public static void main(String[] args) throws Exception {
new JarLauncher().
launch(args);
}
2.launch 方法
protected void launch(String[] args) throws Exception {
JarFile.registerUrlProtocolHandler();
ClassLoader classLoader = createClassLoader(getClassPathArchives());
launch(args,
getMainClass(), classLoader);
}
这个方法中有一个关键语句:
JarFile.registerUrlProtocolHandler();
注册一个自定义的Handler,处理“jar:”这样的协议,处理jar in jar 以及加载其他资源。
实际上是这个玩意下面的Handler:org.springframework.boot.loader
3.
getMainClass()方法
@Override
protected String getMainClass() throws Exception {
Manifest manifest = this.archive.getManifest();
String mainClass = null;
if (manifest != null) {
mainClass = manifest.getMainAttributes().getValue("Start-Class");
}
if (mainClass == null) {
throw new IllegalStateException(
"No 'Start-Class' manifest entry specified in " + this);
}
return mainClass;
}
由此可见 最终运行的是
Start-Class方法
4.MANIFEST.MF文件中的Start-Class为:
Start-Class: com.fboot.FbootApplication