今日思语:I miss you? 何解? 我错过你了?我想你了?

当下许多公司都会选择使用springboot作为服务应用开发框架,springboot框架提供了一套自己的打包机制,是通过spring-boot-maven-plugin插件来实现的。

1、spring-boot-maven-plugin引入pom

对于新建的一个springboot项目来说,pom中会加入插件:

通过idea可以看到maven中包含了spring-boot-maven-plugin插件:

功能说明:

  • build-info:生成项目的构建信息文件 build-info.properties

  • repackage:这个是默认 goal,在 mvn package 执行之后,这个命令再次打包生成可执行的 jar,同时将 mvn package 生成的 jar 重命名为 *.origin

  • run:这个可以用来运行 Spring Boot 应用

  • start:这个在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理

  • stop:这个在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理

spring-boot-maven-plugin插件默认在父工程sprint-boot-starter-parent中被指定为repackage,可以点击sprint-boot-starter-parent进入父pom进行查看,如下图:

如果需要设置其他属性,需要在当前应用的pom中进行设置。

2、执行打包命令

mvn clean package

或者通过开发工具如idea执行clean和package俩命令:

执行以上命令时会自动触发spring-boot-maven-plugin插件的repackage目标,完后可以在target目录下看到生成的jar,如下图:

这里可以看到生成了两个jar相关文件,其中common.jar是spring-boot-maven-plugin插件重新打包后生成的可执行jar,即可以通过java -jar common.jar命令启动。common.jar.original这个则是mvn package打包的原始jar,在spring-boot-maven-plugin插件repackage命令操作时重命名为xxx.original,这个是一个普通的jar,可以被引用在其他服务中。

3、jar内部结构

对这两个jar文件解压看看里面的结构差异:

3.1 common.jar目录结构如下:

其中BOOT-INF主要是一些启动信息,包含classes和lib文件,classes文件放的是项目里生成的字节文件class和配置文件,lib文件是项目所需要的jar依赖。

META-INF目录下主要是maven的一些元数据信息,MANIFEST.MF文件内容如下:

Manifest-Version: 1.0
Implementation-Title: java-common-utils
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.common.util.CommonUtilsApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.9.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher

其中Start-Class是项目的主程序入口,即main方法。Springboot-Boot-Classes和Spring-Boot-Lib指向的是生成的BOOT-INF下的对应位置。

Main-Class属性值为org.springframework.boot.loader.JarLauncher,这个值可以通过设置属性layout来控制,如下:

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--使用-Dloader.path需要在打包的时候增加<layout>ZIP</layout>,不指定的话-Dloader.path不生效-->
<layout>ZIP</layout>
<!-- 指定该jar包启动时的主类[建议] -->
<mainClass>com.common.util.CommonUtilsApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>

设置<layout>ZIP</layout>时Main-Class为org.springframework.boot.loader.PropertiesLauncher,具体layout值对应Main-Class关系如下:

  • JAR,即通常的可执行jar

Main-Class: org.springframework.boot.loader.JarLauncher

  • WAR,即通常的可执行war,需要的servlet容器依赖位于WEB-INF/lib-provided

Main-Class: org.springframework.boot.loader.warLauncher

  • ZIP,即DIR,类似于JAR

Main-Class: org.springframework.boot.loader.PropertiesLauncher

  • MODULE,将所有的依赖库打包(scope为provided的除外),但是不打包Spring Boot的任何Launcher
  • NONE,将所有的依赖库打包,但是不打包Spring Boot的任何Launcher

common.jar之所以可以使用java -jar运行,和MANIFEST.MF文件里的配置关系密切

3.2 original jar包结构

可以看到通过mvn package构建的jar是一个普通的jar,包含的都是项目的字节文件和一些配置文件,没有将项目依赖的第三方jar包含进来。再看下MANIFEST.MF文件:

Manifest-Version: 1.0
Implementation-Title: java-common-utils
Implementation-Version: 0.0.1-SNAPSHOT
Build-Jdk-Spec: 1.8
Created-By: Maven Archiver 3.4.0

其中没有包含Start-Class、Main-Class等信息,这个与可执行jar的该文件存在很多差异,而且目录结构也有很大差异。

一般对使用spring-boot-maven-plugin插件打出的可执行jar不建议作为jar给其他服务引用,因为可能出现访问可执行jar中的一些配置文件找不到的问题。如果想让构建出来的原始jar不被重新打包,可以对spring-boot-maven-plugin插件配置classifier属性,自定义一个可运行jar名称,这样该插件就不会对原始的jar重命名操作了。

