一、讲述
1.SpringBoot提供了一个插件spring-boot-maven-plugin用于把程序打包成一个可执行的jar包。
2.Spring Boot应用打包之后,生成一个Fat jar(jar包中包含jar),包含了应用依赖的jar包和Spring Boot loader相关的
类。
3.java -jar会去找jar中的manifest文件,在那里面找到真正的启动类(Main-Class);
4.Fat jar的启动Main函数是JarLauncher,它负责创建一个LaunchedURLClassLoader来加载boot-lib下面的jar,并以一个新线程启动应用的启动类的Main函数(找到manifest中的Start-Class)。
二、原理
SpringBoot提供了一个插件spring-boot-maven-plugin用于把程序打包成一个可执行的jar包。pom文件配置如下
org.springframework.boot
spring-boot-maven-plugin
${spring-boot.version}
插件spring-boot-maven-plugin,提供了7个maven goal
2、通过mvn package命令,Maven首先会按照标准流程构建项目,随后spring-boot-maven-plugin会执行repackage目标,该目标会重新包装已生成的标准JAR文件,将其转换为包含所有依赖项和适当的启动器信息的Fat JAR。这样生成的JAR可以直接通过java -jar命令启动。jar内部目录如下
3、Spring Boot启动器与Loader机制与MANIFEST.MF文件
Spring Boot应用的jar包可以直接运行主要依赖于它的启动器以及Loader机制,而对于Loader机制主要利用MANIFEST.MF文件以及其内部类加载逻辑。
MANIFEST.MF是JAR文件内的一个标准元数据文件,它包含了关于JAR包的基本信息和运行指令。在jvm规范单中java -jar指令中会规范一个main方法,而这个main方法就在MANIFEST.MF文件中的Main-Class属性,这个类通常是org.springframework.boot.loader.JarLauncher或其他由Spring Boot提供的启动器类。Start-Class属性是启动应用的main方法。JarLauncher会通过一个子线程启动Start-Class中的main方法
4、JarLauncher执行流程
JarLauncher 入口 main 方法
public static void main(String[] args) throws Exception {
// launch 方法是调用父类 Launcher 的 launch 方法
new JarLauncher().launch(args);
}
这里是加载清单文件的中的配置
/**
* Launch the application. This method is the initial entry point that should be
* called by a subclass {@code public static void main(String[] args)} method.
启动一个应用,这个方法应该被初始的入口点,这个入口点应该是一个Launcher的子类的
public static void main(String[] args)这样的方法调用
* @param args the incoming arguments
* @throws Exception if the application fails to launch
*/
protected void launch(String[] args) throws Exception {
if (!isExploded()) {
// 注册一些 URL的属性
JarFile.registerUrlProtocolHandler();
}
// 创建类加载器(LaunchedURLClassLoader),加载得到集合要么是BOOT-INF/classes/,或者BOOT-INF/lib/的目录或者是他们下边的class文件或者jar依赖文件
ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator());
String jarMode = System.getProperty("jarmode");
String launchClass = (jarMode != null && !jarMode.isEmpty()) ? JAR_MODE_LAUNCHER : getMainClass();
// 执行应用的main方法
launch(args, launchClass, classLoader);
}
参与评论
手机查看
返回顶部