Maven 依赖分离Maven 依赖分离是指将项目的**核心代码主 Jar与第三方依赖库依赖 Jar**分离到不同目录而非打包在同一个文件中。这种方式常用于优化部署、减少重复传输、或配合 Docker 镜像分层构建。以下是两种最常用的实现方案方案一使用maven-dependency-plugin通用方案适用于所有 Maven 项目通过插件将依赖复制到指定目录并配置主 Jar 的 Class-Path 指向该目录。1. 配置pom.xml在buildplugins中添加以下两个插件复制依赖到 target/lib 目录配置主 Jar 的 Class-Path 和 Main-Classproject!-- ... 其他配置 ... --buildplugins!-- 1. 复制依赖到 target/lib 目录 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.6.0/versionexecutionsexecutionidcopy-dependencies/idphasepackage/phase!-- 绑定到 package 阶段 --goalsgoalcopy-dependencies/goal/goalsconfiguration!-- 依赖输出目录 --outputDirectory${project.build.directory}/lib/outputDirectory!-- 是否包含传递性依赖 --includeScoperuntime/includeScope!-- 保持依赖的原有文件名 --overWriteReleasesfalse/overWriteReleasesoverWriteSnapshotsfalse/overWriteSnapshotsoverWriteIfNewertrue/overWriteIfNewer/configuration/execution/executions/plugin!-- 2. 配置主 Jar 的 Class-Path 和 Main-Class --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdversion3.3.0/versionconfigurationarchivemanifest!-- 程序入口类 --mainClasscom.example.YourMainClass/mainClass!-- 自动添加 Class-Path --addClasspathtrue/addClasspath!-- Class-Path 中依赖的前缀目录 --classpathPrefixlib//classpathPrefix/manifest/archive/configuration/plugin/plugins/build/project** 关键配置说明 **配置项作用includeScoperuntime/includeScope仅复制运行时需要的依赖compile和runtime范围排除test测试用和provided容器提供的依赖。classpathPrefixlib//classpathPrefix告诉主 Jar 去lib/目录下找依赖必须与outputDirectory的目录名一致。useBaseVersiontrue/useBaseVersion避免 SNAPSHOT 版本的依赖文件名带时间戳如1.0-20240101.123456-1.jar保持文件名简洁。2. 执行打包运行mvn clean package你会在target目录下看到your-app.jar你的主程序体积很小lib/包含所有依赖的 Jar 包3. 运行方式将your-app.jar和lib/放在同一目录下执行java-jaryour-app.jar方案二Spring Boot 项目专用spring-boot-maven-plugin如果是 Spring Boot 项目默认插件会把所有依赖打进一个 Fat Jar。若需分离需调整插件配置。1. 配置pom.xmlproject!-- ... 其他配置 ... --buildplugins!-- Spring Boot 插件 --plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfiguration!-- 1. 启用分层打包Layered Jars --layersenabledtrue/enabled/layers!-- 或者 2. 使用 Properties 配置旧版本方式 --!-- requiresUnpack dependency groupIdcom.example/groupId artifactIdsome-large-lib/artifactId /dependency /requiresUnpack --/configuration/plugin!-- 配合复制依赖插件可选若需物理分离 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdexecutionsexecutionidcopy-dependencies/idphasepackage/phasegoalsgoalcopy-dependencies/goal/goalsconfigurationoutputDirectory${project.build.directory}/lib/outputDirectoryincludeScoperuntime/includeScope/configuration/execution/executions/plugin/plugins/build/project2. 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-dependency-plugin 介绍maven-dependency-plugin是 Maven 中处理依赖最核心的插件提供了复制、解压、解析、分析项目依赖等功能是实现依赖分离、离线构建、依赖冲突排查的关键工具。以下是该插件的全面配置详解结合核心Goal目标和实际场景示例说明。一、插件基本信息在pom.xml中引入插件建议使用最新稳定版buildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.6.1/version!-- 请使用最新版本 --/plugin/plugins/build二、核心 Goal 及详细配置该插件通过不同的Goal目标实现不同功能以下是最常用的 4 个 Goal1.dependency:copy-dependencies最常用复制依赖到指定目录作用将项目的依赖包括传递性依赖从本地仓库复制到指定目录是实现“依赖分离”的核心 Goal。常用配置参数参数名类型默认值说明outputDirectoryString${project.build.directory}/dependency依赖复制的目标目录如target/libincludeScopeString-仅包含指定范围的依赖如runtime、compile、testexcludeScopeString-排除指定范围的依赖includeGroupIdsString-仅包含指定 GroupId 的依赖多个用逗号分隔excludeGroupIdsString-排除指定 GroupId 的依赖includeArtifactIdsString-仅包含指定 ArtifactId 的依赖excludeArtifactIdsString-排除指定 ArtifactId 的依赖includeTypesStringjar仅包含指定类型的依赖如jar、war、pomclassifierString-仅包含指定classifier的依赖如sources、javadocoverWriteReleasesbooleanfalse是否覆盖已存在的 Release 版本依赖overWriteSnapshotsbooleantrue是否覆盖已存在的 Snapshot 版本依赖overWriteIfNewerbooleantrue仅当依赖文件更新时才覆盖useBaseVersionbooleanfalse文件名使用基础版本如1.0而非1.0-20240101.123456-1stripVersionbooleanfalse复制的文件名去掉版本号如commons-lang3.jarprependGroupIdbooleanfalse文件名前加上 GroupId 前缀如org.apache.commons-commons-lang3.jarcopyPombooleanfalse是否同时复制依赖的.pom文件failOnMissingClassifierArtifactbooleantrue当找不到指定classifier的依赖时是否构建失败完整配置示例依赖分离场景plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.6.1/versionexecutionsexecutionidcopy-libs/idphasepackage/phase!-- 绑定到 package 阶段 --goalsgoalcopy-dependencies/goal/goalsconfiguration!-- 1. 目标目录target/lib --outputDirectory${project.build.directory}/lib/outputDirectory!-- 2. 仅包含 runtime 范围的依赖排除 test、provided --includeScoperuntime/includeScope!-- 3. 排除不需要的依赖如 lombok --excludeGroupIdsorg.projectlombok/excludeGroupIds!-- 4. 优化文件覆盖策略 --overWriteReleasesfalse/overWriteReleasesoverWriteSnapshotstrue/overWriteSnapshotsoverWriteIfNewertrue/overWriteIfNewer!-- 5. 文件名使用基础版本避免 SNAPSHOT 时间戳 --useBaseVersiontrue/useBaseVersion/configuration/execution/executions/plugin2.dependency:unpack解压依赖作用将依赖的 Jar/War 包解压到指定目录常用于提取依赖中的资源文件、 native 库等。特有配置参数除了copy-dependencies的参数外参数名类型说明includesString仅解压指定文件Ant 风格路径如**/*.xmlexcludesString排除指定文件配置示例提取依赖中的配置文件executionidunpack-configs/idphasegenerate-resources/phasegoalsgoalunpack/goal/goalsconfigurationoutputDirectory${project.build.directory}/classes/config/outputDirectory!-- 仅解压某个特定依赖 --includeGroupIdscom.example/includeGroupIdsincludeArtifactIdsmy-common-lib/includeArtifactIds!-- 仅解压 xml 和 properties 文件 --includes**/*.xml,**/*.properties/includes/configuration/execution3.dependency:resolve解析依赖作用确保所有依赖都下载到本地仓库不做复制/解压操作常用于构建前的预检查或离线构建准备。配置示例executionidresolve-deps/idphasevalidate/phasegoalsgoalresolve/goal/goalsconfiguration!-- 解析所有范围的依赖包括 test --includeScopetest/includeScope/configuration/execution4.dependency:analyze分析依赖作用分析项目的依赖使用情况找出unused declared dependencies声明了但未使用的依赖used undeclared dependencies使用了但未直接声明的依赖传递性依赖常用配置参数参数名类型默认值说明failOnWarningbooleanfalse发现上述问题时是否构建失败ignoreNonCompilebooleanfalse忽略test、provided、runtime范围的依赖usedDependenciesString-强制声明某些依赖是“已使用”的避免误报配置示例构建时检查未使用依赖executionidanalyze-deps/idphaseverify/phasegoalsgoalanalyze-only/goal!-- 注意用 analyze-only 而非 analyze避免重复执行 --/goalsconfiguration!-- 发现未使用依赖时构建失败强制清理无用依赖 --failOnWarningtrue/failOnWarning!-- 忽略 test 范围 --ignoreNonCompiletrue/ignoreNonCompile!-- 强制认为 lombok 是已使用的避免误报 --usedDependenciesusedDependencyorg.projectlombok:lombok/usedDependency/usedDependencies/configuration/execution三、高级应用场景1. 离线构建准备dependency:go-offline如果需要在无网络环境下构建项目可先执行mvn dependency:go-offline该命令会下载所有依赖包括插件及其依赖到本地仓库配合-ooffline参数即可离线构建mvn clean package-o2. 结合 Profile 实现环境差异化依赖profilesprofileidprod/idbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdexecutionsexecutionidcopy-prod-libs/idphasepackage/phasegoalsgoalcopy-dependencies/goal/goalsconfigurationoutputDirectory${project.build.directory}/prod-lib/outputDirectory!-- 生产环境排除 test 依赖 --excludeScopetest/excludeScope/configuration/execution/executions/plugin/plugins/build/profile/profiles四、注意事项版本兼容性确保插件版本与 Maven 核心版本兼容Maven 3.6 建议使用 3.2.0 版本的插件。传递性依赖includeScope会同时影响传递性依赖如includeScoperuntime会包含compile范围的传递性依赖因为 Maven 会将其转为runtime。性能优化如果依赖数量很多可通过excludeGroupIds排除不需要的组如org.apache.maven提升复制速度。
Maven 依赖分离
Maven 依赖分离Maven 依赖分离是指将项目的**核心代码主 Jar与第三方依赖库依赖 Jar**分离到不同目录而非打包在同一个文件中。这种方式常用于优化部署、减少重复传输、或配合 Docker 镜像分层构建。以下是两种最常用的实现方案方案一使用maven-dependency-plugin通用方案适用于所有 Maven 项目通过插件将依赖复制到指定目录并配置主 Jar 的 Class-Path 指向该目录。1. 配置pom.xml在buildplugins中添加以下两个插件复制依赖到 target/lib 目录配置主 Jar 的 Class-Path 和 Main-Classproject!-- ... 其他配置 ... --buildplugins!-- 1. 复制依赖到 target/lib 目录 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.6.0/versionexecutionsexecutionidcopy-dependencies/idphasepackage/phase!-- 绑定到 package 阶段 --goalsgoalcopy-dependencies/goal/goalsconfiguration!-- 依赖输出目录 --outputDirectory${project.build.directory}/lib/outputDirectory!-- 是否包含传递性依赖 --includeScoperuntime/includeScope!-- 保持依赖的原有文件名 --overWriteReleasesfalse/overWriteReleasesoverWriteSnapshotsfalse/overWriteSnapshotsoverWriteIfNewertrue/overWriteIfNewer/configuration/execution/executions/plugin!-- 2. 配置主 Jar 的 Class-Path 和 Main-Class --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdversion3.3.0/versionconfigurationarchivemanifest!-- 程序入口类 --mainClasscom.example.YourMainClass/mainClass!-- 自动添加 Class-Path --addClasspathtrue/addClasspath!-- Class-Path 中依赖的前缀目录 --classpathPrefixlib//classpathPrefix/manifest/archive/configuration/plugin/plugins/build/project** 关键配置说明 **配置项作用includeScoperuntime/includeScope仅复制运行时需要的依赖compile和runtime范围排除test测试用和provided容器提供的依赖。classpathPrefixlib//classpathPrefix告诉主 Jar 去lib/目录下找依赖必须与outputDirectory的目录名一致。useBaseVersiontrue/useBaseVersion避免 SNAPSHOT 版本的依赖文件名带时间戳如1.0-20240101.123456-1.jar保持文件名简洁。2. 执行打包运行mvn clean package你会在target目录下看到your-app.jar你的主程序体积很小lib/包含所有依赖的 Jar 包3. 运行方式将your-app.jar和lib/放在同一目录下执行java-jaryour-app.jar方案二Spring Boot 项目专用spring-boot-maven-plugin如果是 Spring Boot 项目默认插件会把所有依赖打进一个 Fat Jar。若需分离需调整插件配置。1. 配置pom.xmlproject!-- ... 其他配置 ... --buildplugins!-- Spring Boot 插件 --plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfiguration!-- 1. 启用分层打包Layered Jars --layersenabledtrue/enabled/layers!-- 或者 2. 使用 Properties 配置旧版本方式 --!-- requiresUnpack dependency groupIdcom.example/groupId artifactIdsome-large-lib/artifactId /dependency /requiresUnpack --/configuration/plugin!-- 配合复制依赖插件可选若需物理分离 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdexecutionsexecutionidcopy-dependencies/idphasepackage/phasegoalsgoalcopy-dependencies/goal/goalsconfigurationoutputDirectory${project.build.directory}/lib/outputDirectoryincludeScoperuntime/includeScope/configuration/execution/executions/plugin/plugins/build/project2. 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-dependency-plugin 介绍maven-dependency-plugin是 Maven 中处理依赖最核心的插件提供了复制、解压、解析、分析项目依赖等功能是实现依赖分离、离线构建、依赖冲突排查的关键工具。以下是该插件的全面配置详解结合核心Goal目标和实际场景示例说明。一、插件基本信息在pom.xml中引入插件建议使用最新稳定版buildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.6.1/version!-- 请使用最新版本 --/plugin/plugins/build二、核心 Goal 及详细配置该插件通过不同的Goal目标实现不同功能以下是最常用的 4 个 Goal1.dependency:copy-dependencies最常用复制依赖到指定目录作用将项目的依赖包括传递性依赖从本地仓库复制到指定目录是实现“依赖分离”的核心 Goal。常用配置参数参数名类型默认值说明outputDirectoryString${project.build.directory}/dependency依赖复制的目标目录如target/libincludeScopeString-仅包含指定范围的依赖如runtime、compile、testexcludeScopeString-排除指定范围的依赖includeGroupIdsString-仅包含指定 GroupId 的依赖多个用逗号分隔excludeGroupIdsString-排除指定 GroupId 的依赖includeArtifactIdsString-仅包含指定 ArtifactId 的依赖excludeArtifactIdsString-排除指定 ArtifactId 的依赖includeTypesStringjar仅包含指定类型的依赖如jar、war、pomclassifierString-仅包含指定classifier的依赖如sources、javadocoverWriteReleasesbooleanfalse是否覆盖已存在的 Release 版本依赖overWriteSnapshotsbooleantrue是否覆盖已存在的 Snapshot 版本依赖overWriteIfNewerbooleantrue仅当依赖文件更新时才覆盖useBaseVersionbooleanfalse文件名使用基础版本如1.0而非1.0-20240101.123456-1stripVersionbooleanfalse复制的文件名去掉版本号如commons-lang3.jarprependGroupIdbooleanfalse文件名前加上 GroupId 前缀如org.apache.commons-commons-lang3.jarcopyPombooleanfalse是否同时复制依赖的.pom文件failOnMissingClassifierArtifactbooleantrue当找不到指定classifier的依赖时是否构建失败完整配置示例依赖分离场景plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.6.1/versionexecutionsexecutionidcopy-libs/idphasepackage/phase!-- 绑定到 package 阶段 --goalsgoalcopy-dependencies/goal/goalsconfiguration!-- 1. 目标目录target/lib --outputDirectory${project.build.directory}/lib/outputDirectory!-- 2. 仅包含 runtime 范围的依赖排除 test、provided --includeScoperuntime/includeScope!-- 3. 排除不需要的依赖如 lombok --excludeGroupIdsorg.projectlombok/excludeGroupIds!-- 4. 优化文件覆盖策略 --overWriteReleasesfalse/overWriteReleasesoverWriteSnapshotstrue/overWriteSnapshotsoverWriteIfNewertrue/overWriteIfNewer!-- 5. 文件名使用基础版本避免 SNAPSHOT 时间戳 --useBaseVersiontrue/useBaseVersion/configuration/execution/executions/plugin2.dependency:unpack解压依赖作用将依赖的 Jar/War 包解压到指定目录常用于提取依赖中的资源文件、 native 库等。特有配置参数除了copy-dependencies的参数外参数名类型说明includesString仅解压指定文件Ant 风格路径如**/*.xmlexcludesString排除指定文件配置示例提取依赖中的配置文件executionidunpack-configs/idphasegenerate-resources/phasegoalsgoalunpack/goal/goalsconfigurationoutputDirectory${project.build.directory}/classes/config/outputDirectory!-- 仅解压某个特定依赖 --includeGroupIdscom.example/includeGroupIdsincludeArtifactIdsmy-common-lib/includeArtifactIds!-- 仅解压 xml 和 properties 文件 --includes**/*.xml,**/*.properties/includes/configuration/execution3.dependency:resolve解析依赖作用确保所有依赖都下载到本地仓库不做复制/解压操作常用于构建前的预检查或离线构建准备。配置示例executionidresolve-deps/idphasevalidate/phasegoalsgoalresolve/goal/goalsconfiguration!-- 解析所有范围的依赖包括 test --includeScopetest/includeScope/configuration/execution4.dependency:analyze分析依赖作用分析项目的依赖使用情况找出unused declared dependencies声明了但未使用的依赖used undeclared dependencies使用了但未直接声明的依赖传递性依赖常用配置参数参数名类型默认值说明failOnWarningbooleanfalse发现上述问题时是否构建失败ignoreNonCompilebooleanfalse忽略test、provided、runtime范围的依赖usedDependenciesString-强制声明某些依赖是“已使用”的避免误报配置示例构建时检查未使用依赖executionidanalyze-deps/idphaseverify/phasegoalsgoalanalyze-only/goal!-- 注意用 analyze-only 而非 analyze避免重复执行 --/goalsconfiguration!-- 发现未使用依赖时构建失败强制清理无用依赖 --failOnWarningtrue/failOnWarning!-- 忽略 test 范围 --ignoreNonCompiletrue/ignoreNonCompile!-- 强制认为 lombok 是已使用的避免误报 --usedDependenciesusedDependencyorg.projectlombok:lombok/usedDependency/usedDependencies/configuration/execution三、高级应用场景1. 离线构建准备dependency:go-offline如果需要在无网络环境下构建项目可先执行mvn dependency:go-offline该命令会下载所有依赖包括插件及其依赖到本地仓库配合-ooffline参数即可离线构建mvn clean package-o2. 结合 Profile 实现环境差异化依赖profilesprofileidprod/idbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdexecutionsexecutionidcopy-prod-libs/idphasepackage/phasegoalsgoalcopy-dependencies/goal/goalsconfigurationoutputDirectory${project.build.directory}/prod-lib/outputDirectory!-- 生产环境排除 test 依赖 --excludeScopetest/excludeScope/configuration/execution/executions/plugin/plugins/build/profile/profiles四、注意事项版本兼容性确保插件版本与 Maven 核心版本兼容Maven 3.6 建议使用 3.2.0 版本的插件。传递性依赖includeScope会同时影响传递性依赖如includeScoperuntime会包含compile范围的传递性依赖因为 Maven 会将其转为runtime。性能优化如果依赖数量很多可通过excludeGroupIds排除不需要的组如org.apache.maven提升复制速度。