概述
Apache Maven是一种广泛使用的项目依赖项管理工具和项目构建工具。
Spring Boot是构建应用程序的非常流行的框架。
spring-boot-maven-plugin插件在Apache Maven中提供Spring Boot支持。
mvn package
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插件可以帮助我们。
spring-boot-maven-plugin
要实现SpringBoot重新打包,需要使用spring-boot-maven-plugin插件的repackage。
1、pom.xml中添加spring-boot-maven-plugin插件
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2、重新打包命令
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配置
我们可以在pom.xml中配置spring-boot-maven-plugin插件, 以在Maven生命周期的打包阶段执行重新打包 。换句话说,当我们执行MVN打包,spring-boot:repackage将自动执行。
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
注:repackage只会将其依赖的包重新打包,并不是将整个项目的依赖包都加入。
项目参考《Maven-modules》,portal模块的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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>earth</artifactId>
<groupId>ymqx.com</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>portal</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 使用spring-boot-maven-plugin打包独立可执行程序 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.2.RELEASE</version>
<configuration>
<finalName>earth</finalName>
<classifier>1.0-SNAPSHOT</classifier>
<outputDirectory>../target</outputDirectory>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
service模块的pom.xml:
...
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dao</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>facade</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
...
dao模块的pom.xml:
...
<dependencies>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<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>facade</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
...
执行打包后,生成earth-1.0-SNAPSHOT.jar:
可以看出,repackage只会将依赖包重新打包。
为什么父工程的依赖没有打包呢?
看下父工程pom文件:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${fasterxml.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${fasterxml.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${fasterxml.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${fasterxml.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
...
dependencies依赖包含进去了,但是dependencyManagement依赖没有包含。原因很简单,dependencies依赖默认会被所有子模块继承,而dependencyManagement依赖只有子模块用到时声明才会被引用。所以,dependencyManagement依赖不会被包含。
修改父模块pom文件,将jackson-core改为dependencies依赖:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${fasterxml.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${fasterxml.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${fasterxml.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${fasterxml.version}</version>
</dependency>
</dependencies>
...
执行打包后,生成earth-1.0-SNAPSHOT.jar:
可以看到,依赖jackson-core-2.11.1.jar被包含打包进去。