spring boot打的包直接运行
Spring Boot 提供了一个插件 spring-boot-maven-plugin 把程序打包成一个可执行的jar包,直接执行java -jar xxx.jar即可以启动程序
1、引用 spring-boot-maven-plugin插件
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
2、打包文件内部结构

1)、BOOT-INF:
class:项目代码
lib:依赖jar包
2)、META-INF:程序入口
maven.xxx:程序配置文件
MANIFEST.MF
3)、org.springframework.boot.loader
3、MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: sk-cloud-order-sc
Implementation-Version: 1.0-SNAPSHOT
Start-Class: com.sk.order.sc.app
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 1.4.3.RELEASE
Created-By: Maven JAR Plugin 3.2.2
Main-Class: org.springframework.boot.loader.JarLauncher
Main-Class:org.springframework.boot.loader.JarLauncher:当我们使用java -jar xxx.jar启动jar包的时候通过调用JarLauncher#Main方法,不是我们定义的Main方法。SpringBoot内部提供一个可用于执行SpringBootApplication的工具类,这就是为什么打的包包含spring-boot-loader
4、JarLauncher源码查看
1)、添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-loader</artifactId><version>2.7.8</version>
</dependency>
2)、抽象Launcher类
用于启动应用程序,分别有JarLauncher、WarLauncher、PropertiesLauncher实现类
public abstract class Launcher {private static final String JAR_MODE_LAUNCHER = "org.springframework.boot.loader.jarmode.JarModeLauncher";public Launcher() {}protected void launch(String[] args) throws Exception {if (!this.isExploded()) {JarFile.registerUrlProtocolHandler();}ClassLoader classLoader = this.createClassLoader(this.getClassPathArchivesIterator());String jarMode = System.getProperty("jarmode");String launchClass = jarMode != null && !jarMode.isEmpty() ? "org.springframework.boot.loader.jarmode.JarModeLauncher" : this.getMainClass();this.launch(args, launchClass, classLoader);}protected void launch(String[] args, String launchClass, ClassLoader classLoader) throws Exception {Thread.currentThread().setContextClassLoader(classLoader);this.createMainMethodRunner(launchClass, args, classLoader).run();}//Archive相关代码
}
3)、Archive:归档文件获取Mainifest等URL路径(jar包中包含jar,或者jar包中class文件,那么会使用 !/ 分隔开)
public class JarFileArchive implements Archive {public URL getUrl() throws MalformedURLException {return this.url != null ? this.url : this.jarFile.getUrl();}public Manifest getManifest() throws IOException {return this.jarFile.getManifest();}
}
public class JarLauncher extends ExecutableArchiveLauncher {static final Archive.EntryFilter NESTED_ARCHIVE_ENTRY_FILTER = (entry) -> {return entry.isDirectory() ? entry.getName().equals("BOOT-INF/classes/") : entry.getName().startsWith("BOOT-INF/lib/");};public JarLauncher() {}protected JarLauncher(Archive archive) {super(archive);}protected boolean isPostProcessingClassPathArchives() {return false;}protected boolean isNestedArchive(Archive.Entry entry) {return NESTED_ARCHIVE_ENTRY_FILTER.matches(entry);}protected String getArchiveEntryPathPrefix() {return "BOOT-INF/";}public static void main(String[] args) throws Exception {(new JarLauncher()).launch(args);}
} Launcher#launch
protected void launch(String[] args) throws Exception {if (!this.isExploded()) {JarFile.registerUrlProtocolHandler();}//自定义类加载器加载jar文件(通过active的urls加载jar文件)ClassLoader classLoader = this.createClassLoader(this.getClassPathArchivesIterator());String jarMode = System.getProperty("jarmode");//获取manifest文件的Start-Class类String launchClass = jarMode != null && !jarMode.isEmpty() ? "org.springframework.boot.loader.jarmode.JarModeLauncher" : this.getMainClass();//调用Start-Class类类main方法this.launch(args, launchClass, classLoader);
}protected void launch(String[] args, String launchClass, ClassLoader classLoader) throws Exception {Thread.currentThread().setContextClassLoader(classLoader);this.createMainMethodRunner(launchClass, args, classLoader).run();
}/*
* 调用manifest文件Start-Class类mian方法
*/
public class MainMethodRunner {private final String mainClassName;private final String[] args;public MainMethodRunner(String mainClass, String[] args) {this.mainClassName = mainClass;this.args = args != null ? (String[])args.clone() : null;}public void run() throws Exception {Class<?> mainClass = Class.forName(this.mainClassName, false, Thread.currentThread().getContextClassLoader());Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);mainMethod.setAccessible(true);mainMethod.invoke((Object)null, this.args);}
}
相关文章:
spring boot打的包直接运行
Spring Boot 提供了一个插件 spring-boot-maven-plugin 把程序打包成一个可执行的jar包,直接执行java -jar xxx.jar即可以启动程序 1、引用 spring-boot-maven-plugin插件 <build><plugins><plugin><groupId>org.springframework.boot<…...
移除元素-力扣
第一种解法,暴力解法,使用两个for循环一个进行遍历,一个进行覆盖,代码如下: class Solution { public:int removeElement(vector<int>& nums, int val) {int size nums.size();for(int i 0; i < size; …...
代码随想录算法训练营第三天| 203.移除链表元素、 707.设计链表、 206.反转链表
203.移除链表元素 题目链接: 203.移除链表元素 文档讲解:代码随想录 状态:没做出来,做题的时候定义了一个cur指针跳过了目标val遍历了一遍链表,实际上并没有删除该删的节点。 错误代码: public ListNode re…...
【题解】AB33 相差不超过k的最多数(排序 + 滑动窗口)
https://www.nowcoder.com/practice/562630ca90ac40ce89443c91060574c6?tpId308&tqId40490&ru/exam/oj 排序 滑动窗口 #include <iostream> #include <vector> #include <algorithm> using namespace std;int main() {int n, k;cin >> n &…...
LSPatch免root手机模块应用
软件介绍 LSPatch是一款免root手机模块应用,兼容大部分机型,使用LSPatch,您可以个性化您的Android设备,添加新的功能,修改系统设置,甚至完全改变系统的外观。您可以根据自己的需求选择和安装各种Xposed模块…...
深入解析kube-scheduler的算法自定义插件
目录 编辑 一、问题引入 二、自定义步骤 三、最佳实践考虑 一、问题引入 当涉及到 Kubernetes 集群的调度和资源分配时,kube-scheduler 是一个关键组件。kube-scheduler 负责根据集群的调度策略,将 Pod 分配到适当的节点上。kube-scheduler 默认使…...
java原型模式 (Prototype Pattern) 介绍
原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有的实例来创建新对象,而不是通过实例化类来创建对象。这个模式允许你创建对象时避免复杂的初始化步骤,并且能够动态地创建对象的副本。 原型模式的关键…...
LLama3 | 一. 本地 Web Demo 部署
前置工作 课程文档:Llama3-Tutorial/docs/hello_world.md at main SmartFlowAI/Llama3-Tutorial GitHub 1.安装vscode 2.安装vscode插件 Remote SSH 3.配置 VSCode 远程连接开发机 ssh连接开发机 进行端口映射 在开发机控制台中点击自定义服务,复…...
MariaDB 给指定列值自动加密(持久数据加触发器)
文章目录 代码插入时,自动加密更新时,自动加密查看触发器数据操作示例update数据取出解密取 注意一次尝试,看加密后数据长度 参考链接: 一篇非常好的讲解触发器的文章:示例、原理MySQL/MariaDB触发器。 用触发器自动加…...
深入理解Linux系统管理与网络配置高级指南
深入理解Linux系统管理与网络配置高级指南 目录 深入理解Linux系统管理与网络配置高级指南 一、Linux文件系统管理 二、Linux进程管理 三、Linux系统管理 四、Linux网络管理 五、Linux磁盘管理 一、Linux文件系统管理 1.1 文件和目录操作 在Linux中,一切皆…...
朴素贝叶斯+SMSSpamCollections
1. 打开 Jupyter 后,在工作目录中,新建一个文件夹命名为 Test01 ,并且在文件夹中导入数据 集。在网页端界面点击 “upload” 按钮,在弹出的界面中选择要导入的数据集。然后数据集出现 在 jupyter 文件目录中,此时…...
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
文章目录 一、前言二、绘制效果三、ConstraintLayout 使用方法3.1 创建布局文件3.2 替换配置3.3 设置约束,步骤13.4 设置约束,步骤23.5 其他设置 四、结束 一、前言 在进行Android APP开发过程中,减少layout嵌套即可改善UI的绘制性能&#x…...
深度神经网络详解
深度神经网络详解 一、引言二、深度神经网络的基本概念1. 什么是神经网络2. 深度神经网络的定义3. 基本结构4. 激活函数 三、深度神经网络的发展历史1. 初期发展2. 反向传播算法的提出3. 深度学习的崛起 四、深度神经网络的架构1. 前馈神经网络(Feedforward Neural …...
MYSQL 数据迁移利器 MYSQLSH
1 迁移背景 将数据库从mysql5.7 迁移到mysql8.0. mysqlsh 支持mysql5.7以上版本。 2 查看数据量 SELECT TABLE_SCHEMA, round(SUM(data_length+index_length)/1024/1024,2) AS TOTAL_MB, round(SUM(data_length)/1024/1024,2) AS DATA_MB, …...
【MYSQL】分数排名
表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- id 是该表的主键(有不同值的列)。 该表的每一行都包含了一场比赛的分数。Score 是…...
【论文笔记】| 蛋白质大模型ProLLaMA
【论文笔记】| 蛋白质大模型ProLLaMA ProLLaMA: A Protein Large Language Model for Multi-Task Protein Language Processing Peking University Theme: Domain Specific LLM Main work: 当前 ProLLM 的固有局限性:(i)缺乏自然…...
MySQL笔记第一天(从小白到入门)
文章目录 MySQL笔记SQL语言介绍数据库系统关系型数据库非关系型数据库SQL和数据库系统的关系数据库系统架构 MySQL的介绍概念MySQL的版本 MySQL的DDL操作-重点基本数据库操作基本表操作 MySQL的DML操作-重点insert-插入数据update-更新数据delete-删除数据 MySQL的约束-了解概述…...
初识Qt:从Hello world到对象树的深度解析
Qt中的对象树深度解析 Hello world1.图形化界面创建命令行式创建在栈上创建在堆上创建为什么传文本需要QString,std::string不行吗?那为什么要传入this指针?为什么new后不用显示调用delete函数呢,不会造成内存泄漏问题吗ÿ…...
多维数据库创建
多维数据库 小白的数据仓库学习笔记 2024/5/21 上午 文章目录 多维数据库Cube的作用:什么是多维数据库维的级别多维数据分析方法如何构建多维数据集?创建项目创建数据源创建数据源视图创建多维数据集维度表中缺失的值拖拽过去建立维度结构设计类型启动连…...
win11安装docker运行Open-Webui 界面化展示 ollama大模型
1.OpenWeb UI运行需要docker 环境下载docker Get Started | Docker 2.需要命令提示符docker -v 查询是否安装成功; 查询docker详情docker version 3.github拉取open-webUi镜像Package open-webui GitHub 复制命令运行在命令提示符; 等待下载完成 4.到…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...
