Apache Maven是一种广泛使用的项目依赖项管理工具和项目构建工具。
Spring Boot是构建应用程序的非常流行的框架。
spring-boot-maven-plugin插件在Apache Maven中提供Spring Boot支持。
Maven使用mvn package将应用程序打包到JAR或WAR中。
mvn package命令将采用编译后的代码并将其打包为可分发格式,如JAR格式文件,它仅包含来自项目源的资源和已编译的Java类。
我们可以将此JAR文件用作另一个项目中的依赖项。但是在Spring Boot应用程序中,我们不能直接使用java -jar JAR_FILE执行上述JAR文件。这是因为没有捆绑运行时依赖项。例如,我们没有Servlet容器来启动Web上下文。
要使用简单的java -jar命令启动Spring Boot应用程序,我们需要构建一个胖JAR。spring-boot-maven-plugin插件可以帮助我们。
要实现SpringBoot重新打包,需要使用spring-boot-maven-plugin插件的repackage。
<build>
<finalName>${project.artifactId}finalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
mvn clean spring-boot:repackage
这个命令需要以现有JAR或WAR存档为源,将项目类重新打包,包括所有项目运行时依赖都包括在一起。这样才可以使用命令行java -jar JAR_FILE.jar来执行重新打包好的JAR文件。
因此,我们需要在执行spring-boot:repackage目标之前先构建JAR文件:
mvn clean package spring-boot:repackage
以上命令才是完整的重新打包命令。
在重新打包的JAR文件中,不仅具有来自项目的已编译Java类,而且还具有启动Spring Boot应用程序所需的所有运行时库。
我们可以在pom.xml中配置spring-boot-maven-plugin插件, 以在Maven生命周期的打包阶段执行重新打包 。换句话说,当我们执行MVN打包,spring-boot:repackage将自动执行。
<build>
<finalName>${project.artifactId}finalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
注:repackage只会将其依赖的包重新打包,并不是将整个项目的依赖包都加入。
项目参考《Maven-modules》,portal模块的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>earthartifactId>
<groupId>ymqx.comgroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>portalartifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}groupId>
<artifactId>serviceartifactId>
<version>${project.version}version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>1.4.2.RELEASEversion>
<configuration>
<finalName>earthfinalName>
<classifier>1.0-SNAPSHOTclassifier>
<outputDirectory>../targetoutputDirectory>
configuration>
<executions>
<execution>
<id>repackageid>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
project>
service模块的pom.xml:
...
<dependencies>
<dependency>
<groupId>${project.groupId}groupId>
<artifactId>daoartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>${project.groupId}groupId>
<artifactId>facadeartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
...
dao模块的pom.xml:
...
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${mybatis-plus.version}version>
dependency>
dependencies>
...
portal模块依赖service模块,而service模块引用了dao模块、facade模块。其中,dao模块依赖了包mybatis-plus-boot-starter。执行打包后,生成earth-1.0-SNAPSHOT.jar:
红色是依赖的本项目模块dao-1.0-SNAPSHOT.jar、facade-1.0-SNAPSHOT.jar、service-1.0-SNAPSHOT.jar。
绿色是dao模块依赖的mybatis-plus-boot-starter相关包。
蓝色是父工程依赖的相关包。
黑色箭头这些不知道什么包,感觉也是mybatis-plus-boot-starter相关包。
可以看出,repackage会将portal模块依赖的包以及依赖包依赖的包都重新打包。(有点绕口)
再看一个例子,修改service的pom文件,删除dao模块依赖,修改后service模块的pom.xml:
...
<dependencies>
<dependency>
<groupId>${project.groupId}groupId>
<artifactId>facadeartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
...
执行打包后,生成earth-1.0-SNAPSHOT.jar:
可以看出,repackage只会将依赖包重新打包。
为什么父工程的依赖没有打包呢?
看下父工程pom文件:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>${fasterxml.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${fasterxml.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${fasterxml.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatypegroupId>
<artifactId>jackson-datatype-jsr310artifactId>
<version>${fasterxml.version}version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
...
dependencies依赖包含进去了,但是dependencyManagement依赖没有包含。原因很简单,dependencies依赖默认会被所有子模块继承,而dependencyManagement依赖只有子模块用到时声明才会被引用。所以,dependencyManagement依赖不会被包含。
修改父模块pom文件,将jackson-core改为dependencies依赖:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${fasterxml.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${fasterxml.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatypegroupId>
<artifactId>jackson-datatype-jsr310artifactId>
<version>${fasterxml.version}version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>${fasterxml.version}version>
dependency>
dependencies>
...
执行打包后,生成earth-1.0-SNAPSHOT.jar:
可以看到,依赖jackson-core-2.11.1.jar被包含打包进去。