java -jar 工作原理_可执行Jar包运行原理
spring boot有一个很方便的功能就是可以将应用打成可执行的jar。那么大家有没想过这个jar是怎么运行起来的呢?本篇博客就来介绍下spring boot可执行jar包的运行原理。
1. 打可执行jar包
将spring boot应用打成可执行jar包很容易,只需要在pom中加上一个spring boot提供的插件,然后在执行mvn package即可。
org.springframework.boot
spring-boot-maven-plugin
注意:
如果你的项目没有继承spring-boot-starter-parent这个pom,你需要做如下配置,将目标绑定到repackage。
org.springframework.boot
spring-boot-maven-plugin
repackage
关于这个插件的详细使用,可以参考官网
运行完mvn package后,我们会在target目录下看到两个jar文件。myproject-0.0.1-snapshot.jar和myproject-0.0.1-snapshot.jar.original。第一jar文件就是我们应用的可执行jar包,第二个jar文件是应用原始的jar包。
2. 可执行jar包内部结构
将打出来的可执行jar解压开我们能看到下面的结构:
可执行jar 目录结构
├─boot-inf
│ ├─classes
│ └─lib
├─meta-inf
│ ├─maven
│ ├─app.properties
│ ├─manifest.mf
└─org
└─springframework
└─boot
└─loader
├─archive
├─data
├─jar
└─util
我们先来重点关注两个地方:meta-inf下面的jar包描述文件和boot-inf这个目录。
manifest-version: 1.0
archiver-version: plexus archiver
built-by: xxxx
start-class: com.xxxx.appserver
spring-boot-classes: boot-inf/classes/
spring-boot-lib: boot-inf/lib/
spring-boot-version: 2.1.6.release
created-by: apache maven 3.3.9
build-jdk: 1.8.0_73
main-class: org.springframework.boot.loader.jarlauncher
在上面我们看到一个熟悉的配置main-class: org.springframework.boot.loader.jarlauncher。我们大概能猜到这个类是整个系统的入口。
再看下boot-inf这个目录下面,我们会发现里面是我们项目打出来的class文件和项目依赖的jar包。看到这里,你可能已经猜到spring boot是怎么启动项目的了。
3. jarlauncher
public class jarlauncher extends executablearchivelauncher {
static final string boot_inf_classes = "boot-inf/classes/";
static final string boot_inf_lib = "boot-inf/lib/";
public jarlauncher() {
}
protected jarlauncher(archive archive) {
super(archive);
}
@override
protected boolean isnestedarchive(archive.entry entry) {
if (entry.isdirectory()) {
return entry.getname().equals(boot_inf_classes);
}
return entry.getname().startswith(boot_inf_lib);
}
public static void main(string[] args) throws exception {
//项目入口,重点在launch这个方法中
new jarlauncher().launch(args);
}
}
//launch方法
protected void launch(string[] args) throws exception {
jarfile.registerurlprotocolhandler();
//创建launchedurlclassloader。如果根类加载器和扩展类加载器没有加载到某个类的话,就会通过launchedurlclassloader这个加载器来加载类。这个加载器会从boot-inf下面的class目录和lib目录下加载类。
classloader classloader = createclassloader(getclasspatharchives());
//这个方法会读取jar描述文件中的start-class属性,然后通过反射调用到这个类的main方法。
launch(args, getmainclass(), classloader);
}
4. 简单总结
spring boot可执行jar包的入口点是jarlauncher的main方法;
这个方法的执行逻辑是先创建一个launchedurlclassloader,这个加载器加载类的逻辑是:先判断根类加载器和扩展类加载器能否加载到某个类,如果都加载不到就从boot-inf下面的class和lib目录下去加载;
读取start-class属相,通过反射机制调用启动类的main方法,这样就顺利调用到我们开发的spring boot主启动类的main方法了。
5. 远程调试
这边介绍个调试jarlauncher启动的小技巧--idea 远程调试
step1:我们以下面的方式启动我们的spring boot应用
java -xdebug -xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=y -jar app.jar
step2:在idea中进行如下配置
然后点击下面的执行按钮执行即可:
希望与广大网友互动??
点此进行留言吧!
java -jar 工作原理_可执行Jar包运行原理相关推荐
- python程序运行原理_谈谈 Python 程序的运行原理
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,谈谈 Python 程序的运行原理 这篇文章准确说是『Python 源码剖析』的 ...
- 简述python程序的运行原理_谈谈 Python 程序的运行原理
执行 python demo.py 后,将会启动 Python 的解释器,然后将 demo.py 编译成一个字节码对象 PyCodeObject. 在 Python 的世界中,一切都是对象,函数也是对 ...
- Java Maven项目打包成可执行jar文件
在pom文件中添加一下内容 <build><plugins><plugin><!-- Build an executable JAR --><gr ...
- java虚拟机工作原理图_超“强”的图文详解-JVM虚拟机底层原理与调优实战
今天我和大家分享一篇文章,文章上半部分为JVM底层原理 下半部分为调优实战 文章有点长,需要点耐心哦! 如果觉得看文章太难理解,就点击下面我投稿B站的jvm视频讲解. 还配有视频讲解:解密BATJ一线 ...
- java线程工作原型_深度解析Java内存的原型及工作原理
本文主要通过分析Java内存分配的栈.堆以以及常量池详细的讲解了其的工作原理. 一.java虚拟机内存原型 寄存器:我们在程序中无法控制栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是 ...
- nexus3手动上传jar文件(包括不可执行jar打包配置)
前言 最近用nexus3管理工具jar包时,发现多模块依赖引用找不到依赖包,依赖包不会关联下载,一直以为是打包的问题,还尝试着把所有依赖都打进工具jar中,结果都无法正常启动项目,最后才发现是pom的 ...
- 海天食品的java开发工作如何_再三个月就秋招了,我想找一份java开发工作,现在应该怎么准备一下?...
在找工作之前,大家都要做一些准备工作,java开发也是如此 掌握核心JavaSE 首先,从核心Java(JavaSE)开始学习,尽可能地掌握它.你应该了解和掌握一些基本概念,如循环,数组,运算符等等. ...
- jar命令的使用与执行jar包
(1)jar命令模板 c:>jar cvfe test.jar test.Test test 把test目录下的所有文件都压缩到test.jar包中,并指定使用test.Test类(如果主类带包 ...
- mysql的sql执行原理图_性能测试MySQL之SQL运行原理
一,MySQL运行原理 两个一样的图 1,SQL语句执行的过程详细说明 如上图所示,当向MySQL发送一个请求的时候,MySQL到底做了什么: a, 客户端发送一条查询给服务器. b, 服务器先检查查 ...
最新文章
- QT打开和保存文件对话框
- 数据结构:关于重建二叉树的三种思路
- mysql now str,数据库学习之MySQL (十)—— 日期和时间函数 NOW STR_TO_DATE DATE_FORMAT 流程控制函数 IF IFNULL CASE...
- 第二周CoreIDRAW课总结
- 【转】C#数据结构-有限状态机
- linux-用户与组的概念
- 漫步最优化十二——局部极小与极大的充分必要条件(下)
- EJB3.0学习笔记---Bean实现多个接口的情况下定义,访问方式:
- 解决Spark集群无法停止
- dns114.114.114..114
- android 获取类对象(代码片段)
- 索辰科技在科创板过会:拟募资金额有所下调,上半年亏损4000万元
- jsp自定义标签的问题Unable to load tag handler class
- A Transformer-based Approach for Source code Summarization 翻译
- 弗洛伊德算法注意项 floyd
- 国庆七天假期就剩下最后一天了
- VCNL4040传感器
- 新学期 新目标 新征程
- 《智慧书》格言11¬20
- 反序列化漏洞分析讲解
热门文章
- vue 多层表格嵌套
- 用C语言实现2的次方运算
- 1、解决Access连接 accdb 不可识别的数据库格式异常
- 壮美大山包-2017中国大山包国际超百公里ITRA积分赛赛记
- r语言 read_html,R语言外部数据读取(示例代码)
- vba 引用Sheet的几种方法
- Android 进阶之探索 OkHttp 原理
- 射频layout设计笔记
- CS品牌SD NAND在车联网行业中的应用案例
- chrome浏览器出现Uncaught DOMException: Failed to execute ‘postMessage‘ on ‘Window‘: HTMLUnknownElement ob