网站外链购买,wordpress 4 下载地址,乡林建设集团官方网站,腾讯云怎么建网站文章目录 1. Maven生命周期2. jar包结构2.1 不可执jar包结构2.2 可执行jar包结构 3. spring-boot-maven-plugin插件打包4. 执行jar原理 1. Maven生命周期
Maven的生命周期有三种#xff1a;
clean#xff1a;清除项目构建数据#xff0c;较为简单#xff0c;不深入探讨
clean清除项目构建数据较为简单不深入探讨site建立和部署项目站点使用的较少也不深入探讨default定义了项目构建时所需要的所有步骤是Maven生命周期中最核心最重要的的部分。
本次要深入了解的便是default流程。其生命周期如下
阶段可否执行说明validate√验证项目是否正确以及所有必要信息是否可用initializeX初始化构建状态generate-sourcesX生成编译阶段需要的所有源码文件process-sourcesX处理源码文件例如过滤某些值generate-resourcesX生成项目打包阶段需要的资源文件process-resourcesX处理资源文件并复制到输出目录为打包阶段做准备compile√编译源代码并移动到输出目录process-classesX处理编译生成的字节码文件generate-test-sourcesX生成编译阶段需要的测试源代码process-test-sourcesX处理测试资源并复制到测试输出目录test-compileX编译测试源代码并移动到测试输出目录中test√使用适当的单元测试框架如junit运行测试prepare-packageX在真正打包前执行一些必要的操作package√获取编译后的代码并按照可发布的格式进行打包如jar、war或ear文件pre-integration-testX在集成测试执行之前执行所需的操作例如设置环境变量integration-testX处理和部署所需的包到集成测试能够运行的环境中post-integration-testX在集成测试被执行后执行必要的操作例如清理环境verify√对集成测试的结果进行检查以保证质量达标install√安装打包的项目到本地仓库以供本地其它项目使用deploy√拷贝最终的包文件到远程仓库中以共享给其它开发人员和项目
其中可以在Maven常见的Lifecycle中直接执行的有validate、compile、test、package、verify和deploy七种一般在Maven的plugin标签中可以通过配置如下配置来指定插件在某个阶段生效需要注意的是不可随意配置每个插件可处理的阶段都是不同的。不配置则执行插件默认的
executionsexecutionphaseXX/phasegoalsgoalXXXX/goal/goals/execution
/executions今天要深入了解的spring-boot-maven-plugin插件就是在package阶段中生效的。
2. jar包结构
通常而言jar包分为可执行jar包和不可执行jar包顾名思义可执行jar包即可通过命令java -jar直接执行不可执行jar包通过命令java -jar执行则会报错。
2.1 不可执jar包结构
|-- _jar包根目录|-- 原项目class文件和resource文件|-- _META-INF|-- MANIFEST.MF|-- _maven|-- _项目目录|-- pom.properties|-- pom.xml上面是经典的不可执行jar包目录其中MANIFEST.MF文件内容如下
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: xxxxx
Created-By: Apache Maven 3.5.0
Build-Jdk: 1.8.0_151这五项是最基本的如果使用java -jar执行这些jar包将会抛出错误码java.launcher.jar.error3意为没找到Main-Class属性。不同语言展示的最终描述不同由launcher对应语言类转换简体中文在launcher_zh_CN类中转换{0}为jar包名称内容如下
{0}中没有主清单属性英文在launcher类中转换{0}为jar包名称内容如下
no main manifest attribute, in {0}2.2 可执行jar包结构
可执行jar包结构挑选经典的springboot启动包来做示范
|-- _jar包根目录|-- _BOOT-INF|-- _classes|-- 原项目class文件和resource文件|-- _lib|--原项目依赖的jar库文件|-- _META-INF|-- MANIFEST.MF|-- spring-configuration-metadata.jsonspringboot项目特有|-- build-info.properties|-- _maven|-- _项目目录|-- pom.properties|-- pom.xml上一节我们得知了如果在MANIFEST.MF中没有Main-Class属性使用java -jar命令执行jar包会报错接下来看看在可执行jar包的结构MANIFEST.MF中具体有什么属性
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: XXXX
Implementation-Version: 1.0-SNAPSHOT
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.6.RELEASE
Created-By: Maven Archiver 3.4.0
Start-Class: XXX.XXX.XXX.XXXX
Main-Class: org.springframework.boot.loader.JarLauncher里面有两个很重要的属性Start-Class和Main-Class其中Start-Class指的是项目中springboot的SpringApplication启动类而Main-Class则是jar包的启动类入口。
3. spring-boot-maven-plugin插件打包 springboot打包插件执行原理
读取原jar包Maven插件都能读MavenProject对象内容从中可以读取到Artifact信息调用该对象的getFile()方法即可获取原jar包文件对象读取项目依赖jar库直接使用MavenProject对象的getArtifacts()方法即可获取依赖的jar库加载launchScript读取embeddedLaunchScript配置并构建LaunchScript对象重新改写MANIFEST.MF到此步骤开始为repackage的核心流程改写清单文件时最主要的便是写入Start-Class和Main-Class属性除此之外还会写入jar库和原项目文件目录属性写入spring-boot-loader包文件该包是springboot对接java -jar执行命令的核心处理逻辑springboot打包后加入的Main-Class: org.springframework.boot.loader.JarLauncher属性指向的类便是此包中的jar包启动类如果war包则会写入war包启动类写入原项目文件原项目文件会被挪到BOOT-INF/classes/目录下写入项目依赖jar库原项目依赖的jar库会被写入到BOOT-INF/lib/目录下。
如果要看spring-boot-maven-plugin插件打包源码以分析原理可导入插件的依赖此时就能看到该插件的源码。如果使用的是IDEA下载源码后打上断点在执行package时使用debug模式启动也能直接进行调试。
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdversionXXXXX/version
/dependency4. 执行jar原理
将会分析执行java -jar命令后Java程序调用到Springboot启动类main方法的流程。 JVM启动执行加载主函数LoadMainClass此时是在JVM底层实现的里面指定了LauncherHelper类执行LauncherHelper的checkAndLoadMain方法JVM将会调用LauncherHelper的checkAndLoadMain方法解析并校验jar包并获取主要的启动类解析jar的MANIFEST.MF文件在此方法中会完成读取MANIFEST.MF文件主要是读取其中的Main-Class属性并做jar包启动的校验GetStaticMethodID方法JVM获取到Main-Class类对象调用Main-Class类对象的main方法执行JarLauncher的main方法JarLauncher继承自Launchermain方法最后还是会调用到Launcher.launch()方法中读取jar的Start-Class此时会读取jar包的Start-Class属性该属性就是原项目的SpringApplication启动类调用启动类的main方法调用MainMethodRunner的run方法里面会调用Start-Class类的main方法此时调入到自定义的启动类中完成启动Springboot程序的入口程序。