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

简介: Spring Boot应用打包之后,生成一个Fat jar,包含了应用依赖的jar包和Spring Boot loader相关的类。Fat jar的启动Main函数是JarLauncher,其作用是创建一个LaunchedURLClassLoader来加载/lib下面的jar,并以一个新线程启动应用的Main函数。

从Spring-boot-maven-plugin谈起


对于SpringBoot打包的jar文件,只需要通过jar -jar一行命令便可以启动一个web项目,那springboot是如何做到的呢,这需要从plugin谈起。


对于SpringBoot项目,我们会在pom.xml文件添加打包插件spring-boot-maven-plugin,那么执行打包的时候,会生成相应的jar文件,比如:

spring-boot-hello-0.0.1-SNAPSHOT.jar


打开上面jar的文件可以发现有如下东西:

44ccd754ce326202bdc195875a7da564_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTQ4NDQ2MA==,size_16,color_FFFFFF,t_70.png

通过查阅资料和学习,可以发现,Spring-boot-maven-plugin完成了几件对打包重要的事情:

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

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

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

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


使用记事本打开MANIFEST.MF文件:

17dfb77ed172230daab28859d4aa1304_fb03de74c16a49f1a5d6cf85326b6850.png


在文件中,有两个重要的属性:

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函数。


相关文章
|
9月前
|
JSON 分布式计算 大数据
springboot项目集成大数据第三方dolphinscheduler调度器
springboot项目集成大数据第三方dolphinscheduler调度器
577 3
|
9月前
|
Java 关系型数据库 数据库连接
Spring Boot项目集成MyBatis Plus操作PostgreSQL全解析
集成 Spring Boot、PostgreSQL 和 MyBatis Plus 的步骤与 MyBatis 类似,只不过在 MyBatis Plus 中提供了更多的便利功能,如自动生成 SQL、分页查询、Wrapper 查询等。
919 3
|
9月前
|
Java 关系型数据库 MySQL
springboot项目集成dolphinscheduler调度器 实现datax数据同步任务
springboot项目集成dolphinscheduler调度器 实现datax数据同步任务
890 2
|
9月前
|
分布式计算 Java 大数据
springboot项目集成dolphinscheduler调度器 可拖拽spark任务管理
springboot项目集成dolphinscheduler调度器 可拖拽spark任务管理
493 2
|
9月前
|
Java 测试技术 Spring
简单学Spring Boot | 博客项目的测试
本内容介绍了基于Spring Boot的博客项目测试实践,重点在于通过测试驱动开发(TDD)优化服务层代码,提升代码质量和功能可靠性。案例详细展示了如何为PostService类编写测试用例、运行测试并根据反馈优化功能代码,包括两次优化过程。通过TDD流程,确保每项功能经过严格验证,增强代码可维护性与系统稳定性。
351 0
|
9月前
|
存储 Java 数据库连接
简单学Spring Boot | 博客项目的三层架构重构
本案例通过采用三层架构(数据访问层、业务逻辑层、表现层)重构项目,解决了集中式开发导致的代码臃肿问题。各层职责清晰,结合依赖注入实现解耦,提升了系统的可维护性、可测试性和可扩展性,为后续接入真实数据库奠定基础。
696 0
|
分布式计算 大数据 Java
springboot项目集成大数据第三方dolphinscheduler调度器 执行/停止任务
springboot项目集成大数据第三方dolphinscheduler调度器 执行/停止任务
233 0
|
10月前
|
网络协议 Java
在SpringBoot项目中使用Netty实现远程调用
本文介绍了使用Netty解决网络连接性能问题的方法,重点讲解了Netty的NIO特性及其在SpringBoot中的应用。Netty作为高效的NIO框架,支持非阻塞IO,能通过单线程管理多个客户端连接,简化TCP/UDP套接字服务器开发。文章详细展示了Netty在SpringBoot中实现远程调用的过程,包括服务端与客户端代码实现、依赖配置及测试验证。通过示例代码,如`NettyServer`、`NettyClientUtil`等,清晰说明了Netty的工作原理和实际应用,解决了半包等问题,并提供了完整的测试结果。
949 3
|
分布式计算 Java 大数据
springboot项目集成dolphinscheduler调度器 项目管理
springboot项目集成dolphinscheduler调度器 项目管理
275 0
|
SQL 前端开发 Java
深入理解 Spring Boot 项目中的分页与排序功能
本文深入讲解了在Spring Boot项目中实现分页与排序功能的完整流程。通过实际案例,从Service层接口设计到Mapper层SQL动态生成,再到Controller层参数传递及前端页面交互,逐一剖析每个环节的核心逻辑与实现细节。重点包括分页计算、排序参数校验、动态SQL处理以及前后端联动,确保数据展示高效且安全。适合希望掌握分页排序实现原理的开发者参考学习。
781 4

热门文章

最新文章

下一篇
开通oss服务