springboot项目打成的jar包一般通过 java-jar xxx.jar命令启动,原理:
原理:查看解压后的demo/target/demo/META-INF/MANIFEST.MF
通过java-jar的方式启动 springboot项目时,首先找到 上图 文件中的 Main-Class jarLauncher主类,查看JarLauncher源码:
依赖:
org.springframework.boot
spring-boot-loader
2.3.1.RELEASE
执行JarLauncher.java 中 的main方法:
public static void main(String[] args) throws Exception {
(new JarLauncher()).launch(args);
}
Launcher.java 的 launch()方法:
protected void launch(String[] args) throws Exception {
if (!this.isExploded()) {
JarFile.registerUrlProtocolHandler();
}
ClassLoader classLoader = this.createClassLoader(this.getClassPathArchivesIterator());
String jarMode = System.getProperty("jarmode");
String launchClass = jarMode != null && !jarMode.isEmpty() ? "org.springframework.boot.loader.jarmode.JarModeLauncher" : this.getMainClass();
this.launch(args, launchClass, classLoader);
}
查看 getMainClass()方法:(实现类中 PropertiesLauncher)
protected String getMainClass() throws Exception {
//加载 jar包 target目录下的 MANIFEST.MF 文件中 Start-Class配置,找到springboot的启动类
String mainClass = this.getProperty("loader.main", "Start-Class");
if (mainClass == null) {
throw new IllegalStateException("No 'loader.main' or 'Start-Class' specified");
} else {
return mainClass;
}
}
继续执行Launcher.java的 launch()方法:执行run方法
protected void launch(String[] args, String launchClass, ClassLoader classLoader) throws Exception {
Thread.currentThread().setContextClassLoader(classLoader);
this.createMainMethodRunner(launchClass, args, classLoader).run();
}
run()方法:
public void run() throws Exception {
//获取springboot项目启动类
Class> mainClass = Class.forName(this.mainClassName, false, Thread.currentThread().getContextClassLoader());
//获取启动方法 main方法:
Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
mainMethod.setAccessible(true);
//反射运行main方法
mainMethod.invoke((Object)null, this.args);
}
以上就是springboot项目通过 java-jar启动 jar包的 原理。