2026/1/10 4:58:22
网站建设
项目流程
网站内页可以做关键词优化吗,临沂网站建设昂牛网络,iis下安装wordpress,东营做网站优化公司#x1f3af; 问题背景
在 Maven 多模块项目中#xff0c;你可能会看到项目根目录和各个子模块下都存在一个 .flattened-pom.xml 文件#xff0c;这个文件是做什么的#xff1f;能删除吗#xff1f;
问题的本质
这个问题涉及到 Maven 的一个核心矛盾#xff1a;
开发时的… 问题背景在 Maven 多模块项目中你可能会看到项目根目录和各个子模块下都存在一个.flattened-pom.xml文件这个文件是做什么的能删除吗问题的本质这个问题涉及到 Maven 的一个核心矛盾开发时的灵活性 VS 发布时的兼容性 ↓ ↓ 使用变量、继承 需要具体值、独立性 核心概念什么是.flattened-pom.xml.flattened-pom.xml是由Maven Flatten Plugin自动生成的扁平化 POM 文件。简单类比原始 pom.xml 带公式的 Excel 表格如SUM(A1:A10).flattened-pom.xml 计算后的结果表格只有具体数值为什么需要扁平化场景 1版本号变量问题!-- 原始 pom.xml开发时方便 --groupIdorg.gycoder/groupIdartifactIdsmart-common/artifactIdversion${revision}/version!-- 变量 --propertiesrevision1.0.0-SNAPSHOT/revision/properties问题当你把这个 JAR 发布到 Maven 中央仓库后别人依赖你的项目时!-- 其他开发者的项目 --dependencygroupIdorg.gycoder/groupIdartifactIdsmart-common/artifactIdversion${revision}/version!-- ❌ 别人的项目没有定义这个变量 --/dependencyMaven 报错Could not resolve dependencies: Failed to collect dependencies for org.gycoder:smart-common:jar:${revision}解决方案扁平化!-- ✅ .flattened-pom.xml发布时使用 --groupIdorg.gycoder/groupIdartifactIdsmart-common/artifactIdversion1.0.0-SNAPSHOT/version!-- 变量已被替换为具体值 --现在别人就可以正常依赖了dependencygroupIdorg.gycoder/groupIdartifactIdsmart-common/artifactIdversion1.0.0-SNAPSHOT/version!-- ✅ 清晰明确 --/dependency⚙️ 工作原理插件配置你的项目中!-- pom.xml:187-212 --plugingroupIdorg.codehaus.mojo/groupIdartifactIdflatten-maven-plugin/artifactIdversion1.7.2/versionconfiguration!-- 只解析 CI Friendly 变量 --flattenModeresolveCiFriendliesOnly/flattenMode!-- 更新 POM 文件生成 .flattened-pom.xml --updatePomFiletrue/updatePomFile/configurationexecutions!-- 在处理资源阶段生成扁平化 POM --executionidflatten/idphaseprocess-resources/phasegoalsgoalflatten/goal/goals/execution!-- 在清理阶段删除扁平化 POM --executionidflatten.clean/idphaseclean/phasegoalsgoalclean/goal/goals/execution/executions/plugin执行流程graph LR A[mvn install] -- B[process-resources 阶段] B -- C[flatten-maven-plugin 执行] C -- D[读取 pom.xml] D -- E[解析 ${revision} 1.0.0-SNAPSHOT] E -- F[生成 .flattened-pom.xml] F -- G[后续构建使用扁平化 POM] H[mvn clean] -- I[clean 阶段] I -- J[flatten-maven-plugin clean] J -- K[删除 .flattened-pom.xml]核心转换逻辑原始 pom.xml.flattened-pom.xml说明version${revision}/versionversion1.0.0-SNAPSHOT/version变量替换parent.../parent可能被移除或简化继承展开properties.../properties可能被移除属性内联化dependencyManagement根据模式处理依赖管理优化 项目实战分析你的项目使用情况1. 父 POMsmart-service-bot-parent!-- pom.xml:10 --version${revision}/version!-- pom.xml:31 --propertiesrevision1.0.0-SNAPSHOT/revision/properties分析✅ 使用了${revision}变量统一管理版本✅ 这是CI Friendly Versions的标准用法⚠️必须依赖flatten-maven-plugin 才能正常工作2. 依赖管理引用!-- pom.xml:52-58 --dependencygroupIdorg.gycoder/groupIdartifactIdsmart-dependencies/artifactIdversion${revision}/version!-- 引用同一个变量 --typepom/typescopeimport/scope/dependency分析✅ 确保所有模块版本一致⚠️ 如果没有扁平化其他模块无法解析这个依赖3. 子模块继承!-- 子模块 smart-common/pom.xml假设 --parentgroupIdorg.gycoder/groupIdartifactIdsmart-service-bot-parent/artifactIdversion${revision}/version!-- 继承父版本 --/parent分析✅ 子模块自动继承父模块版本⚠️ 发布时必须替换为具体版本号删除插件的后果模拟场景测试删除 flatten-maven-plugin 后执行构建# 1. 删除插件配置# 2. 执行构建mvn cleaninstall预期报错[ERROR] Failed to execute goal on project smart-common: Could not resolve dependencies for project org.gycoder:smart-common:jar:${revision}: Failed to collect dependencies at org.gycoder:smart-dependencies:pom:${revision}: Failed to read artifact descriptor for org.gycoder:smart-dependencies:pom:${revision}: Could not transfer artifact org.gycoder:smart-dependencies:pom:${revision} from/to central (https://repo.maven.apache.org/maven2): Illegal character in path at index 57: https://repo.maven.apache.org/maven2/org/gycoder/smart-dependencies/${revision}/...错误原因Maven 尝试从本地仓库读取smart-dependencies:${revision}变量${revision}没有被解析直接作为字符串使用路径中包含非法字符${}导致失败 深度理解CI Friendly Versions 的设计理念传统版本管理的痛点项目结构 smart-service-bot-parent (1.0.0-SNAPSHOT) ├── smart-common (1.0.0-SNAPSHOT) ├── smart-auth (1.0.0-SNAPSHOT) ├── smart-api (1.0.1-SNAPSHOT) ← 版本不一致 └── ...问题❌ 需要手动修改每个模块的 pom.xml❌ 容易遗漏某个模块导致版本混乱❌ 发布新版本时要改动 N 个文件CI Friendly 解决方案!-- 所有模块统一使用 --version${revision}/version!-- 只需在父 POM 修改一处 --propertiesrevision2.0.0-RELEASE/revision!-- 所有模块同步升级 --/properties优势✅ 单点修改全局生效✅ CI/CD 可通过命令行参数动态修改版本✅ 避免版本不一致问题CI/CD 集成示例# GitLab CI 示例build:script:# 动态生成版本号主版本.次版本.构建号-VERSION2.0.${CI_PIPELINE_ID}# 通过 -D 参数覆盖 revision 变量-mvn clean deploy-Drevision${VERSION}# 发布到 Maven 仓库时版本号为 2.0.1234对比传统方式# 传统方式需要用 mvn versions 插件修改所有 pom.xmlmvn versions:set -DnewVersion2.0.1234 mvn versions:commitgitadd.gitcommit -mBump version to 2.0.1234# 然后才能构建mvn clean deployMaven 依赖解析机制本地构建时的解析1. Maven Reactor 构建顺序 smart-service-bot-parent ├── 解析 ${revision} 1.0.0-SNAPSHOT从当前 POM properties ├── smart-common (version ${revision}) │ └── Maven Reactor 知道 ${revision} 1.0.0-SNAPSHOT └── smart-auth (version ${revision}) └── 依赖 smart-common:${revision} └── Maven Reactor 在内存中已有 smart-common:1.0.0-SNAPSHOT 结论本地多模块构建时Maven Reactor 能正确解析 ${revision}发布到仓库后的解析1. smart-common 发布到 Maven 仓库 repo/org/gycoder/smart-common/ ├── 1.0.0-SNAPSHOT/ │ ├── smart-common-1.0.0-SNAPSHOT.jar │ └── smart-common-1.0.0-SNAPSHOT.pom ← 如果没有扁平化包含 ${revision} 2. 其他项目依赖 smart-common dependency groupIdorg.gycoder/groupId artifactIdsmart-common/artifactId version1.0.0-SNAPSHOT/version /dependency 3. Maven 下载并读取 POM ❌ 如果 POM 中有 version${revision}/version → Maven 无法解析没有这个变量的定义 → 构建失败 ✅ 如果使用了 .flattened-pom.xml已替换为具体值 → Maven 可以正确解析 → 构建成功flattenMode 配置详解flattenModeresolveCiFriendliesOnly/flattenModeflattenMode说明适用场景resolveCiFriendliesOnly只解析${revision},${sha1},${changelist}三个变量推荐你的项目使用此模式oss更激进移除parent、properties等发布到 Maven Centralbom仅保留dependencyManagementBOM (Bill of Materials) 项目fatJar为 fat JAR 优化Spring Boot 可执行 JARdefaults默认模式平衡处理一般项目你的项目为什么选择resolveCiFriendliesOnly!-- 原始 pom.xml --parent.../parent!-- 保留子模块需要知道父模块信息 --propertiesrevision1.0.0-SNAPSHOT/revision!-- 仅解析这个 --java.version17/java.version!-- 保留其他属性不动 --/properties!-- .flattened-pom.xml --parent.../parent!-- ✅ 保留 --version1.0.0-SNAPSHOT/version!-- ✅ ${revision} 被替换 --propertiesjava.version17/java.version!-- ✅ 保留 --/properties✅ 最佳实践1. Git 版本控制# .gitignore.flattened-pom.xml **/.flattened-pom.xml原因.flattened-pom.xml是构建产物不是源代码每次构建都会重新生成提交没有意义不同开发者本地路径可能不同提交会导致冲突2. 持续集成配置# .gitlab-ci.yml 示例variables:MAVEN_OPTS:-Dmaven.repo.local$CI_PROJECT_DIR/.m2/repositorybuild:stage:buildscript:-mvn clean install-Drevision1.0.${CI_PIPELINE_ID}artifacts:paths:-target/*.jar# ❌ 不要包含 .flattened-pom.xml3. 版本号命名规范!-- 开发分支 --revision1.0.0-SNAPSHOT/revision!-- 发布候选 --revision1.0.0-RC1/revision!-- 正式发布 --revision1.0.0/revision!-- 紧急修复 --revision1.0.1-HOTFIX/revisionCI/CD 动态覆盖# 开发构建mvn cleaninstall-Drevision1.0.0-DEV-${BUILD_NUMBER}# 生产发布mvn clean deploy -Drevision1.0.04. 多模块版本策略策略 A所有模块统一版本推荐!-- 父 POM --revision2.0.0/revision!-- 所有子模块 --smart-common:2.0.0 smart-auth:2.0.0 smart-api:2.0.0优点✅ 版本一致易于管理✅ 发布时一起升级原子性操作缺点❌ 某个模块小改动也要升级整个版本策略 B模块独立版本!-- 父 POM --revision1.0.0/revision!-- 各模块独立定义 --smart-common:1.0.0 smart-auth:1.2.0!-- 认证模块有更新 --smart-api:1.1.0!-- API 有小改动 --优点✅ 模块独立演进缺点❌ 版本管理复杂❌ 不能使用${revision}失去 CI Friendly 优势建议对于你的项目使用策略 A已采用。5. 插件配置最佳实践plugingroupIdorg.codehaus.mojo/groupIdartifactIdflatten-maven-plugin/artifactIdversion1.7.2/versionconfiguration!-- 只解析 CI Friendly 变量保留其他配置 --flattenModeresolveCiFriendliesOnly/flattenMode!-- 更新 POM 文件生成 .flattened-pom.xml --updatePomFiletrue/updatePomFile!-- 扁平化后的依赖范围可选 --flattenDependencyModedirect/flattenDependencyMode!-- 输出目录默认是项目根目录 --outputDirectory${project.build.directory}/outputDirectory/configurationexecutions!-- 构建时生成 --executionidflatten/idphaseprocess-resources/phasegoalsgoalflatten/goal/goals/execution!-- 清理时删除 --executionidflatten.clean/idphaseclean/phasegoalsgoalclean/goal/goals/execution/executions/plugin⚠️ 常见误区误区 1认为可以手动编辑.flattened-pom.xml❌ 错误做法# 手动修改 .flattened-pom.xmlvim.flattened-pom.xml✅ 正确做法永远不要手动编辑此文件修改原始pom.xml插件会自动重新生成原因每次构建都会覆盖手动修改会丢失误区 2把.flattened-pom.xml提交到 Git❌ 错误做法gitadd.flattened-pom.xmlgitcommit -mAdd flattened pom✅ 正确做法# .gitignore.flattened-pom.xml **/.flattened-pom.xml原因这是构建产物不是源代码每个开发者构建结果可能不同会导致 Git 冲突误区 3误以为删除插件后项目还能正常工作场景!-- 删除 flatten-maven-plugin 配置 --!-- 但保留 ${revision} 变量 --结果mvn cleaninstall# ❌ 构建失败教训如果使用了${revision}等 CI Friendly 变量就必须配置 flatten-maven-plugin两者是配套的不能单独删除插件误区 4不理解 flattenMode使用错误的模式错误示例!-- ❌ 错误对于多模块项目使用 oss 模式 --flattenModeoss/flattenMode后果!-- .flattened-pom.xml --!-- ❌ parent 被移除子模块无法识别父模块 --!-- ❌ properties 全部被移除丢失重要配置 --正确做法!-- ✅ 多模块项目推荐 --flattenModeresolveCiFriendliesOnly/flattenMode误区 5本地能构建就认为发布也没问题场景# 本地构建成功mvn cleaninstall# ✅ 成功# 发布到 Maven 仓库mvn clean deploy# ✅ 成功# 其他项目依赖dependencygroupIdorg.gycoder/groupIdartifactIdsmart-common/artifactIdversion1.0.0-SNAPSHOT/version/dependency# ❌ 失败如果没有使用 flatten原因本地多模块构建Maven Reactor 在内存中管理所有模块发布后依赖Maven 从远程仓库下载 POM无法解析${revision}教训本地测试不能完全模拟真实依赖场景必须测试安装到本地仓库 → 新项目依赖的完整流程 总结对比表特性不使用 flatten-maven-plugin使用 flatten-maven-plugin版本号定义version1.0.0-SNAPSHOT/versionversion${revision}/version版本修改需手动修改每个模块只需修改一处revisionCI/CD 动态版本需要使用versions:set插件通过-Drevisionxxx参数本地构建✅ 正常✅ 正常发布到仓库✅ 正常✅ 正常使用扁平化 POM其他项目依赖✅ 正常✅ 正常变量已被替换版本一致性❌ 容易不一致✅ 强制一致Yudao 技术栈对齐❌ 不符合✅ 符合最佳实践 核心要点总结关键认知.flattened-pom.xml是什么Maven Flatten Plugin 的构建产物将包含变量的 POM 转换为具体值的 POM用于发布到 Maven 仓库供其他项目依赖为什么需要它开发时需要灵活性变量、继承、属性发布时需要确定性具体值、独立性、兼容性扁平化是连接两者的桥梁你的项目必须使用它✅ 已使用${revision}变量✅ 符合 Yudao 技术栈最佳实践✅ 多模块版本统一管理⚠️ 删除插件会导致构建失败实操建议操作建议原因删除 .flattened-pom.xml❌ 不要手动删除会自动重新生成编辑 .flattened-pom.xml❌ 永远不要编辑构建时会覆盖提交到 Git❌ 添加到 .gitignore这是构建产物删除 flatten-maven-plugin❌ 必须保留项目依赖此插件修改 flattenMode⚠️ 保持 resolveCiFriendliesOnly适合你的项目深刻理解Maven 依赖解析的本质问题 本地构建 远程依赖 ↓ ↓ Maven Reactor 独立 POM 文件 (内存管理) (文件读取) ↓ ↓ 可解析 ${revision} 无法解析 ${revision} ↓ ↓ 构建成功 ✅ 构建失败 ❌ 解决方案flatten-maven-plugin 原始 pom.xml .flattened-pom.xml ↓ ↓ ${revision} 变量 1.0.0-SNAPSHOT 具体值 ↓ ↓ 本地开发使用 发布到仓库使用