<configuration>
<!-- 指定该jar包启动时的主类[建议] -->
<mainClass>com.common.util.CommonUtilsApplication</mainClass>
<!--配置的 classifier 表示可执行 jar 的名字,配置了这个之后,在插件执行 repackage 命令时,
就不会给 mvn package 所打成的 jar 重命名了,这样就可以被其他项目引用了,classifier命名的为可执行jar-->
<classifier>myexec</classifier>
</configuration>

效果如下:

以上是对spring-boot-maven-plugin插件的打包机制和jar包结构的一些分析。

springboot 打包插件spring-boot-maven-plugin打包机制及内部结构分析的更多相关文章

  1. Spring Boot的Maven插件Spring Boot Maven plugin详解

    Spring Boot的Maven插件(Spring Boot Maven plugin)能够以Maven的方式为应用提供Spring Boot的支持,即为Spring Boot应用提供了执行Mave ...

  2. Spring Boot Maven Plugin打包异常及三种解决方法:Unable to find main class

    [背景]spring-boot项目,打包成可执行jar,项目内有两个带有main方法的类并且都使用了@SpringBootApplication注解(或者另一种情形:你有两个main方法并且所在类都没 ...

  3. Spring Boot Maven Plugin(二):run目标

    简介 Spring Boot Maven Plugin插件提供spring boot在maven中的支持.允许你打包可运行的jar包或war包. 插件提供了几个maven目标和Spring Boot ...

  4. Spring Boot Maven Plugin(一):repackage目标

    简介 Spring Boot Maven Plugin插件提供spring boot在maven中的支持.允许你打包可运行的jar包或war包. 插件提供了几个maven目标和Spring Boot ...

  5. spring boot maven profiles,打包不同的配置文件

    1. 在pom.xml添加 <profiles> <profile> <id>dev</id> <properties> <envir ...

  6. spring boot 打包方式 spring boot 整合mybaits REST services

    <build> <sourceDirectory>src/main/java</sourceDirectory> <plugins> <plugi ...

  7. Spring boot(4)-应用打包部署

    1.Spring Boot内置web spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定 ...

  8. Spring Boot(十二):spring boot如何测试打包部署

    Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...

  9. spring boot项目Intellij 打包

    spring boot项目Intellij 打包 学习了:http://blog.csdn.net/hzt_fighting_up/article/details/78174291 在edit con ...

  10. 微服务下 Spring Boot Maven 工程依赖关系管理

    单体 Spring Boot Maven 工程 最基本的 pom.xml 包含工程信息.Spring Boot 父工程.属性配置.依赖包.构建插件 <?xml version="1.0 ...

随机推荐

  1. MQTTv5.0 ---AUTH – 认证交换

    AUTH报文被从客户端发送给服务端,或从服务端发送给客户端,作为扩展认证交换的一部分,比如质询/ 响应认证.如果CONNECT报文不包含相同的认证方法,则客户端或服务端发送AUTH报文将造成协议错 误 ...

  2. Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

    Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只 ...

  3. C语言----流程图(基础篇四)

    大家晚上好,最近忙每天忙于项目没有时间更新自己的博客,时间就是海绵嘛硬挤挤就是有的,咂看标题" 流程图 ",编程界的一个不可或缺的技能,特别是在做复杂的逻辑的时候要处理好每一步的关 ...

  4. tqdm()与set_description()的用法

    pbar=tqdm(range(55156))for i in pbar: # print(i) a=464443161*845113131 pbar.set_description("tr ...

  5. dubbo循序渐进 - yml配置

    Dubbo首先使用com.alibaba.dubbo.config.spring.schema.NamespaceHandler注册解析器,当spring解析xml配置文件时就会调用这些解析器生成对应 ...

  6. jQuery源码二之extend的实现

    extend是jQuery中一个比较核心的代码,如果有查看jQuery的源码的话,就会发现jQuery在多处调用了extend方法. 作用 对任意对象进行扩展 扩展某个实例对象 对jquery本身的实 ...

  7. React的基本知识和优缺点

    阮一峰 React入门实例教程 知识点 1.html模板3个预加载的js文件,script的type属性 2.ReactDOM.render() 3.JSX语言:允许js和html的混写 4.comp ...

  8. 你能想象未来的MES系统是什么样吗?

    “智能制造”热潮席卷神州大地,在工业4.0热潮,以及国家大力推进中国制造2025的背景下,建设智能工厂,推进智能制造已成为制造企业共同的目标.作为承上启下的车间级综合信息系统,MES系统得到了制造企业 ...

  9. 搭建前端监控系统(六)JS截屏和录屏篇

    怎样定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一系列操作之后.错误的原因可能源于机型,网络环境,接口请求,复杂的操作行为等等,在我们想要去解决的时候很难复现出来,自然也就无法解决 ...

  10. Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量

    在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...