前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot从0到实战5:项目是如何通过jar包启动的?

SpringBoot从0到实战5:项目是如何通过jar包启动的?

作者头像
程序员洲洲
发布2024-06-06 21:44:51
1020
发布2024-06-06 21:44:51
举报
文章被收录于专栏:项目文章

从Spring-boot-maven-plugin谈起

  • 对于SpringBoot打包的jar文件,只需要通过jar -jar一行命令便可以启动一个web项目,那springboot是如何做到的呢,这需要从plugin谈起。
  • 对于SpringBoot项目,我们会在pom.xml文件添加打包插件spring-boot-maven-plugin,那么执行打包的时候,会生成相应的jar文件,比如:
代码语言:javascript
复制
spring-boot-hello-0.0.1-SNAPSHOT.jar
  • 打开上面jar的文件可以发现有如下东西:
  • 通过查阅资料和学习,可以发现,Spring-boot-maven-plugin完成了几件对打包重要的事情:

1、生成核心的文件MANIFEST.MF;

2、把依赖的jar包进行打包;

  • 在jar包里打包进去了别的jar包,这样的jar成为fat jar,也叫作uber jar。

从生成核心的文件MANIFEST.MF谈起

  • 使用记事本打开MANIFEST.MF文件:
  • 在文件中,有两个重要的属性:
代码语言:javascript
复制
Start-Class:com.kfit.springboothellosts.SpringBootHelloStsApplication

Main-Class:org.springframework.boot.loader.JarLauncher

仔细观察发现Start-Class指向的是我们的启动类HelloStsApplication,也就是注解了@SpringBootApplication的类。而Main-Class则可以理解为真正的启动类。

理解java -jar真正做了什么事

  • 找出官网的描述如下:
  • If the -jar optionis specified, its argument is the name of the JAR file containing class andresource files for the application. The startup class must be indicated bythe Main-Class manifest header in its source code.
  • 使用百度翻译如下:
  • 使用-jar参数时,后面的参数是jar的文件名称(本例子中是spring-boot-hello-0.0.1-SNAPSHOT.jar),该jar文件中包含的是class和资源文件;在mainfest文件中有Main-Class的定义;Main-Class的源码中指定了整个应用的启动类。
  • 简单的理解为:java -jar会找jar中的mainfest文件,进而找到属性Main-Class文件,从而找到真正的启动类。

理解Main-Class中的JarLauncher

  • 对于Spring Boot项目的Main-Class中的值是org.springframework.boot.loader.JarLauncher,那么当我们执行命令:Java-jar spring-boot-hello-0.0.1-SNAPSHOT.jar的时候,那么会找到.jar文件中的Main-Class属性值org.springframework.boot.loader.JarLauncher,然后执行JarLauncher文件。
  • JarLauncher实际上是一个自定义ClassLoader,那么它核心作用就是:加载jar包的jar文件和class文件。加载完成之后会找到Start-Class指定的启动类,通过反射进行启动应用。

为什么SpringBoot要定义一个ClassLoader

  • 这个就和java有关系了,对于嵌套的jar,这里有很重要的一句话:Java没有提供任何标准的方式来加载嵌套的jar文件(即,它们本身包含在jar中的jar文件)。所以对于Spring Boot项目中依赖的jar文件,java并无能为力,对于-jar的底层是找到一个Main-Class属性值,对于Spring Boot项目要启动,有两个核心的事情就要去做了: (1)加载jar中的jar文件以及class文件; (2)启动main方法;
  • 对于main方法启动类上的注解@SpringBootApplication注解是在相应的jar中的,很显然不能直接先启动main方法中的类,然后再加载jar文件。
  • 所以需要Main-Class就不能指向main方法中的启动类了,对于SpringBoot定义了一个JarLauncher来加载jar文件和class文件,对于jar文件和class文件的加载的工作在java中是由classloader来完成的,java内置的classloader不能满足要求,也就需要Spring Boot自定义ClassLoader来搞定这个事情了,也就是JarLauncher是一个自定义的类加载器。
  • 对于Starter-Class是SpringBoot自己定义的一个属性值,为了JarLauncher加载了jar文件和class文件之后,可以找到启动类。

IDEA中如何启动SpringBoot应用

  • 在IDE里启动SpringBoot应用是最简单的一种情况,依赖的Jar都让IDE放到classpath里了,所以Spring boot直接启动。

总结

  • Spring Boot应用打包之后,生成一个Fat jar,包含了应用依赖的jar包和Spring Boot loader相关的类。
  • Fat jar的启动Main函数是JarLauncher,其作用是创建一个LaunchedURLClassLoader来加载/lib下面的jar,并以一个新线程启动应用的Main函数。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从Spring-boot-maven-plugin谈起
    • 1、生成核心的文件MANIFEST.MF;
      • 2、把依赖的jar包进行打包;
      • 从生成核心的文件MANIFEST.MF谈起
      • 理解java -jar真正做了什么事
      • 理解Main-Class中的JarLauncher
      • 为什么SpringBoot要定义一个ClassLoader
      • IDEA中如何启动SpringBoot应用
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档