Spring Boot Loader源码分析

分析Spring Boot Loader源码其实就是在搞懂为何Spring Boot打成jar包可以直接运行起来。

一)、探索从解压jar包开始

解压项目打包成的jar包,我们可以得到三个文件夹

  • BOOT-INF,内部还有两个文件夹classes(存放项目相关字节码文件)和lib(存放项目所依赖第三方jar包)

  • META-INF,关于项目的一些元数据

    Manifest-Version: 1.0
    Implementation-Title: spring_boot_dissect
    Implementation-Version: 1.0
    Start-Class: top.yangzefeng.dissect.SpringBootDissectApplication
    Spring-Boot-Classes: BOOT-INF/classes/
    Spring-Boot-Lib: BOOT-INF/lib/
    Build-Jdk-Spec: 1.8
    Spring-Boot-Version: 2.2.7.RELEASE
    Created-By: Maven Archiver 3.4.0
    Main-Class: org.springframework.boot.loader.JarLauncher
    
  • org,其实是 Spring Boot 提供的 spring-boot-loader 项目,即便我们项目中并没有明确指定loader的存在,但Spring Boot也会帮我们将其代码拷贝放到jar包内。

    <!-- 如果需要研究loader的源码,我们还得在pom.xml中引入相关依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-loader</artifactId>
        <version>2.2.7.RELEASE</version>
    </dependency>
    

二)、loader源码分析从JarLauncher出发

我们解压jar包得到META-INF文件夹,查看META-INF文件夹的MANIFEST.MF文件内容。

最为关键的两个属性:

  • Start-Class,为我们项目启动类的全类路径
  • Main-Class,为JarLauncher的全类路径,即Java规定的启动jar包类
Start-Class: top.yangzefeng.dissect.SpringBootDissectApplication
Main-Class: org.springframework.boot.loader.JarLauncher

由Main-Class的属性值,我们可以得出,要想分析Spring Boot Loader的源码,得从org.springframework.boot.loader.JarLauncher开始。

三)、JarLauncher

/**
 * {@link Launcher} for JAR based archives. This launcher assumes that dependency jars are
 * included inside a {@code /BOOT-INF/lib} directory and that application classes are
 * included inside a {@code /BOOT-INF/classes} directory.
 */
public class JarLauncher extends ExecutableArchiveLauncher {
   
	public JarLauncher() {
   
	}

	public static void main(String[] args) throws Exception {
   
		new JarLauncher().launch(args);
	}
}

从JarLauncher的main方法开始。

  • 1、创建JarLauncher对象,我们可以看到,JarLauncher的无参构造方法没有代码,但由于JarLauncher类继承了ExecutableArchiveLauncher抽象类,所以会调用ExecutableArchiveLauncher的无参构造方法。

  • 2、ExecutableArchiveLauncher的无参构造方法主要是为了创建JarFileArchive对象并进行字段赋值。

    其中createArchive()由Launcher进行调用。

    public abstract class ExecutableArchiveLauncher extends Launcher {
         
    	private final Archive archive;
        
    	public ExecutableArchiveLauncher() {
         
    		try {
         
    			this.archive = createArchive();
    		}
    		catch (Exception ex) {
         
    			throw new IllegalStateException(ex);
    		}
    	}
    }
    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值