浅析Spring Boot中的spring-boot-load模块

作者:并发编程网 - ifeve.com 时间:2023-11-23 02:39:31 

一、前言

正常情况下classloader只能找到jar里面当前目录或者文件类里面的*.class文件。为了能够加载嵌套jar里面的资源之前都是把嵌套jar里面的class文件和应用的class文件打包为一个jar,这样就不存在嵌套jar了,但是这样做就不能很清晰的知道应用到底依赖了哪些东西,哪些是应用自己的,另外多个jar里面的class可能内容不一样但是文件名却一样。springboot中spring-boot-loader就是为优雅解决这个问题而诞生的。

spring-boot-loader模块允许我们使用java -jar archive.jar运行包含嵌套依赖jar的jar或者war文件,它提供了三种类启动器 (JarLauncher, WarLauncher and PropertiesLauncher),这些类启动器的目的一样都是为了能够加载嵌套在jar里面的资源(比如class文件,配置文件等)。[Jar|War]Launcher固定去查找当前jar的lib目录里面的嵌套jar文件里面的资源。

二、spring-boot-loader模块提供的jar目录结构

Springboot中jar文件格式固定如下:


archive.jar
|
+-META-INF(1)
| +-MANIFEST.MF
+-org(2)
| +-springframework
| +-boot
| +-loader
|  +-<spring boot loader classes>
+-com(3)
| +-mycompany
| + project
| +-YouClasses.class
+-lib(4)
+-dependency1.jar
+-dependency2.jar
  • 结构(1)jar文件中MANIFEST.MF文件存放处

  • 结构(2) Spring-boot-loader本身需要的class放置处

  • 结构(3) 应用本身的文件放置处

  • 结构(4)应用依赖的jar固定放到lib目录。

那么spring-boot是如何去按照这个结构加载资源那?

  • 首先在打包时候会使用spring-boot-maven-plugin插件重写打成的jar文件,会设置META-INF/MANIFEST.MF中的


Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.mycompany.project.MyApplication

并拷贝spring-boot-loader包里面的class文件到结构(2),应用依赖拷贝到(4)应用类拷贝到(3)

  • 通过java -jar archive.jar 运行时候Launcher会去加载JarLauncher类并执行其中的main函数,JarLauncher主要关心构造一个合适的URLClassLoader加载器用来调用我们应用程序(MyApplication)的main方法。

三、spring-boot-maven-plugin插件打包流程分析

浅析Spring Boot中的spring-boot-load模块 

注:这里需要思考下为何要拷贝本来应该放入到lib里面的spring-boot-loader.jar里面的class到结构(2)?

四、JarLauncher执行流程分析

浅析Spring Boot中的spring-boot-load模块 

看完这个流程在分析下第三节留的问题,如流程图首先使用Appclassloader加载了JarLauncher类并创建了LaunchedURLClassLoader类,而LaunchedURLClassLoader是属于spring-boot-loader.jar包里面的,而Appclassloader是普通的加载器不能加载嵌套的jar里面的文件,所以如果把spring-boot-loader.jar放到lib 目录下,Appclassloader将找不到LaunchedURLClassLoader。所以在打包时候

拷贝本来应该放入到lib里面的spring-boot-loader.jar里面的class到结构(2)。

五、总结

spring-boot-load模块通过自定义jar包结构自定义类加载器优雅的实现了嵌套jar资源的加载,通过打包时候重新设置启动类和组织jar结构,通过运行时设置自定义加载器来实现嵌套jar资源加载。

来源:http://ifeve.com/spring-boot-loader/

标签:spring,boot,load,模块
0
投稿

猜你喜欢

  • Java二维数组计算集合总结

    2023-02-15 16:38:14
  • java根据不同的参数调用不同的实现类操作

    2021-11-08 17:05:16
  • 使用 C# 下载文件的多种方法小结

    2023-11-08 06:59:37
  • C#隐藏手机号、邮箱等敏感信息的实现方法

    2023-12-08 17:17:45
  • java实现递归菜单树

    2023-02-01 00:03:06
  • Android下载进度监听和通知的处理详解

    2022-03-27 08:39:02
  • Java API文档的使用方法详解

    2022-06-15 20:12:03
  • 详解C#读取Appconfig中自定义的节点

    2022-07-16 08:30:38
  • Java多线程 ThreadLocal原理解析

    2022-11-15 12:48:50
  • Java动态代理之拦截器的应用

    2022-11-24 11:18:55
  • SpringBoot如何接收Post请求Body里面的参数

    2023-07-30 13:43:35
  • Jmeter自定义函数base64加密实现过程解析

    2021-10-21 14:04:00
  • logback过滤部分日志输出的操作

    2023-10-16 21:45:50
  • android实现圆环倒计时控件

    2021-12-15 20:55:54
  • Spring @EventListener 异步中使用condition的问题及处理

    2023-07-07 21:42:16
  • C#学习笔记- 浅谈数组复制,排序,取段,元组

    2021-10-21 00:50:58
  • C#开发Android百度地图手机应用程序(多地图展示)

    2022-01-06 00:47:51
  • C#实现PDF文件添加图片背景

    2022-04-03 20:45:35
  • java面试常问的Runnable和Callable的区别

    2023-11-23 09:23:28
  • 实例讲解C#中的职责链模式

    2021-06-05 23:37:44
  • asp之家 软件编程 m.aspxhome.com