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周瑜,没有废话,全程干货。

相关推荐
武子康几秒前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
苏-言7 分钟前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
界面开发小八哥14 分钟前
更高效的Java 23开发,IntelliJ IDEA助力全面升级
java·开发语言·ide·intellij-idea·开发工具
草莓base27 分钟前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Allen Bright41 分钟前
maven概述
java·maven
Ljw...42 分钟前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改
编程重生之路43 分钟前
Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常
java·spring boot·后端
薯条不要番茄酱43 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
努力进修1 小时前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list
politeboy1 小时前
k8s启动springboot容器的时候,显示找不到application.yml文件
java·spring boot·kubernetes