面试官:讲讲为什么SpringBoot的 jar 可以直接运行?

Spring Boot 是一个用于简化 Spring 应用程序开发的框架,它通过约定优于配置和大量的自动化配置,使得开发者可以更轻松地创建和部署 Spring 应用程序。一个特别引人注目的特性是 Spring Boot 应用可以打包成一个可执行的 JAR 文件,并且可以直接运行。这篇文章将详细介绍为什么 Spring Boot 的 JAR 可以直接运行,以及它背后的实现原理。

一、可执行 JAR 概述

通常,Java 应用程序需要通过 java -jar 命令来运行 JAR 文件。而 Spring Boot 应用程序的 JAR 文件不仅包含了应用程序的字节码和依赖库,还包含了一个内嵌的服务器(如 Tomcat 或 Jetty),使得它们可以通过直接运行 JAR 文件来启动整个应用。

示例代码

一个简单的 Spring Boot 应用如下:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

构建后的 JAR 文件可以通过以下命令直接运行:

java -jar demo-0.0.1-SNAPSHOT.jar

二、Spring Boot 可执行 JAR 的实现原理

1. 内嵌服务器

Spring Boot 将内嵌服务器(如 Tomcat)作为依赖打包进应用程序的 JAR 文件中。这样,无需额外配置或安装服务器即可运行应用程序。

pom.xml 中,我们可以看到嵌入式 Tomcat 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. 特殊的 JAR 结构

Spring Boot 的可执行 JAR 文件采用了一种特殊的结构,包含以下几个部分:

  • **BOOT-INF/classes/:**包含应用程序的类文件。
  • **BOOT-INF/lib/:**包含应用程序的依赖 JAR 文件。
  • **META-INF/MANIFEST.MF:**包含启动类信息和类路径信息。

JAR 文件结构示例:

demo-0.0.1-SNAPSHOT.jar
├── BOOT-INF/
│   ├── classes/
│   └── lib/
├── META-INF/
└── org/

3. 自定义类加载器

Spring Boot 使用 LaunchedURLClassLoader 类加载器来加载 BOOT-INF/classesBOOT-INF/lib 下的资源。这种自定义类加载器能够处理特殊的 JAR 文件结构。

以下是 LaunchedURLClassLoader 的简化示例:

public class LaunchedURLClassLoader extends URLClassLoader {
    public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    @Override
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // 自定义类加载逻辑
    }
}

4. 启动脚本

Spring Boot JAR 文件包含一个特殊的启动脚本,这个脚本由 org.springframework.boot.loader.JarLauncher 类实现。JarLauncher 是 Spring Boot 的启动入口,它负责引导 Spring 应用程序。

JarLauncher 类的简化示例:

public class JarLauncher extends Launcher {
    @Override
    protected void launch(String[] args) throws Exception {
        // 设置类加载器并启动应用
    }

    public static void main(String[] args) throws Exception {
        new JarLauncher().launch(args);
    }
}

5. MANIFEST.MF 文件

MANIFEST.MF 文件中包含了启动类信息:

Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.demo.DemoApplication

三、构建和运行示例

1. 创建 Spring Boot 项目

使用 Spring Initializr 创建一个新的 Spring Boot 项目:

curl https://start.spring.io/starter.zip -d dependencies=web -d baseDir=demo -d bootVersion=2.5.4 -o demo.zip
unzip demo.zip
cd demo

2. 添加示例代码

src/main/java/com/example/demo/DemoApplication.java 文件中添加以下代码:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

3. 构建 JAR 文件

使用 Maven 构建 JAR 文件:

mvn clean package

构建成功后,目标目录下会生成一个可执行的 JAR 文件:

ls target/demo-0.0.1-SNAPSHOT.jar

4. 运行 JAR 文件

直接运行生成的 JAR 文件:

java -jar target/demo-0.0.1-SNAPSHOT.jar

浏览器中访问 http://localhost:8080,可以看到应用程序已成功运行。

结语

Spring Boot 通过内嵌服务器、自定义类加载器和特殊的 JAR 结构,使得应用程序可以打包成一个可执行的 JAR 文件,并且能够直接运行。这种机制极大地方便了应用程序的部署和管理。希望这篇文章能帮助你更好地理解 Spring Boot 可执行 JAR 的实现原理。

