Maven -- dependency详解

本文深入探讨Maven中依赖(type)与构件分类器(classifier)的概念,解析它们如何定位特定构件,以及在构建过程中如何影响项目输出。通过实例说明不同构件类型与分类器的应用场景。

PS:部分来源官网文档,翻译不到位,请移步官网

一 :type:个人理解:依赖<dependency>通过其子标签   定位了某个特定的唯一构件,所以type--依赖类型,更准确的说应该是依赖的构件的类型。它指定了应该用什么样的插件来处理该构件。

构件:在Maven中,任何依赖(jar包,tomcat等),或项目(自己打包的jar,war等)输出都可成为构件。每个构件都有自己的唯一标识(唯一坐标),由groupId,artifactId,和version等信息构成,由此,Maven就可以对构件进行版本控制,管理。任何可以被Maven的坐标系统唯一标识的对象都是一个Maven构件,但是,只包含其他POM文件(该文件本身不产生构件,打包方式为pom)使用定义的POM文件也是一个Maven构件。

依赖的类型,通常但并不总是代表依赖文件的扩展名。类型可以映射到不同的扩展名和分类器,类型通常与所使用的包装方式相对应,但也不都是如此。<packaging>xxx</packaging>。常见的有 jar, war, ejb-client, test-jar等等 。另,type的默认值为jar。以下是官网列出的一些默认处理方式列表,但这不是全部。插件也可以通过将extension设置为true,从而产生新的type定义

涉及到插件知识,这里只是提到相关的一部分。The <plugin> element contains informations required for a plugin,其中有个子标签<extensions>, 官网对其的解释为:“是否从该插件加载Maven扩展(如打包和类型处理程序 such as packaging and type handlers)。出于性能原因,这应该只在必要时启用,注意:由于技术原因,这个字段的类型是String,而语义类型实际上是Boolean,默认为false” 。这中间的细节暂不做深究,这里主要是弄清type的概念意义。

想起以前看到的一句话,Maven就是一个插件集合,(以下是我个人观点,我不确定是否正确)我认为任何构件都是通过一些插件按照其pom文件指定的build方式产生的,该过程可以指定插件以及插件的工作方式,也可以完全采取默认方式。约定由于配置。

同一个工程,其build方式不同,自然也会产生不同的构件。所以我们在指定依赖的时候,有时若我们想依赖的并不是jar类型的构件,则需要指出其type,若有必要,还需更进一步指出其分类器classifier。实际上,通过gav确定的坐标体系并没有具体到某一个构件,它真正指向的可能是类似这样的一组文件,默认会在文件中选择默认值 type 为 jar, calssifier 为 null 的那份构件(我们可以称之为主构件和附加构件吧)用于匹配dependency引用的最小信息集实际上是{groupId,artifactId,version,type,classifier},然而多数情况下,这些依赖关系将引用的通常是没有classifier的jar依赖。所以我们不需要补充type和classifier信息,因为type的默认值是jar,并且默认classifier为null

然而,在下列这种情况下,光靠gav已经找不到对应构件了,这时候便需要classifier指定特定版本

二:classifier:构件分类器,帮助定义构建输出的一些附属构件。如spring-core.jar,还生成有文档javadoc.jar,源码sources.jar。通常追加组成构件的文件名,跟在version之后,默认为null。通过指定分类器,可以指向不同的附加构件,比如sources和javadoc。它也可以用于区分 由同一份pom但build方式不同生成的一组构件,如上例中使用jdk13和jdk15。注意:type通常是和classifier一起使用的,两者具有配对关系,两者不匹配会导致找不到指定构件。

其他属性参考文章https://blog.youkuaiyun.com/VVVZCS/article/details/81625547,暂时没空深究

