项目打包SpringBoot启动过程
当使用打包时,会下载org-springframework-boot-loader的jar,并且不会放在lib存放的第三方jar包文件中,该jar包中有个JarLauncher.class文件中设置了jar包运行时的入口和打包后文件的结构(定义了BOOT-INF,META-INF中放什么数据)
使用java -jar 启动项目时,因为META-INF中文件记载了启动的顺序
Manifest-Version: 1.0	#版本 Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx	Start-Class: com.zyy.gradletest1.GradleTest1Application	#项目的启动器 Spring-Boot-Classes: BOOT-INF/classes/	#记录编译后文件存放地址 Spring-Boot-Lib: BOOT-INF/lib/	#记录第三方jar包存放地址 Spring-Boot-Version: 2.3.0.RELEASE	#SpringBoot版本 Main-Class: org.springframework.boot.loader.JarLauncher	#标记了程序的入口,程序的入口定义类加载器去加载项目的启动器
所以程序会直接进入JarLauncher.class中执行main方法
public class JarLauncher extends ExecutableArchiveLauncher {	static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";	static final String BOOT_INF_LIB = "BOOT-INF/lib/";	public JarLauncher() {	}	protected JarLauncher(Archive archive) {	super(archive);	}	@Override	protected boolean isNestedArchive(Archive.Entry entry) {	if (entry.isDirectory()) {	return entry.getName().equals(BOOT_INF_CLASSES);	}	return entry.getName().startsWith(BOOT_INF_LIB);	}	public static void main(String[] args) throws Exception {	new JarLauncher().launch(args);	} }
JarLancher继承了ExecutableArchiveLauncher,ExecutableArchiveLauncher抽象类是归档启动器的父类,它有两个子类
Lancher:是整个归档的基类(抽象类)
|
ExecutableArchiveLauncher
| |
JarLancher WarLancher
顾名思义jarLancher就是打包成jar的归档启动类,WarLancher是War打包方式的归档启动类。
当执行JarLancher的main方法时,会调用Lancher基类的launch方法,该方法注释为:启动应用程序。 此方法是初始入口点应该由一个子类被称为public static void main(String[] args)方法。
使用SpringBoot自定义类加载器(LaunchedURLClassLoader)来加载打包好的Jar文件中BOOT-INF里面的类和lib
ClassLoader classLoader = createClassLoader(getClassPathArchives());
getClassPathArchives()方法:返回嵌套Archive S表示匹配指定过滤器条目。
意思就是:获得需要自定义类加载器需要加载的类的路径并返回(归档文件)
public abstract class ExecutableArchiveLauncher extends Launcher { @Override protected ListgetClassPathArchives() throws Exception { Listarchives = new ArrayList