公司的这种打包启动方式,我简直惊呆了! 野性酷女 2023-09-26 17:42 67阅读 0赞 大家都知道,SpringBoot应用最终会打出一个`Fat Jar`, 里面包含了用到的全部依赖,启动也非常简单,`java -jar xxx.jar`即可。 ![42c8cacfb02ba53fdad832e791f8d612.jpeg][] 但是我们公司打出的最终包,将依赖包挪到了外部,然后启动的时候通过`loader.path`指定依赖包的位置,如`java -Dloader.path=libs -jar xxxx`的方式启动,也能够启动成功。 ![a6517b47cb4819f55cd562391da5afa0.png][] 这样做最大的一个好处就是如果发现某个依赖出现问题,那么我只需要在libs替换其中某个依赖,影响范围可以减小很多。 那大家是不是很好奇是怎么做到的呢? ### 打包方式详解 ### 主要是通过两个maven插件打出这样的结构的包。 #### 1. spring-boot-maven-plugin #### 该插件是`spring boot`官方提供的一个打包插件,主要用来打出`fat jar`,并且提供了支持`java -jar xxx.jar`方式启动。官网地址:https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/。 我们需要用这个插件,因为只有它可以打出支持启动的jar,但是打出的包中又不能有依赖,该怎么做呢?如下图: ![7d2fe845419614df20acdb33cefe00dc.png][] * `layout`: 布局方式,这里要选择`ZIP`,后面说明原因。 * `includes`: 选择包含哪些依赖,这里写了一个不存在的jar,那么也间接实现了不打入其他的依赖。这种方式比较ugly,但是目前没有找到更加合适的方案。关注公众号:码猿技术专栏,回复关键词:1111 获取阿里内部的java性能调优手册 #### 2. maven-assembly-plugin #### maven-assembly-plugin插件可以灵活定制打包内容,官网地址:https://maven.apache.org/plugins/maven-assembly-plugin/。 我们现在就是想办法利用该插件抽出我们用到的依赖包,该怎么做呢? ![00368f918b9243e1ef0030e00e53c37c.png][] 我们现在看下`assembly.xml`中的关键配置: ![515eef3bfa3704f30f41f0aa6d40e2eb.png][] 可以根据`include`、`exclude`属性通过正则灵活的抽取相关依赖到指定的目录下 最终执行`mvn clean package`在target目录下得到最终的安装包: ![d411cbb67cde6d9b8ded4cb79395acb1.png][] 解压该安装包: ![b4c0fb6a65305cefbd8c2f67ae5decd1.png][] 打开libs目录: ![58e5388e2b417c6a5d5a49ef8fe8a77a.png][] ### 启动方式解析 ### 现在我们已经按照自己想要的结构打出包了,那如何在启动的时候加载`libs`目录中的依赖呢? 前面提到了`springboot`插件打出的包是启动的入口,实际上在这个包里面`springboot`会自动打入一个引导类`org.springframework.boot.loader.Launcher`,它是 `Spring Boot`可执行 jar 的主要入口点;关注公众号:码猿技术专栏,回复关键词:1111 获取阿里内部的java性能调优手册;它是 `Spring Boot jar` 文件中的实际 `Main-Class`,用于设置适当的 `URLClassLoader` 并最终调用`Spring Boot`项目中定义的 `main()`方法。 `Launcher`有三个子类(`JarLauncher`、`WarLauncher` 和 `PropertiesLauncher`),如果我们打包插件的`layout`配置的是`ZIP`的方式,它会使用`PropertiesLauncher`。 PropertiesLauncher机制说明: 默认情况下,`PropertiesLauncher` 在 `BOOT-INF/lib/` 中加载,我们可以通过设置`loader.properties`中的`loader.path` 或 `LOADER_PATH` 环境变量来增加其它的加载位置。 * `loader.path`:配置逗号分隔的 `Classpath` 类路径,例如 `lib,${HOME}/app/lib`,前面的路径优先,类似于 javac 命令中的 `-classpath`。 * `loader.home`:用于解析 `loader.path` 配置的相对路径,默认是`${user.dir}`。 所以,打包成功后,我们可以通过`java -jar -Dloader.path=xx1,xx2,public <jarName>.jar` 命令来启动程序,这样对应目录下的依赖均会被加载。 ### 总结 ### 这种打包启动方式虽然不常见,但是还是有一定的价值的,特别是在项目组件模块比较多的时候,出现紧急缺陷,可以按需替换包,将影响范围控制到最小。 [42c8cacfb02ba53fdad832e791f8d612.jpeg]: https://img-blog.csdnimg.cn/img_convert/42c8cacfb02ba53fdad832e791f8d612.jpeg [a6517b47cb4819f55cd562391da5afa0.png]: https://img-blog.csdnimg.cn/img_convert/a6517b47cb4819f55cd562391da5afa0.png [7d2fe845419614df20acdb33cefe00dc.png]: https://img-blog.csdnimg.cn/img_convert/7d2fe845419614df20acdb33cefe00dc.png [00368f918b9243e1ef0030e00e53c37c.png]: https://img-blog.csdnimg.cn/img_convert/00368f918b9243e1ef0030e00e53c37c.png [515eef3bfa3704f30f41f0aa6d40e2eb.png]: https://img-blog.csdnimg.cn/img_convert/515eef3bfa3704f30f41f0aa6d40e2eb.png [d411cbb67cde6d9b8ded4cb79395acb1.png]: https://img-blog.csdnimg.cn/img_convert/d411cbb67cde6d9b8ded4cb79395acb1.png [b4c0fb6a65305cefbd8c2f67ae5decd1.png]: https://img-blog.csdnimg.cn/img_convert/b4c0fb6a65305cefbd8c2f67ae5decd1.png [58e5388e2b417c6a5d5a49ef8fe8a77a.png]: https://img-blog.csdnimg.cn/img_convert/58e5388e2b417c6a5d5a49ef8fe8a77a.png
还没有评论,来说两句吧...