个人观点,仅供参考。


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新计划,不断变更!做自己,接受不美好!猪肝移植——早读(逆天打工人爬取热门微信文章解读)

时间不等人 引言Python 代码第一篇 做自己&#xff0c;没有很好也没关系第二篇结尾 引言 新计划&#xff1a; 早上一次性发几个视频不现实 所以更改一下 待后面有比较稳定的框架再优化 每天早上更新 早到8点 晚到10点 你刚刚好上班或者上课 然后偷瞄的看两眼 学习一下 补充知…

吴恩达2022机器学习专项课程C2W2:2.22 多类 softmax softmax与神经网络 softmax的代码改良 多标签分类

目录 多分类问题1.什么是多分类问题2.多分类问题案例3.二分类与多分类的区别 Softmax1. 什么是Softmax2.逻辑回归预测的计算过程3. Softmax预测的计算过程4.Softmax 回归与逻辑回归的关系5. Softmax的损失函数 softmax与神经网络1.设置Softmax层2.Softmax层的计算3.softmax激活…

Yolov5——训练目标检测模型详解(含完整源码)

项目的克隆 打开yolov5官网&#xff08;GitHub - ultralytics/yolov5 at v5.0&#xff09;&#xff0c;下载yolov5的项目&#xff1a; 环境的安装&#xff08;免额外安装CUDA和cudnn&#xff09; 打开anaconda的终端&#xff0c;创建新的名为yolov5的环境&#xff08;python选…

源码编译安装LAMP(安装apeche mysql php 论坛 网站 巨详细版)

目录 一.LAMP架构相关概述 1.各组件作用 Linux&#xff08;平台&#xff09; Apache&#xff08;前台&#xff09; MySQL&#xff08;后台&#xff09; PHP/Perl/Python&#xff08;中间连接&#xff09; 总结 二.编译安装Apache httpd服务 1.关闭防火墙&#xff0c;将…

DMPO -- Stressmarq

货号&#xff1a;SIH-324 名称&#xff1a;DMPO 规格&#xff1a;25mg、125mg 产品描述&#xff1a; 自由基和其他高活性氧的形成与许多疾病状态的发病机制有关。识别这些物种的能力至关重要&#xff0c;而自旋诱捕已经完成了这一目标。DMPO&#xff08;5&#xff0c;5-二甲…

分析训练全球 2k+ 水文站数据,中科院团队发布 ED-DLSTM,实现无监测数据地区洪水预测

随着全球气候变化&#xff0c;洪水灾害正变得愈发频繁。联合国减少灾害风险办公室与比利时鲁汶大学灾害流行问题研究中心联合发布的报告指出&#xff1a;过去 20 年间&#xff0c;全球洪水灾害数量从 1,389 起上升到 3,254 起&#xff0c;增加了超两倍&#xff0c;占到灾害总数…

第一届 长城杯 总决赛wp

第一届 长城杯 总决赛 - Ahisec 第一阶段 Zip_guessinteger 第一层bkcrack攻击部分明文&#xff0c;注意偏移 ​ ┌──(root㉿Ten)-[~/tools/Misc/bkcrack] └─# ./bkcrack -C zip_guessinteger.zip -c breakthroughentry.txtflag.txt.zip -p 1.txt -o 30 bkcrack 1.6.1 …

一个给新手进阶的IAT加密壳

前言 这篇文章中介绍了IAT加壳与解壳的全过程&#xff0c;并用Ollydbg进行逆向分析&#xff0c;说明这个壳的鸡肋的之处&#xff0c;最后给出了核心源代码。 必备基础 必须很熟悉PE结构&#xff0c;特别是导入表的双桥结构。 IAT(Import Address Table)&#xff0c;导入地址…

Shiro+Jwt+Redis

如何整合ShiroJwtRedis&#xff0c;以及为什么要这么做 我个人认为 ①为什么用shiro&#xff1a;“ShiroJwtRedis”模式和“单纯的shiro”模式相比&#xff0c;主要用的是shiro里面的登录认证和权限控制功能 ②为什么用jwt&#xff1a;“ShiroJwt”模式和“ShiroCookie”模式相…

