springboot源码学习笔记之进入之前发生了啥

人称: 露哥
QQ: 408365330
N01.编程就是验证学习的最好方式
N02.为了挣钱所以编程,为了挣大钱所以写好代码,为了写好代码所以学习
N03.好好学习天天编程

springboot源码学习笔记之进入之前发生了啥

虽然用springboot也有一段时间,但是之前也没怎么关注过springboot项目打包过程中发生了什么,启动过程细节是什么!
直到最近在搞公司的私有化大平台时需要了解更多的本质上的东西才细细品味了一下springboot的源码,从起源开始……

springboot 程序长啥样(身材和脸蛋)?

@SpringBootApplication
@EnableAutoConfiguration
public class EgojitApplication {
	public static void main(String[] args) {
		SpringApplication.run(EgojitApplication.class, args);
	}
}

我第一眼看到特别亲切,这就是一个main程序啊;然后再看一眼,好像比普通的main上面多了两个注解,总以为两眼就了解她,和普通的main也没什么不同么啊,其实只是了解了身材和脸蛋;需要三回眸免得错过什么精彩内容;然后我使用 spring-boot-maven-plugin 进行打包;生成一个jar包;既然要深入了解她的“品质”啊,那就得由内而外;unzip 这个美丽的jar吧;

springboot的jar包内在(品质)

名词说明

我们这里把由 spring-boot-maven-plugin maven插件打包的jar包称为“胖jar”或者“聚合jar”(不仅仅只有这一种打包胖jar的方式,我们约定胖jar就是spring-boot-maven-plugin插件打包的jar包,我喜欢约定),把maven-jar-plugin 默认打包出来的jar包称为“瘦jar”或者“散jar”

  • 胖jar/聚合jar
    整个项目会打包成一个jar包,所有的依赖jar包被打进一个jar包

  • 瘦jar/散jar
    整个项目jar包是散的,依赖的包和项目主class或者jar是平行的

N01 有内涵

springboot的jar包 BOOT-INF
unzip后发现这个和普通的main程序jar包完全不同啊,包含BOOT-INF,META-INF,org三个目录;然后可以看见BOOT-INF/classes才是真正的classpath,而传统的jar包直接解压后就是classpath

N02 有特色

springboot的jar包 MAINFEST.MF
META-INF目录中我重点关注MANIFEST.INF文件,我看到了我不敢相信的一幕,她和普通main区别大大的,她可不是表面上看到的那样,入口main在JarLauncher中(记住它后面我们分析spring-boot-loader源码从它入手);所以我推翻我之前的认知springboot的xxxApplicaion中的main不是普通的main。它只是一个被xxxApplicion调用的普通方法而已;和普通的MANIFEST.INF不同它还有一个Start-Class,不要怀疑这个就是我们写的xxxApplicaion; Spring-Boot-Classes指出了springboot的特殊class目录;Spring-Boot-Lib配置第三方依赖包目录

N03 超仙

springboot的jar包

org目录有点神奇,出现了超自然现象啊,我的项目绝对没有org.springframework.boot包啊。它从哪里来的?我怀疑人生的打开项目依赖找了一遍,我确定它是超自然现象,好仙,不是我等凡人容易理解的;我想到既然我没干什么,那就绝对是打包干的,谁打包?????
spring-boot-maven-plugin 对!就是它,被我逮到了;它把项目打包成我们看到的目录结构,同时把spring-boot-loader jar包中的class拷贝到项目中了;

spring-boot-loader 分析

以下是JarLauncher执行流程分析

JarLauncher执行流程

通过源码分析流程可以知道spring-boot-load模块通过自定义jar包结构自定义类加载器优雅的实现了嵌套jar资源的加载,通过打包时候重新设置启动类和组织jar结构,通过运行时设置自定义加载器来实现嵌套jar资源加载;
知道这些我们可以实现自己的JarLauncher实现Archive动态指定实现插件化;既然spring-boot-loader能指定lib以及class目录,那么我们也可以实现自己的JarLauncher合并更多的lib目录,实现外部扩展lib,再结合spring boot中的spring.factries的原理扫描注入代码;公司的私有化平台中的应用托管就是我在研究spring-boot-loader这种原理结合spring boot中的spring.factries的机制基础上实现的;改造了原来基于java的jagent方式。这种方案解决了很多问题;其中第三方springboot应用日志采集,性能监控,健康检查等等都可以基于这个机制去实现(了解这个原理多么重要);更多的就涉密了……。哈哈……

原文地址:https://www.cnblogs.com/qlsy/p/9607550.html