qidao123.com技术社区-IT企服评测·应用市场

标题: 为什么springboot的jar可以直接启动 [打印本页]

作者: 欢乐狗    时间: 2025-3-25 03:35
标题: 为什么springboot的jar可以直接启动
一、讲述
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文件配置如下
  1. <plugin>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-maven-plugin</artifactId>
  4.     <version>${spring-boot.version}</version>
  5. </plugin>
复制代码
插件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 方法
  1. public static void main(String[] args) throws Exception {
  2.     // launch 方法是调用父类 Launcher 的 launch 方法
  3.     new JarLauncher().launch(args);
  4. }
复制代码
这里是加载清单文件的中的配置
  1.    /**
  2.          * Launch the application. This method is the initial entry point that should be
  3.          * called by a subclass {@code public static void main(String[] args)} method.
  4.            启动一个应用,这个方法应该被初始的入口点,这个入口点应该是一个Launcher的子类的
  5.            public static void main(String[] args)这样的方法调用
  6.          * @param args the incoming arguments
  7.          * @throws Exception if the application fails to launch
  8.          */
  9.         protected void launch(String[] args) throws Exception {
  10.                 if (!isExploded()) {
  11.                   // 注册一些 URL的属性
  12.                         JarFile.registerUrlProtocolHandler();
  13.                 }
  14.                 // 创建类加载器(LaunchedURLClassLoader),加载得到集合要么是BOOT-INF/classes/,或者BOOT-INF/lib/的目录或者是他们下边的class文件或者jar依赖文件
  15.                 ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator());
  16.                 String jarMode = System.getProperty("jarmode");
  17.                 String launchClass = (jarMode != null && !jarMode.isEmpty()) ? JAR_MODE_LAUNCHER : getMainClass();
  18.                 // 执行应用的main方法
  19.                 launch(args, launchClass, classLoader);
  20.         }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4