企业注册网站域名,wordpress获取页面文章内容的代码,江西网站设计团队,青岛市城市建设档案馆网站jar -jar运行原理
1.前言
阅读这篇文章你将知道
jar包是如何被jvm加载#xff0c;并运行起来的。 jvm的classload如何进行加载 springboot对象的生命周期啥时候开始的
2.提问
平时我对于java代码是如何运行起来的缺少认知#xff0c;那么java代码是如何运行起来的呢并运行起来的。 jvm的classload如何进行加载 springboot对象的生命周期啥时候开始的
2.提问
平时我对于java代码是如何运行起来的缺少认知那么java代码是如何运行起来的呢
3.前置知识
jvm类加载原理双亲委派基金二进制字节码spi知识点需要复习jar包的结构
jar包的结构如下
run.jar |——org | |——springframework | |——boot | |——loader | |——JarLauncher.class | |——Launcher.class |——META-INF | |——MANIFEST.MF |——BOOT-INF | |——class | |——Main.class | |——Begin.class | |——lib | |——commons.jar | |——plugin.jar | |——resource | |——a.jpg | |——b.jpg
4.运行原理
在idea中我们点击运行其实经历了以外几步1.clean-compile→install其实就是编译和打包得到一个jar包
编译的过程其实就是将java代码编译成一个一个.class文件二进制字节码这个也是jvm的一个优点二进制字节码是脱离语言而存在的这里就能体现一次编码到处都可以运行。 java真正运行起来是通过jar -jar来进行的那么jar -jar完会直接去找Main-Class
即找到META-INF下面的MANIFEST.MF文件里的Main-Class的属性值。也就是org.springframework.boot.loader.JarLauncher,这是一个用于jar这种归档文件的启动器它的直接父类是ExecutableArchiveLauncher类这个父类有两个子类另一个是WarLauncher然后会执行里面一个入口方法也就是main方法
main方法里创建了一个JarLauncher实例并执行了它的一个launch方法这个方法位于父类Launcher类中,通过一个getClassPathArchives方法获取到我们执行的那个jar归档文件
然后通过getNestedArchives方法获取到boot-inf里面的第三方jar包和项目中的信息也就是嵌套的jar文件随后创建一个LaunedURLClassloader自定义类加载器把Launcher这个类的类加载器作为它的父类加载器并且把线程上下文类加载器设置成该类加载器这个类加载器是springboot自定义的类加载器用于加载jdk提供的类加载器所加载不到的被嵌套的jar文件和项目类信息,
拿到Start-class的属性值也就是我们自己定义的springbootapplication的启动类用这个类加载器去加载这个启动类 接下来通过反射的方式去执行main方法
springbootapplication启动之后会进行spring对象生命周期的过程中通过autoconfigration还有扫描注解将bean加载到springfactory里面 注意jar -jar第一步是将所有的字节码存入内存但是并不是所有的内容都加载到classloader里面jvm是对特定的对象通过双亲委派来进行加载到内存的
5.classpath的几种读取方式
5.1 classpath是啥
classpath是存放.class文件的根路径这个根路径是如何获取到呢是在jdk源码classloader包里面有定义被定义为classloader的资源.
5.2 classpath的读取方式
由于classpath的数据来源是jdk,classloaderspring还有线程读取classload的方式都是异曲同工原理都是调用classload的getResource方法常用的方法有
5.2.1 class.getClassloader()
Class.getResource(String path)
path不以’/‘开头时默认是从此类所在的包下取资源path以’/‘开头时则是从项目的ClassPath根下获取资源。在这里’/‘表示ClassPath JDK设置这样的规则是很好理解的path不以’/‘开头时我们就能获取与当前类所在的路径相同的资源文件而以’/开头时可以获取ClassPath根下任意路径的资源。
5.2.2.classload.getResource()
Class.getClassLoader().getResource(String path)
path不能以’/‘开头时path是指类加载器的加载范围在资源加载的过程中使用的逐级向上委托的形式加载的’/表示Boot
5.2.3.resourceUtil.getURL(“classpath:”).getPath() (springboot的方式)
这种方式其实是封装了classload.getResouce方式即获取当前线程类加载器 然后去获取classloder的资源
6参考
https://blog.csdn.net/gml0000/article/details/105334331
https://blog.csdn.net/l18848956739/article/details/97514462