1. 概述
Apache Maven 允许我们定义仓库作为存储和检索项目构件的中心位置。某些场景下,当项目依赖仅存在于特定仓库的库时,我们就需要定义多个仓库。
本教程将探索 Maven 中实现此需求的两种主要方式:通过settings.xml 文件和pom.xml 文件。
2. 将自定义 JAR 部署到私有仓库
为演示这些方法,我们首先将简单的 GreeterServiceExample 部署到私有远程仓库:
public class GreeterServiceExample {
public Greeting greetInYourLanguage(String language) {
return switch (language.toLowerCase()) {
case "english" -> new Greeting("Hello", new Language("English", "en"));
case "spanish" -> new Greeting("Hola", new Language("Spanish", "es"));
case "xhosa" -> new Greeting("Molo", new Language("Xhosa", "xh"));
default -> null;
};
}
}
该服务根据选定语言返回特定语言的 Greeting 对象。
部署构件前,需在 POM 或 settings.xml 中指定仓库信息:
<repositories>
<repository>
<id>internal-maven-repo</id>
<name>Internal Repository</name>
<url>https://host/internal-maven-packages</url>
</repository>
<!-- 其他仓库 -->
</repositories>
接着更新 settings.xml,添加包含认证信息的 server 指令:
<server>
<id>internal-maven-repo</id>
<username>dev_user</username>
<password>secure_token_123</password>
</server>
除认证凭据外,还指定了仓库配置引用的唯一 ID。
现在将示例库发布到内部仓库:
mvn deploy:deploy-file \
-DgroupId=com.baeldung \
-DartifactId=maven-multiple-repositories \
-Dversion=0.0.1 \
-Dpackaging=jar \
-Dfile=./target/GreeterExampleService.jar \
-DrepositoryId=internal-maven-repo \
-Durl=https://repo.example.com/internal-maven-packages
在 deploy:deploy-file 目标中,我们指定了:
- settings.xml 中定义的 repositoryId
- 待部署的 file
- 仓库 URL(均为必需参数)
若需将构件部署到其他仓库,需对每个仓库重复此部署过程。
自定义库部署完成后,我们探索如何在其他项目中使用此依赖。
3. 通过 settings.xml 配置仓库
Maven 配置文件可帮助自定义构建配置。在 settings.xml 中添加配置文件定义:
<profile>
<id>local-dev</id>
<repositories>
<repository>
<id>internal-maven-repo</id>
<name>Internal Repository</name>
<url>https://host/internal-maven-packages</url>
</repository>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
</profile>
内部仓库定义中,确保仓库 ID 与 server 指令中的 ID 匹配。虽然中央仓库配置继承自 Super POM,但此处为演示目的显式包含。
将新定义的配置文件添加到 settings.xml 的激活列表:
<activeProfiles>
<activeProfile>local-dev</activeProfile>
</activeProfiles>
此操作会为所有构建激活该配置文件。
指定上传库的依赖:
<dependency>
<groupId>com.baeldung</groupId>
<artifactId>maven-multiple-repositories</artifactId>
<version>0.0.1</version>
</dependency>
执行 Maven install 目标下载依赖:
mvn install
构建成功,因为所有依赖均从各自仓库正确获取。在单元测试中使用导入的库:
@Test
public void whenGreetingInEnglish_thenAnENCodeShouldBeMadeAvailable() {
GreeterServiceExample greeterService = new GreeterServiceExample();
Greeting englishGreeting = greeterService.greetInYourLanguage("English");
assertEquals("en", englishGreeting.getLanguage().getCode());
}
在 settings.xml 中配置仓库信息适合本地开发,但在多构建环境中可能变得繁琐。我们探索另一种方案。
4. 通过 pom.xml 配置仓库
POM 文件允许指定使用的仓库,并可选择在构建配置文件内外定义仓库细节。在 Maven 构建配置文件外定义仓库:
<repositories>
<repository>
<id>internal-maven-repo</id>
<name>Internal Repository</name>
<url>https://host/internal-maven-packages</url>
</repository>
<!-- 其他仓库 -->
</repositories>
⚠️ 重要:由于内部仓库需要认证,最佳实践是将凭据保留在 settings.xml 的 server 指令中,避免随源代码分发敏感信息。再次确保仓库 ID 与 settings.xml 中的 server 指令匹配。
执行构建:
mvn clean install
由于仓库定义在构建配置文件外,Maven install 目标中无需指定配置文件。
5. 总结
本教程探索了 Maven 中指定多个仓库的两种方法:使用 settings.xml 和 pom.xml。虽然两种方法结果相同,但在 pom.xml 中配置仓库细节更具可移植性。但出于安全考虑(如敏感信息分发),不建议在 pom.xml 中包含仓库认证信息。
所有示例的源代码可在 GitHub 获取。