IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 学习第四篇:【SpringBoot-Labs】Jar 启动原理 -> 正文阅读

[Java知识库]学习第四篇:【SpringBoot-Labs】Jar 启动原理

本周(8.21-8.27)将学习芋道 Spring Boot的以下文章:
8.21: 快速入门
**8.22:**Spring Boot 自动配置原理 、Jar 启动原理
8.23:调试环境、 热部署入门、消除冗余代码 Lombok 入门
8.24:对象转换 MapStruct 入门、SpringMVC 入门
8.25: WebFlux 入门、 分布式 Session 入门
8.26:API 接口文档 Swagger 入门、API 接口文档 Swagger Starter 入门
8.27:参数校验 Validation 入门、WebSocket 入门

芋道 Spring Boot Jar 启动原理

  • Spring Boot 提供了 Maven 插件 spring-boot-maven-plugin,可以方便的将 Spring Boot 项目打成 jar 包或者 war 包。

  • Jar包的结构组成

    • META-INF 目录:通过 MANIFEST.MF 文件提供 jar 包的元数据,声明了 jar 的启动类。

    • org 目录:为 Spring Boot 提供的 spring-boot-loader 项目,它是 java -jar 启动 Spring Boot 项目的秘密所在,也是稍后我们将深入了解的部分。

      Spring Boot Loader provides the secret sauce that allows you to build a single jar file that can be launched using java -jar. Generally you will not need to use spring-boot-loader directly, but instead work with the Gradle or Maven plugin.

    • BOOT-INF/lib 目录:我们 Spring Boot 项目中引入的依赖jar 包们。spring-boot-loader 项目很大的一个作用,就是解决 jar 包里嵌套 jar 的情况,如何加载到其中的类。

      • spring-boot-loader 项目需要解决两个问题:
        • 第一,如何引导执行我们创建的 Spring Boot 应用的启动类,例如上述图中的 Application 类。
        • 第二,如何加载 BOOT-INF/class 目录下的类,以及 BOOT-INF/lib 目录下内嵌的 jar 包中的类。
    • BOOT-INF/classes 目录:我们在 Spring Boot 项目中 Java 类所编译的 .class、配置文件等等。

  • META-INF/MANIFEST.MF 文件,里面的内容如下:

    Manifest-Version: 1.0
    Implementation-Title: lab-39-demo
    Implementation-Version: 2.2.2.RELEASE
    Start-Class: cn.iocoder.springboot.lab39.skywalkingdemo.Application
    Spring-Boot-Classes: BOOT-INF/classes/
    Spring-Boot-Lib: BOOT-INF/lib/
    Build-Jdk-Spec: 1.8
    Spring-Boot-Version: 2.2.2.RELEASE
    Created-By: Maven Archiver 3.4.0
    Main-Class: org.springframework.boot.loader.JarLauncher
    
  • 实际是一个 Properties 配置文件,每一行都是一个配置项目。重点来看看两个配置项:

    • Main-Class 配置项:Java 规定的 jar 包的启动类,这里设置为 spring-boot-loader 项目的 JarLauncher 类,进行 Spring Boot 应用的启动。
    • Start-Class 配置项:Spring Boot 规定的启动类,这里设置为我们定义的 Application 类。

    小知识补充:为什么会有 Main-Class/Start-Class 配置项呢?因为我们是通过 Spring Boot 提供的 Maven 插件 spring-boot-maven-plugin 进行打包,该插件将该配置项写入到 MANIFEST.MF 中,从而能让 spring-boot-loader 能够引导启动 Spring Boot 应用。

    • 直接运行Start-Class 配置项的主启动类(main函数)是无法启动的(提示找不到或无法加载主类),主要是因为打包成的jar的不符合java默认加载jar包的规则(/WEB-INF/classes下的class文件,而Start-Class的Aplication类被打包在 BOOT-INF/classes下,其次Java 规定可执行器的 jar 包禁止嵌套其它 jar 包,而maven项目需要加载BOOT-INF/lib 目录下Spring Boot 应用依赖的所有 jar 包),所以需要通过spring-boot-loader 项目自定义实现了 ClassLoader 实现类 LaunchedURLClassLoader,支持加载 BOOT-INF/classes 目录下的 .class 文件,以及 BOOT-INF/lib 目录下的 jar 包。
  • JarLauncher 类是针对 Spring Boot jar 包的启动类,整体类图如下所示:

    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 {
    		new JarLauncher().launch(args);
    	}
    
    }
    

    通过 #main(String[] args) 方法,创建 JarLauncher 对象,并调用其 #launch(String[] args) 方法进行启动。整体的启动逻辑,其实是由父类 Launcher 所提供。

  • 简单来说,就是做一个可以读取 jar 包中类的加载器,保证 BOOT-INF/lib 目录下的类和 BOOT-classes 内嵌的 jar 中的类能够被正常加载到,之后执行 Spring Boot 应用的启动。

  • LaunchedURLClassLoaderspring-boot-loader 项目自定义的类加载器,实现对 jar 包中 META-INF/classes 目录下的META-INF/lib 内嵌的 jar 包中的加载

  • 总体来说,Spring Boot jar 启动的原理是非常清晰的,整体如下图所示:

    Spring Boot  启动原理

红色部分,解决 jar 包中的类加载问题:

  • 通过 Archive,实现 jar 包的遍历,将 META-INF/classes 目录和 META-INF/lib 的每一个内嵌的 jar 解析成一个 Archive 对象。
  • 通过 Handler,处理 jar: 协议的 URL 的资源读取,也就是读取了每个 Archive 里的内容。
  • 通过 LaunchedURLClassLoader,实现 META-INF/classes 目录下的类和 META-INF/classes 目录下内嵌的 jar 包中的类的加载。具体的 URL 来源,是通过 Archive 提供;具体 URL 的读取,是通过 Handler 提供。

橘色部分,解决 Spring Boot 应用的启动问题:

当然,上述的一切都是通过 Launcher 来完成引导和启动,通过 MANIFEST.MF 进行具体配置。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-23 16:31:00  更:2021-08-23 16:33:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:42:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码