公司的这种打包启动方式,我简直惊呆了

news2025/7/18 5:50:09

前言

大家都知道,SpringBoot应用最终会打出一个Fat Jar, 里面包含了用到的全部依赖,启动也非常简单,java -jar xxx.jar即可。

但是我们公司打出的最终包,将依赖包挪到了外部,然后启动的时候通过loader.path指定依赖包的位置,如java -Dloader.path=libs -jar xxxx的方式启动,也能够启动成功。

这样做最大的一个好处就是如果发现某个依赖出现问题,那么我只需要在libs替换其中某个依赖,影响范围可以减小很多。

那大家是不是很好奇是怎么做到的呢?

打包方式详解

主要是通过两个maven插件打出这样的结构的包。

  1. spring-boot-maven-plugin

该插件是spring boot官方提供的一个打包插件,主要用来打出fat jar,并且提供了支持java -jar xxx.jar方式启动。 官网地址:docs.spring.io/spring-boot…。

我们需要用这个插件,因为只有它可以打出支持启动的jar,但是打出的包中又不能有依赖,该怎么做呢?如下图:

  • layout: 布局方式,这里要选择ZIP,后面说明原因。
  • includes: 选择包含哪些依赖,这里写了一个不存在的jar,那么也间接实现了不打入其他的依赖。这种方式比较ugly,但是目前没有找到更加合适的方案。
  1. maven-assembly-plugin

maven-assembly-plugin插件可以灵活定制打包内容,官网地址:maven.apache.org/plugins/mav…。

我们现在就是想办法利用该插件抽出我们用到的依赖包,该怎么做呢?

我们现在看下assembly.xml中的关键配置:

  • 可以根据includeexclude属性通过正则灵活的抽取相关依赖到指定的目录下

最终执行mvn clean package在target目录下得到最终的安装包:

解压该安装包:

打开libs目录:

启动方式解析

现在我们已经按照自己想要的结构打出包了,那如何在启动的时候加载libs目录中的依赖呢?

前面提到了springboot插件打出的包是启动的入口,实际上在这个包里面springboot会自动打入一个引导类org.springframework.boot.loader.Launcher,它是 Spring Boot 可执行 jar 的主要入口点,它是 Spring Boot jar 文件中的实际 Main-Class,用于设置适当的 URLClassLoader 并最终调用 Spring Boot项目中定义的 main()方法。

Launcher有三个子类(JarLauncherWarLauncherPropertiesLauncher),如果我们打包插件的layout配置的是ZIP的方式,它会使用PropertiesLauncher

PropertiesLauncher机制说明:

默认情况下,PropertiesLauncherBOOT-INF/lib/ 中加载,我们可以通过设置loader.properties 中的loader.pathLOADER_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 命令来启动程序,这样对应目录下的依赖均会被加载。

总结

这种打包启动方式虽然不常见,但是还是有一定的价值的,特别是在项目组件模块比较多的时候,出现紧急缺陷,可以按需替换包,将影响范围控制到最小。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第1章 数据库及其表的自动生成与前言

001 RootEntityTkey<Tkey>、BlogArticle RootEntityTkey<Tkey>&#xff1a;该实体类以泛型形式&#xff0c;定义了当前程序中所有实体的自增型主键。 BlogArticle&#xff1a;继承了RootEntityTkey<Tkey>&#xff0c;通过该实体类及其属性成员&#xff0c;用…

基于sklearn的机器学习实战

本文目录如下&#xff1a;LinearRegression线性回归入门数据生成定义模型模型测试与比较多项式回归具体实现LogisticRegression算法思想简述算法实现Decision TreeMLPSVM线性SVM多项式核高斯核对比不同核在Mnist上的效果读取数据高斯核多项式核线性核NBayesbagging与随机森林Ad…

适用于Linux的6个最佳Python IDE

早在 1991 年&#xff0c;当Guido van Rossum第一次引入 Python 时&#xff0c;他不会想到 Python 的未来发展这么好。现在我们在这里规模地使用Python构建项目。根据 2022 年的一份报告&#xff0c;Python 在全球拥有 29.53% 的份额&#xff0c;位居榜首。 Python 的设计牢记…

④开启shift后门实验报告

班级 计科1班 姓名 彭彭头 学号 时间 2022.05.13 成绩 实验项目名称 开启shift后门 实验目的 1、了解常用入侵主机的方法 2、掌握操作系统常见漏洞&#xff0c;并学会防范 实验内容 利用Windows7系统的shift漏洞&#xff0c;开启后门。 实验环境 操作系统&a…

分布式前修课:Zookeeper锁实现方式

前言 聊完MySQL和Redis&#xff0c;我们接下来在聊一聊Zookeeper。相信大家都已经发现了&#xff0c;这些都是我们在开发过程非常常用的技术。搞定他们&#xff0c;一切难题都不在话下。 Zookeeper&#xff0c;盘它 官网是我们学习某一种技术框架的第一手资料&#xff0c;通…

JAVA泛型

泛型的由来 因为JAVA中假如构建了一个object集合&#xff0c;在集合里存储任何的数据类型对象&#xff0c;定义了一个字符串&#xff0c;又定义一个常数。呢么在遍历数组Arraylist的时候&#xff0c;在代码行里并不会报错&#xff0c;但是运行之后会出现ClassCastException异常…

传奇私服开服架设教程 传奇服务端设置教程