怎么搭建微信留言板功能

在信息爆炸的时代&#xff0c;微信已经成为了我们日常生活中不可或缺的一部分。它不仅仅是一个简单的聊天工具&#xff0c;更是一个充满无限可能的营销平台。今天&#xff0c;我要向大家介绍的是如何在你的微信平台上搭建一个独具特色的留言板功能&#xff0c;让用户能够自由发…

【Flutter】Dialog组件PageView组件

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Flutter学习 &#x1f320; 首发时间&#xff1a;2024年5月27日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; 目…

需求跟踪矩阵是什么?怎么创建?一文详解

一、什么是需求跟踪矩阵 对项目经理或产品经理来说&#xff0c;需求清单肯定不陌生&#xff0c;那什么是需求跟踪矩阵呢&#xff1f; 需求跟踪矩阵&#xff08;Requirement Track Matrix&#xff0c;简称RTM &#xff09;&#xff0c;是把产品需求从其来源连接到能满足需求的…

Spring中@Component注解

Component注解 在Spring框架中&#xff0c;Component是一个通用的注解&#xff0c;用于标识一个类作为Spring容器管理的组件。当Spring扫描到被Component注解的类时&#xff0c;会自动创建一个该类的实例并将其纳入Spring容器中管理。 使用方式 1、基本用法&#xff1a; Co…

[AI OpenAI] OpenAI 安全更新

AI 首尔峰会中分享我们的实践 我们自豪地构建并发布了在能力和安全性方面都处于行业领先地位的模型。 超过一亿用户和数百万开发者依赖于我们安全团队的工作。我们将安全视为我们必须在多个时间范围内投资并取得成功的事项&#xff0c;从使今天的模型与我们未来预期的更具能力…

【Spring Cloud】远程调用

目录 Spring Cloud Netflix Feign简介前言Feign是什么OpenFeign组件和Spring Cloud OpenFeignOpenFeign组件Spring Cloud OpenFeign OpenFeign-微服务接口调用需求说明1. 启动Eureka Server服务2.创建两个项目&#xff0c;将其注册到Eureka Server3.在服务提供者中添加业务处理…

如何处理逻辑设计中的时钟域

1.什么是时钟域 2.PLL对时钟域管理 不管是否需要变频变相&#xff0c;在FPGA内部将外部输入时钟从专用时钟引脚扇入后先做PLL处理。如何调用pll&#xff0c;见另一篇文章。 约束输入时钟 creat_clock -period 10 -waveform {0 5} [get_ports {sys_clk}] 3.单bit信号跨时钟…

【Linux进程篇】父子进程fork函数||进程生死轮回状态||僵尸进程与孤儿进程

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;上篇文章中我们认识了进程&#xff0c;可执行程序在内存中加载运行被称作进程&#xff0c;而操作系统是通过给每一个可执行程序创建一个PCB来管理进程的。并且学习了一些查看进程的指令&#xff0c;认识…

Flask 蓝图路由的模块化开发

基于 Flask 蓝图路由的模块化开发 1. 编程目标 为了提高Flask应用的可维护性和可扩展性&#xff0c;我们通过使用Flask的蓝图(Blueprint)功能&#xff0c;可以将不同的功能模块拆分到独立的文件中&#xff0c;方便后续的开发和维护。 2. 项目结构 项目结构树如下&#xff1…

助力企业标准化搭建--图框模板的创建

古有秦皇书同文、车同轨&#xff0c;今各行各业都有国际标准、国家标准&#xff0c;其目的就是为了标准化、统一化&#xff0c;由此可见标准化的重要性&#xff1b;一个企业若是想规范员工的操作&#xff0c;推行标准化也很重要&#xff1b;因此对于需要绘制电气图纸的行业来说…

从0开始学统计-秩和检验

1.什么是秩和检验&#xff1f; 秩和检验&#xff0c;也称为Wilcoxon 秩和检验&#xff0c;是一种非参数统计检验方法&#xff0c;用于比较两个独立样本的中位数是否有显著差异。它不要求数据满足正态分布假设&#xff0c;因此适用于小样本或者数据不满足正态分布假设的情况。 …