SpringBoot中的LaunchedURLClassLoader的作用是什么?

我的公众号:IT周瑜

前几天有一个粉丝朋友问我:SpringBoot中的LaunchedURLClassLoader的作用是什么

今天抽时间给大家来分析分析,当我们在SpringBoot应用中引入spring-boot-maven-plugin后,执行mvn clean package命令,即可将SpringBoot应用打成一个可直接java -jar执行的Jar包,解压该Jar包看看里面的内容: BOOT-INF目录下主要包括classes和lib目录:

classes目录包括应用本身的字节码和配置文件: 而lib目录则包括了应用中第三方依赖

我们再来看MANIFEST.MF文件: 该文件的内容为:

  • 其中Spring-Boot-Classes和Spring-Boot-Lib对应的就是上面介绍的BOOT-INF目录下的classes和lib目录,表示当前应用用到的所有类
  • Start-Class:我们定义的应用启动类,com.zhouyu.MyApplication
  • Main-Class:真正的应用启动类,org.springframework.boot.loader.JarLauncher

基于Java基础知识,当我们运行java -jar hello-spring-boot.jar时,java命令会找Jar包中的MANIFEST.MF文件中指定的Main-Class,并执行它的main()方法,所以大家注意,最开始运行的是JarLauncher中的main()方法,而不是MyApplication中的main()方法,而JarLauncher类就在:

那为什么要多此一举呢?为什么Main-Class不直接为MyApplication呢?我们先看看org.springframework.boot.loader.JarLauncher中main()方法的实现: 在launch()方法中主要分为三步:

  1. 第一步,创建一个ClassLoader,具体类型为LaunchedURLClassLoader
  2. 第二步,找到真正的启动类,最后的getMainClass()取的就是Start-Class的值,也就是MyApplication类
  3. 第三步,会把上面创建的ClassLoader设置为线程上下文类加载器,并运行MyApplication中的main()方法,真正开始启动SpringBoot

也就是说,在执行java -jar hello-spring-boot.jar时,会先创建一个自定义类加载器LaunchedURLClassLoader,并且会成为线程上下文类加载器,然后再运行MyApplication的main()方法,也就是说在运行MyApplication的main()方法时遇到需要加载类时就会用LaunchedURLClassLoader来加载。

那为什么SpringBoot要自定义一个LaunchedURLClassLoader类加载器呢?

因为普通的类加载器只能加载Jar包中直接的类,而不能加载Jar包中的Jar包中的类 ,比如一个普通的Jar包内容为: 普通的类加载器能加载到MyAppliation和ZhouyuController两个类,但是如果这个Jar包中还有一个third.jar包,那么普通的类加载器则没办法加载third.jar中的类了,而SpringBoot想要的效果就是将应用的所有第三方依赖jar全部放在应用的Jar包中,也就是Jar包中包含Jar包,所以需要在启动的最开始自定义一个类加载器,后续就由这个自定义类加载器来加载BOOT-INF目录下的classes目录和lib目录下的类了。

比如hello-spring-boot.jar中就有一个JarFileArchive类,它里面就有一个unpack()方法,自然就是用来解压第三方Jar包并加载其中的类的:

我们也会把SpringBoot插件打出来的Jar叫做FatJar,因为它包含了很多第三方依赖,所以很胖,SpringBoot就像大家的父母,小时候上学,父母会在早上把你一天要用到的东西都准备好放在书包(FatJar)里,你需要时直接从书包里取就可以了,而不用额外再去家里或商店去取了。

我是大都督周瑜,欢迎关注我的公众号:IT周瑜,没有废话,全程干货。

相关推荐
程序猿DD14 分钟前
JUnit 5 中的 @ClassTemplate 实战指南
java·后端
爱吃山竹的大肚肚26 分钟前
EasyPOI 大数据导出
java·linux·windows
Victor35637 分钟前
Netty(14)如何处理Netty中的异常和错误?
后端
panzer_maus1 小时前
归并排序的简单介绍
java·数据结构·算法
Smartdaili China1 小时前
掌握Java网页抓取:技术与示例完整指南
java·网络·学习·指南·网页·住宅ip·爬虫api
Victor3561 小时前
Netty(13)Netty中的事件和回调机制
后端
程序员游老板2 小时前
基于SpringBoot3_vue3_MybatisPlus_Mysql_Maven的社区养老系统/养老院管理系统
java·spring boot·mysql·毕业设计·软件工程·信息与通信·毕设
码事漫谈2 小时前
VS Code 1.107 更新:多智能体协同与开发体验升级
后端
福尔摩斯张2 小时前
C++核心特性精讲:从C语言痛点出发,掌握现代C++编程精髓(超详细)
java·linux·c语言·数据结构·c++·驱动开发·算法