Maven 依赖分离的两种方式
作者:zhougl996
本文主要介绍了Maven 依赖分离的两种方式,包括用通用方案或SpringBoot专属配置,把主Jar和依赖lib分开放,优化Docker镜像构建、加速传输,感兴趣的可以了解一下
插件配置
- 复制依赖到 target/lib 目录
- 配置主 Jar 的 Class-Path 和 Main-Class
Maven 依赖分离是指将项目的 核心代码(主 Jar) 与 第三方依赖库(依赖 Jar) 分离到不同目录,而非打包在同一个文件中。这种方式常用于优化部署、减少重复传输、或配合 Docker 镜像分层构建。
以下是两种最常用的实现方案:
方案一:使用maven-dependency-plugin(通用方案)
适用于所有 Maven 项目,通过插件将依赖复制到指定目录,并配置主 Jar 的 Class-Path 指向该目录。
1. 配置pom.xml
在 <build><plugins> 中添加以下两个插件:
<project>
<!-- ... 其他配置 ... -->
<build>
<!-- 配置target的文件位置 -->
<directory>${basedir}/target</directory>
<plugins>
<!-- 1. 复制依赖到 target/lib 目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase> <!-- 绑定到 package 阶段 -->
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- 依赖输出目录 -->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!-- 是否包含传递性依赖 -->
<includeScope>runtime</includeScope>
<!-- 保持依赖的原有文件名 -->
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<!-- 2. 配置主 Jar 的 Class-Path 和 Main-Class -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<!-- 程序入口类 -->
<mainClass>com.example.YourMainClass</mainClass>
<!-- 自动添加 Class-Path -->
<addClasspath>true</addClasspath>
<!-- Class-Path 中依赖的前缀目录 -->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>关键配置说明
| 配置项 | 作用 |
|---|---|
<includeScope>runtime</includeScope> | 仅复制运行时需要的依赖(compile 和 runtime 范围),排除 test(测试用)和 provided(容器提供)的依赖。 |
<classpathPrefix>lib/</classpathPrefix> | 告诉主 Jar 去 lib/ 目录下找依赖,必须与 outputDirectory 的目录名一致。 |
<useBaseVersion>true</useBaseVersion> | 避免 SNAPSHOT 版本的依赖文件名带时间戳(如 1.0-20240101.123456-1.jar),保持文件名简洁。 |
2. 执行打包
运行 mvn clean package,你会在 target 目录下看到:
your-app.jar(你的主程序,体积很小)lib/(包含所有依赖的 Jar 包)
3. 运行方式
将 your-app.jar 和 lib/ 放在同一目录下,执行:
java -jar your-app.jar
方案二:Spring Boot 项目专用(spring-boot-maven-plugin)
如果是 Spring Boot 项目,默认插件会把所有依赖打进一个 Fat Jar。若需分离,需调整插件配置。
1. 配置pom.xml
<project>
<!-- ... 其他配置 ... -->
<build>
<plugins>
<!-- Spring Boot 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 1. 启用分层打包(Layered Jars) -->
<layers>
<enabled>true</enabled>
</layers>
<!-- 或者 2. 使用 Properties 配置(旧版本方式) -->
<!-- <requiresUnpack>
<dependency>
<groupId>com.example</groupId>
<artifactId>some-large-lib</artifactId>
</dependency>
</requiresUnpack> -->
</configuration>
</plugin>
<!-- 配合复制依赖插件(可选,若需物理分离) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>2. Spring Boot 分层 Jar 说明
Spring Boot 的 layers 模式虽然不直接物理分离文件,但内部将 Jar 分为了不同层(如 dependencies、spring-boot-loader、snapshot-dependencies、application),非常适合 Docker 镜像构建,能利用缓存加速。
如果需要物理分离(像方案一那样 lib 目录在外),建议直接使用 方案一 的通用配置,Spring Boot 项目同样兼容。
总结
- 普通项目:推荐 方案一,结构清晰,运行简单。
- Spring Boot + Docker:推荐使用
layers分层模式,优化镜像构建速度。 - 注意:分离后部署时,务必保证
lib目录和主 Jar 的相对位置与classpathPrefix配置一致。
到此这篇关于Maven 依赖分离的两种方式的文章就介绍到这了,更多相关Maven 依赖分离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
