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.xmlpom.xml。虽然两种方法结果相同,但在 pom.xml 中配置仓库细节更具可移植性。但出于安全考虑(如敏感信息分发),不建议在 pom.xml 中包含仓库认证信息

所有示例的源代码可在 GitHub 获取。


原始标题:Define Multiple Repositories With Maven | Baeldung