Maven - 快照
一个大型软件应用通常由多个模块组成,多个团队同时在同一个应用的不同模块上工作是很常见的场景。例如,假设一个团队正在开发应用的 front end,作为 app-ui 项目(app-ui.jar:1.0),他们正在使用 data-service 项目(data-service.jar:1.0)。
现在,负责 data-service 的团队可能正在快速修复 bug 或进行增强,几乎每隔一天就向远程仓库发布库。
如果 dataservice 团队每隔一天上传一个新版本,就会出现以下问题 −
dataservice 团队每次发布更新代码时,都需要通知 app-ui 团队。
appui 团队需要定期更新他们的 pom.xml 以获取更新版本。
为了处理这种情况,SNAPSHOT 概念就派上用场了。
什么是 SNAPSHOT?
SNAPSHOT 是一个特殊的版本,表示当前的开发副本。与普通版本不同,Maven 在每次构建时都会检查远程仓库中是否有新的 SNAPSHOT 版本。
现在,data-service 团队每次都会将更新代码的 SNAPSHOT 发布到仓库,例如 data-service: 1.0-SNAPSHOT,替换旧的 SNAPSHOT jar。
Snapshot 与 Version 的区别
对于 Version,如果 Maven 已经下载了指定的版本,例如 dataservice:1.0,它将不会尝试下载仓库中可用的更新的 1.0。要下载更新代码,需要将 data-service 版本升级到 1.1。
对于 SNAPSHOT,Maven 会在 app-ui 团队每次构建项目时自动获取最新的 SNAPSHOT(dataservice:1.0-SNAPSHOT)。
appui pom.xml
app-ui 项目正在使用 data-service 的 1.0-SNAPSHOT。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>appui</groupId>
<artifactId>appui</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>appui</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dataservice</groupId>
<artifactId>dataservice</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
dataservice pom.xml
dataservice 项目会为每次小改动发布 1.0SNAPSHOT 版本。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dataservice</groupId>
<artifactId>dataservice</artifactId>
<packaging>jar</packaging>
<version>1.0-snapshot</version>
<name>dataservice</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
尽管对于 SNAPSHOT 版本,Maven 会每天自动获取最新的 SNAPSHOT,但你可以使用 -U 开关强制 Maven 下载最新的 snapshot build,适用于任何 maven 命令。
mvn clean package -U
示例 - 快照的使用
让我们创建两个 Maven 项目 appui 和 dataservice,其中 appui 使用版本 1.0,dataservice 使用版本 1.0-SNAPSHOT。
创建 appui 项目
D:\Projects\MVN>mvn archetype:generate -DgroupId=appui -DartifactId=appui -Dversion=1.0 -Dname=app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
创建 dataservice 项目
D:\Projects\MVN>mvn archetype:generate -DgroupId=dataservice -DartifactId=dataservice -Dversion=1.0-snapshot -Dname=dataservice -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
更新 pom.xml 以添加 data-service 依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>appui</groupId>
<artifactId>appui</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>app-ui</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dataservice</groupId>
<artifactId>dataservice</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
打开命令控制台,进入 D:\Projects\MVN\dataservice 目录,执行以下 mvn 命令将 dataservice 发布到本地仓库。
D:\Projects\MVN\dataservice>mvn install [INFO] Scanning for projects... [INFO] [INFO] ----------------------< dataservice:dataservice >----------------------- [INFO] Building dataservice 1.0-snapshot [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.3.1:resources (default-resources) @ dataservice --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\Projects\MVN\dataservice\src\main\resources [INFO] [INFO] --- compiler:3.13.0:compile (default-compile) @ dataservice --- [INFO] Nothing to compile - all classes are up to date. [INFO] [INFO] --- resources:3.3.1:testResources (default-testResources) @ dataservice --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\Projects\MVN\dataservice\src\test\resources [INFO] [INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ dataservice --- [INFO] Nothing to compile - all classes are up to date. [INFO] [INFO] --- surefire:3.2.5:test (default-test) @ dataservice --- [INFO] Using auto detected provider org.apache.maven.surefire.junit.JUnit3Provider [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running dataservice.AppTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.038 s -- in dataservice.AppTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- jar:3.4.1:jar (default-jar) @ dataservice --- [INFO] Building jar: D:\Projects\MVN\dataservice\target\dataservice-1.0-snapshot.jar [INFO] [INFO] --- install:3.1.2:install (default-install) @ dataservice --- [INFO] Installing D:\Projects\MVN\dataservice\pom.xml to C:\Users\mahes\.m2\repository\dataservice\dataservice\1.0-snapshot\dataservice-1.0-snapshot.pom [INFO] Installing D:\Projects\MVN\dataservice\target\dataservice-1.0-snapshot.jar to C:\Users\mahes\.m2\repository\dataservice\dataservice\1.0-snapshot\dataservice-1.0-snapshot.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.216 s [INFO] Finished at: 2025-09-15T16:34:03+05:30 [INFO] ------------------------------------------------------------------------
打开命令控制台,进入 D:\Projects\MVN\appui 目录,执行以下 mvn 命令。
D:\Projects\MVN\appui>mvn clean package -U
Maven 将在下载 dataservice 的最新 SNAPSHOT 后开始构建项目。
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------< appui:appui >-----------------------------
[INFO] Building appui 1.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ appui ---
[INFO] Deleting D:\Projects\MVN\appui\target
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ appui ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Projects\MVN\appui\src\main\resources
[INFO]
[INFO] --- compiler:3.13.0:compile (default-compile) @ appui ---
[INFO] Recompiling the module because of changed source code.
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file with javac [debug target 1.8] to target\classes
[WARNING] bootstrap class path is not set in conjunction with -source 8
not setting the bootstrap class path may lead to class files that cannot run on JDK 8
--release 8 is recommended instead of -source 8 -target 1.8 because it sets the bootstrap class path automatically
[WARNING] source value 8 is obsolete and will be removed in a future release
[WARNING] target value 8 is obsolete and will be removed in a future release
[WARNING] To suppress warnings about obsolete options, use -Xlint:-options.
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ appui ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Projects\MVN\appui\src\test\resources
[INFO]
[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ appui ---
[INFO] Recompiling the module because of changed dependency.
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file with javac [debug target 1.8] to target\test-classes
[WARNING] bootstrap class path is not set in conjunction with -source 8
not setting the bootstrap class path may lead to class files that cannot run on JDK 8
--release 8 is recommended instead of -source 8 -target 1.8 because it sets the bootstrap class path automatically
[WARNING] source value 8 is obsolete and will be removed in a future release
[WARNING] target value 8 is obsolete and will be removed in a future release
[WARNING] To suppress warnings about obsolete options, use -Xlint:-options.
[INFO]
[INFO] --- surefire:3.2.5:test (default-test) @ appui ---
[INFO] Using auto detected provider org.apache.maven.surefire.junit.JUnit3Provider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running appui.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.035 s -- in appui.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- jar:3.4.1:jar (default-jar) @ appui ---
[INFO] Building jar: D:\Projects\MVN\appui\target\appui-1.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.558 s
[INFO] Finished at: 2025-09-15T16:34:58+05:30
[INFO] ------------------------------------------------------------------------