<think> 我们正在讨论的是 flatten-maven-plugin,它用于管理 Maven 项目的版本,特别是在多模块项目中,以及如何生成扁平化的POM文件以便发布。 根据引用内容,flatten-maven-plugin 主要解决在Maven项目中使用了属性(如${revision})作为版本号时,在发布(deploy)时这些属性不会被替换为实际值的问题。 同时,它还可以简化POM文件,移除一些对使用者不必要的元素(如插件配置、版本管理信息等),使得发布的POM更简洁。 以下是详细介绍: # flatten-maven-plugin 详解 ## 1. 核心作用 - **版本属性替换**:在项目构建过程中使用属性(如`${revision}`)定义版本号,在发布时将这些属性替换为实际值,实现“CI友好”的版本管理。 - **POM文件扁平化**:生成一个简化版的POM(称为flattened-pom),该POM仅包含依赖和插件管理等必要信息,去除构建配置、插件配置等不必要信息,使发布的POM更简洁。 - **解决多模块项目版本管理问题**:在多模块项目中,统一管理子模块版本,避免重复修改。 ## 2. 工作原理 1. **构建阶段**:在`package`阶段之前(通常绑定到`prepare-package`阶段),插件会读取项目的原始POM。 2. **变量替换**:将所有版本属性(如`${revision}`、`${sha1}`、`${changelist}`)替换为实际值(这些值在构建时通过属性或profile提供)。 3. **POM简化**:根据配置移除或保留POM中的某些部分,生成一个扁平化的POM(默认在`target`目录下,文件名为`.flattened-pom.xml`)。 4. **替换原始POM**:在后续的部署(deploy)阶段,Maven会使用这个扁平化的POM作为项目的POM文件进行发布。 ## 3. 基本配置 ```xml <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>flatten-maven-plugin</artifactId> <version>1.5.0</version> <!-- 建议使用最新版本 --> <configuration> <!-- 指定生成扁平化POM的模式(默认是'minimum') --> <flattenMode>oss</flattenMode> <!-- 可选:指定输出文件名,默认为.flattened-pom.xml --> <outputFileName>.flattened-pom.xml</outputFileName> </configuration> <executions> <execution> <id>flatten</id> <phase>process-resources</phase> <!-- 通常绑定在prepare-package阶段,但也可以调整 --> <goals> <goal>flatten</goal> </goals> </execution> <!-- 清理阶段,删除生成的扁平化POM --> <execution> <id>flatten.clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> ``` ### 配置说明: - **flattenMode**:决定哪些POM元素会被包含在扁平化的POM中。常用模式有: - `minimum`(默认):仅包含依赖和依赖管理。 - `oss`:包含开源项目所需元素(包括开发者、贡献者等),适用于发布到Maven中央仓库。 - `bom`:用于Bill of Materials(BOM)项目。 - `defaults`:包含默认元素(包括依赖、插件等)。 - `clean`:移除所有可选元素,仅保留必须的元素(如GAV坐标、依赖)。 - `fatjar`:包含构建fatjar所需的所有元素。 - **outputFileName**:生成的扁平化POM的文件名(默认为隐藏文件`.flattened-pom.xml`)。 ## 4. 与CI友好版本结合使用 在父POM中定义版本属性(如`revision`)并统一管理版本号: ```xml <project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>parent</artifactId> <version>${revision}</version> <!-- 使用属性 --> <packaging>pom</packaging> <properties> <revision>1.0.0-SNAPSHOT</revision> <!-- 定义属性值 --> </properties> <modules> <module>child-module</module> </modules> <!--dependencyManagement中统一管理依赖版本 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> </dependencies> </dependencyManagement> <!-- 配置flatten插件 --> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>flatten-maven-plugin</artifactId> <version>1.5.0</version> <configuration> <flattenMode>oss</flattenMode> </configuration> <executions> <execution> <id>flatten</id> <phase>process-resources</phase> <goals> <goal>flatten</goal> </goals> </execution> <execution> <id>flatten.clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> ``` 在子模块中,继承父POM的版本,并且不需要再指定版本: ```xml <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.example</groupId> <artifactId>parent</artifactId> <version>${revision}</version> <!-- 使用父POM定义的属性 --> </parent> <artifactId>child-module</artifactId> <!-- 不需要指定版本,继承父POM的版本属性 --> </project> ``` ## 5. 构建与发布 - 在构建时,通过命令行参数指定版本属性值(适用于CI构建): ```bash mvn clean deploy -Drevision=2.0.0 ``` - 在本地开发时,使用父POM中定义的默认值(如`1.0.0-SNAPSHOT`)。 ## 6. 效果对比 ### 原始POM片段(子模块): ```xml <parent> <groupId>com.example</groupId> <artifactId>parent</artifactId> <version>${revision}</version> </parent> <artifactId>child-module</artifactId> <version>${revision}</version> <!-- 如果子模块单独指定了版本,通常也使用属性 --> ``` ### 扁平化后的POM片段: ```xml <parent> <groupId>com.example</groupId> <artifactId>parent</artifactId> <version>2.0.0</version> <!-- 属性被替换为实际值 --> </parent> <artifactId>child-module</artifactId> <version>2.0.0</version> <!-- 属性被替换 --> ``` ## 7. 注意事项 1. **插件绑定阶段**:默认绑定到`package`阶段之前(具体是`prepare-package`),确保在打包前生成扁平化POM。 2. **版本属性定义**:在父POM中定义版本属性(如`revision`)并在子模块中统一使用。 3. **部署问题**:使用`maven-deploy-plugin`部署时,会自动使用扁平化后的POM(`.flattened-pom.xml`)而不是原始POM。 4. **多模块构建**:在父POM中配置插件,子模块会继承配置。 5. **模式选择**:根据发布需求选择合适的`flattenMode`。例如,发布到中央仓库推荐使用`oss`模式。 ## 8. 与versions-maven-plugin的协作 - **versions-maven-plugin**:用于自动化更新项目中的版本号(如批量更新子模块版本)。 - **flatten-maven-plugin**:用于在发布时替换版本属性并简化POM。 - **协作流程**: 1. 使用`versions:set`更新版本属性(如`revision`)的值。 2. 构建时,`flatten-maven-plugin`将属性替换为实际值并生成扁平化POM。 3. 使用`deploy`部署包含扁平化POM的项目。 通过结合使用这两个插件,可以实现版本管理的自动化和发布流程的标准化[^2]。 ## 9. 常见问题 - **问题**:部署后依赖的版本号仍是占位符(如`${revision}`)? - **原因**:未使用`flatten-maven-plugin`或配置不正确。 - **解决**:检查插件配置是否正确绑定阶段,并确保在部署前生成了扁平化POM。 - **问题**:扁平化后的POM包含过多或过少内容? - **解决**:调整`flattenMode`配置,选择适合的模式。 - **问题**:在多模块项目中,子模块的父POM版本仍是占位符? - **解决**:确保在父POM中配置了`flatten-maven-plugin`,并且子模块的父POM版本使用属性(如`${revision}`),在构建时该属性会被替换。 ## 总结 flatten-maven-plugin 是管理Maven项目版本(特别是使用属性定义版本)的关键工具,它通过生成扁平化POM解决版本属性在部署时不被替换的问题,同时简化POM结构,使发布的POM更规范、简洁。结合 versions-maven-plugin 可以实现版本管理的全自动化[^1][^2][^3]。 §§相关问题§§ 1. flatten-maven-plugin 如何与 Maven 的版本属性(如 ${revision})结合使用? 2. flatten-maven-plugin 的 flattenMode 有哪些可选值?它们分别适用于什么场景? 3. 如何解决在部署后依赖版本号仍然是占位符(如${revision})的问题? 4. flatten-maven-plugin 在多模块项目中如何配置? 5. 使用 flatten-maven-plugin 时,如何选择绑定阶段(phase)? </think> # flatten-maven-plugin 详解 ## 1. 核心作用 `flatten-maven-plugin` 是 Maven 生态中用于**解决版本管理问题**的关键插件,主要解决以下问题: - **版本属性替换**:将 POM 文件中的动态版本属性(如 `${revision}`, `${sha1}`, `${changelist}`)替换为实际值 - **POM 文件简化**:生成"扁平化"的 POM 文件,移除开发阶段特有的配置(如插件配置) - **CI/CD 友好**:支持持续集成环境中的自动化版本管理 - **多模块管理**:优化多模块项目的版本一致性 ## 2. 典型应用场景 ### 2.1 版本管理问题 在传统 Maven 项目中,多模块项目版本管理存在痛点: ```xml <!-- 父POM --> <version>1.0.0-SNAPSHOT</version> <!-- 子模块 --> <parent> <version>1.0.0-SNAPSHOT</version> <!-- 硬编码版本号 --> </parent> ``` 每次版本升级需要修改所有子模块的 POM 文件。 ### 2.2 解决方案:CI Friendly Versions 使用属性代替硬编码版本: ```xml <!-- 父POM --> <version>${revision}</version> <properties> <revision>1.0.0-SNAPSHOT</revision> </properties> <!-- 子模块 --> <parent> <version>${revision}</version> <!-- 使用属性 --> </parent> ``` 但直接部署时,Maven 仓库会存储包含 `${revision}` 的原始 POM,导致其他项目无法解析依赖[^1]。 ## 3. 核心功能 ### 3.1 POM 扁平化处理 插件在 `package` 阶段生成扁平化 POM: ```mermaid graph LR A[原始POM] --> B[flatten-maven-plugin] B --> C[扁平化POM] C --> D[Maven仓库] ``` ### 3.2 属性替换机制 | 属性 | 说明 | 示例值 | |---------------|-------------------------------|----------------------| | `${revision}` | 主版本号 | 1.0.0 | | `${sha1}` | Git 提交哈希(短格式) | a1b2c3d | | `${changelist}` | 变更列表(通常用于SNAPSHOT) | -SNAPSHOT | ### 3.3 生成的 POM 变化 原始 POM 片段: ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> </plugin> </plugins> </build> ``` 扁平化 POM 片段: ```xml <!-- 移除了build配置 --> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <!-- 属性被替换为实际值 --> </dependency> </dependencies> ``` ## 4. 完整配置示例 ```xml <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>flatten-maven-plugin</artifactId> <version>1.5.0</version> <configuration> <updatePomFile>true</updatePomFile> <flattenMode>oss</flattenMode> <!-- 开源项目模式 --> </configuration> <executions> <execution> <id>flatten</id> <phase>process-resources</phase> <goals> <goal>flatten</goal> </goals> </execution> <execution> <id>flatten.clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ``` ## 5. 配置参数详解 | 参数 | 说明 | 可选值 | |--------------------|----------------------------------------------------------------------|--------------------------------| | `flattenMode` | 扁平化模式 | `default`, `oss`, `bom` 等 | | `updatePomFile` | 是否更新原始POM文件 | true/false (默认false) | | `outputDirectory` | 生成的POM文件输出目录 | 默认: ${project.build.directory} | | `pomElements` | 显式指定要保留的POM元素 | 如 `<dependencies>`, `<licenses>` | ### 5.1 常用扁平化模式 1. **default**:保留基本元素(依赖、插件管理) 2. **oss**:适合开源项目(保留开发者、许可证信息) 3. **bom**:Bill of Materials 模式 4. **clean**:仅保留最小必要元素 5. **fatjar**:适合打包可执行JAR ## 6. 与 versions-maven-plugin 协作 典型工作流: ```mermaid sequenceDiagram participant D as Developer participant V as versions-maven-plugin participant F as flatten-maven-plugin participant M as Maven Central D->>V: 执行 versions:set -DnewVersion=2.0.0 V->>F: 更新所有模块的${revision} F->>M: 部署扁平化POM(版本2.0.0) M-->>D: 其他项目可正常解析依赖 ``` 命令行示例: ```bash # 设置新版本 mvn versions:set -DnewVersion=2.0.0 # 构建并部署 mvn clean deploy -Drevision=2.0.0 ``` ## 7. 最佳实践 1. **版本属性定义**: ```xml <properties> <revision>1.0.0</revision> <sha1/> <!-- 构建时由CI工具注入 --> <changelist/> <!-- 构建时由CI工具注入 --> </properties> ``` 2. **CI/CD 集成**: ```bash # Jenkins/GitLab CI示例 mvn deploy -Drevision=${BUILD_VERSION} -Dchangelist=-SNAPSHOT ``` 3. **多模块项目结构**: ``` parent-pom/ ├── module-a ├── module-b └── pom.xml (配置flatten插件) ``` ## 8. 常见问题解决 - **问题:部署后依赖版本仍是占位符** 原因:未正确配置插件执行阶段 解决:确保绑定到 `process-resources` 阶段 - **问题:扁平化POM缺少必要信息** 原因:`flattenMode` 配置过于严格 解决:调整为 `oss` 或 `default` 模式 - **问题:本地构建失败** 原因:未定义属性默认值 解决:在 `properties` 中提供默认版本值 ## 9. 与标准Maven插件的区别 | 插件 | 主要功能 | 输出结果 | |--------------------------|-----------------------------------|------------------------------| | `flatten-maven-plugin` | 生成部署用POM | 精简的扁平化POM | | `maven-source-plugin` | 打包源代码 | -sources.jar 文件 | | `maven-javadoc-plugin` | 生成Javadoc | -javadoc.jar 文件 | | `maven-deploy-plugin` | 部署构件到仓库 | 将构件传输到远程仓库 | 通过使用 `flatten-maven-plugin`,可以实现真正的 CI-Friendly 版本管理,解决多模块项目版本同步问题,并生成适合分发的精简 POM 文件[^1][^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值