一、背景
在 Java Maven 项目中,我们经常会看到不同形式的版本号,例如:
xml
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0</version>
<version>1.0.0-RELEASE</version>
这些版本号看起来差别不大,但在 Maven 构建、Nexus 私服发布、依赖管理和生产环境稳定性方面,影响非常明显。
本文将系统说明 Maven 中的快照版本、正式版本,以及 Nexus 仓库中的常见规则和最佳实践。
二、Maven 中的版本类型
1. SNAPSHOT 快照版本
以 -SNAPSHOT 结尾的版本,称为快照版本。
示例:
xml
<version>1.0.0-SNAPSHOT</version>
SNAPSHOT 表示该版本仍处于开发阶段,内容可能随时变化。
当快照版本发布到 Nexus 后,Maven 实际上传的文件名可能会变成:
text
demo-1.0.0-20260513.102233-3.jar
但项目中依赖时仍然写:
xml
<version>1.0.0-SNAPSHOT</version>
Maven 会通过 maven-metadata.xml 找到最新的快照构建。
2. Release 正式版本
不以 -SNAPSHOT 结尾的版本,默认都是正式版本。
示例:
xml
<version>1.0.0</version>
正式版本表示该版本已经发布完成,内容应当稳定且不可变。
如果发现问题,不应该覆盖原来的 1.0.0,而应该发布新的版本,例如:
text
1.0.0 -> 1.0.1 -> 1.0.2
3. 只有版本号是什么意思
例如:
xml
<version>1.0.0</version>
这是 Maven 中最标准的正式版本写法。
而:
xml
<version>1.0.0-RELEASE</version>
虽然也会被 Maven 当作正式版本,但通常没有必要。因为 Maven 本身已经通过是否包含 -SNAPSHOT 来区分快照版本和正式版本。
三、Nexus 中的仓库类型
Nexus 私服通常会配置两个 Maven 仓库:
| 仓库名称 | 接收版本 | 使用场景 |
|---|---|---|
maven-snapshots |
*-SNAPSHOT |
开发、联调、测试 |
maven-releases |
非 SNAPSHOT 版本 |
预发、生产、正式发布 |
常见对应关系如下:
text
1.0.0-SNAPSHOT -> maven-snapshots
1.0.0 -> maven-releases
1.0.0-RELEASE -> maven-releases
如果将 SNAPSHOT 版本发布到 release 仓库,或者将正式版本发布到 snapshot 仓库,Nexus 通常会拒绝上传。
四、不同版本类型的影响
1. 对构建稳定性的影响
SNAPSHOT 版本是可变的,同一个版本号可能对应不同的包内容。
这意味着:
xml
<version>1.0.0-SNAPSHOT</version>
今天构建成功,明天可能因为依赖包被重新发布而失败。
正式版本则不同:
xml
<version>1.0.0</version>
只要 Nexus 不允许覆盖,任何时间拉取到的 1.0.0 都应该是同一个内容。
2. 对问题排查的影响
如果生产环境依赖了 SNAPSHOT,出现问题时很难确认当时实际使用的是哪一次构建产物。
正式版本更容易追踪问题:
text
服务版本:1.0.1
依赖版本:common-utils-2.3.0
发布时间:2026-05-13
版本清晰后,日志、部署记录、制品仓库和代码提交记录才能对应起来。
3. 对团队协作的影响
开发阶段使用 SNAPSHOT 可以提升联调效率。
例如公共模块还在频繁修改时,业务项目可以先依赖:
xml
<version>2.0.0-SNAPSHOT</version>
但进入测试验收或生产发布阶段,应当切换为明确的正式版本:
xml
<version>2.0.0</version>
五、常见问题
1. 生产环境依赖 SNAPSHOT
这是非常不推荐的做法。
原因包括:
- 构建不可复现
- 包内容可能被覆盖
- 问题排查困难
- 发布链路不可审计
生产环境应当依赖明确的 release 版本。
2. 重复发布同一个 release 版本
如果 Nexus 允许覆盖 release 包,会带来严重风险。
例如第一次发布的 1.0.0 和第二次覆盖上传的 1.0.0 内容不同,但版本号完全一样。
这会导致不同环境、不同机器、不同时刻拉到的依赖内容不一致。
正确做法是:
text
发现问题 -> 修改代码 -> 升级版本号 -> 发布新版本
例如:
text
1.0.0 -> 1.0.1
3. 使用 LATEST 或 RELEASE 作为依赖版本
不建议这样写:
xml
<version>LATEST</version>
<version>RELEASE</version>
这种写法会让 Maven 自动选择版本,构建结果不可控。现代 Maven 项目中应当显式指定具体版本号。
六、推荐实践
1. 开发阶段使用 SNAPSHOT
xml
<version>1.1.0-SNAPSHOT</version>
适用于:
- 本地开发
- 模块联调
- 测试环境快速验证
2. 发布阶段使用正式版本
xml
<version>1.1.0</version>
适用于:
- 测试验收
- 预发环境
- 生产环境
- 对外发布的公共组件
3. Release 仓库禁止覆盖
Nexus 中建议配置 release 仓库不允许重复部署。
这样可以保证:
- 版本不可变
- 构建可复现
- 问题可追踪
- 发布链路更可靠
4. 版本号保持简洁
推荐:
text
1.0.0
1.0.1
1.1.0
2.0.0
不推荐无必要地写成:
text
1.0.0-RELEASE
因为 1.0.0 本身已经是正式版本。
七、总结
Maven 中判断快照版本和正式版本的核心规则非常简单:
只有以
-SNAPSHOT结尾的版本才是快照版本,其他版本默认都是正式版本。
SNAPSHOT 适合开发和联调,特点是灵活但不稳定。
Release 适合正式发布,特点是稳定、可追踪、可复现。
在 Nexus 私服中,应当将快照版本和正式版本分别发布到不同仓库,并严格禁止正式版本被覆盖。
最终推荐规范如下:
text
开发版本:1.0.1-SNAPSHOT
正式版本:1.0.1
修复版本:1.0.2
良好的版本管理不仅能减少依赖冲突,也能提升构建稳定性、发布可靠性和线上问题排查效率。