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

相关推荐
ok!ko3 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2401_857622663 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589364 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰4 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没5 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch5 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
编程、小哥哥5 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
IT学长编程6 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
莹雨潇潇6 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
杨哥带你写代码7 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端