首先开区要使用两个必备的软件&#xff1a;DBC2000、传奇引擎&#xff0c;当然也少不了传奇服务端(传奇服务端在论坛免费服务端和商业服务端中有下载)。 先把下载好的服务端解压到D盘或者某个般的根目录(所谓根目录&#xff0c;就是D盘或E盘&#xff0c;不是D盘和E盘的某个文件…

TCN代码详解-Torch (误导纠正)

1. 绪论 TCN网络由Shaojie Bai&#xff0c; J. Zico Kolter&#xff0c; Vladlen Koltun 三人于2018提出。对于序列预测而言&#xff0c;通常考虑循环神经网络结构&#xff0c;例如RNN、LSTM、GRU等。他们三个人的研究建议我们&#xff0c;对于某些序列预测&#xff08;音频合…

基于Matlab仿真极化双基地雷达系统(附源码)

目录 一、系统设置 二、系统仿真 三、使用圆极化接收阵列 四、总结 五、程序 此示例演示如何仿真极化双基地雷达系统以估计目标的范围和速度。发射器、接收器和目标运动学被考虑在内。 一、系统设置 该系统以 300 MHz 的频率运行&#xff0c;使用线性 FM 波形&#xff0…

Devkit代码迁移工具——smartdenovo源码迁移

smartdenovo源码迁移 迁移前准备工作 1、服务器和操作系统正常运行。 2、PC端已经安装SSH远程登录工具。 3、Porting Advisor已在准备好的x86平台环境和鲲鹏平台环境中完成安装并正常运行。 4、待迁移的相关软件包、源代码已准备就绪。 迁移步骤 1、利用Porting Advisor的源码…

人工智能学习:ResNet神经网络(8)

ResNet是一种非常有效的图像分类识别的模型&#xff0c;可以参考如下的链接 https://blog.csdn.net/qq_45649076/article/details/120494328 ResNet网络由残差&#xff08;Residual&#xff09;结构的基本模块构成&#xff0c;每一个基本模块包含几个卷积层。其中&#xff0c;…

【MySQL数据库笔记 - 进阶篇】(五)锁

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;暂定 &#x1f4dd;视频地址&#xff1a;黑马程序员 MySQL数据库入门到精通 &#x1f4e3;专栏定位&#xff1a;这个专栏我将会整理 B 站黑马程序员的 MySQL…

硬件科普系列之显示篇——LCD与OLED知多少

前言 无论是手机还是电脑&#xff0c;作为机器与人交互最为频繁的硬件设备&#xff0c;显示屏一直是决定用户体验最为关键的因素之一。大家近几年在购买手机的时候&#xff0c;可以发现目前大部分手机都在使用OLED屏幕&#xff0c;那么你有没有思考过为什么各大厂商都在大力推…

jupuyter的背景主题

jupuyter的背景主题一.背景主题安装查看可用主题1.主题安装2. **查看可用主题**3.更换主题&#xff0c;字体等其他设置4.其他命令&#xff0c;还原原本主题二.每个主题的效果1.chesterish2. grade33.gruvboxd4.oceans165.onedork6.solarizedd7.solarizedl一.背景主题安装查看可…

上帝视角看Vue源码整体架构+相关源码问答

前言 这段时间利用课余时间夹杂了很多很多事把 Vue2 源码学习了一遍&#xff0c;但很多都是跟着视频大概过了一遍&#xff0c;也都画了自己的思维导图。但还是对详情的感念模糊不清&#xff0c;故这段时间对源码进行了总结梳理。 本篇文章更合适于已看过 Vue2 源码&#xff0c…

使用NNI对DLASeg剪枝的失败记录

本文希望对CenterNet算法的Backbone暨DLASeg进行剪枝。 剪枝试验涉及3个文件&#xff0c;分别为&#xff1a; DCN可变性卷积dcn_v2.py&#xff0c;因为DLASeg依赖DCN。 #!/usr/bin/env python from __future__ import absolute_import from __future__ import print_functio…

如何在 Windows 10上修复0x000006ba错误

修复0x000006ba错误 可能导致此错误代码的原因已确认的可行的解决办法运行打印机疑难解答重新启动后台打印程序服务清除 PRINTERS 文件夹运行 SFC 和 DISM 扫描启用打印机共享某些 Windows 10 在尝试在 Windows 10 上打印新文档时遇到0x000006ba错误代码。其他用户在尝试使用 W…

【面试题】line-height继承问题

1. line-height为具体数值 当父元素line-height的值为具体数值的时候&#xff0c;例如30px&#xff0c;则子元素的line-height直接继承该数值。 <style>body{font-size: 20px;line-height: 50px;}p{background-color: #ccc;font-size: 16px;} </style><body&g…

类和对象的初步介绍

文章目录面向对象的初步认识什么是面向对象面向对象与面向过程类定义和使用简单认识类类的定义格式随堂练习定义一个学生类类的实例化什么是实例化类和对象的说明this 引用为什么要有this引用什么时this引用this引用的特性对象的构造和初始化构造方法概念特性默认初始化就地初始…

Shell脚本学习指南(三)——文本处理工具

文章目录排序文本行的排序以字段的排序文本块排序sort的效率sort的稳定性sort小结删除重复重新格式化段落计算行数、字数以及字符数打印打印技术的演化其他打印软件提取开头或结尾数行排序文本 含有独立数据记录的文本文恶剪&#xff0c;通常都可以拿来排序。一个可预期的记录…