You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java代码从Maven中央仓库或特定仓库下载依赖?

从Maven仓库自动下载依赖并管理版本的实现方案

你这个场景完全可以用Apache Aether来搞定——它就是Maven底层用来处理依赖解析、下载的核心库,成熟稳定,不用自己造轮子去解析Maven仓库的元数据(比如maven-metadata.xml)。下面给你具体的实现步骤和代码示例:

一、先引入Aether依赖

在你的项目pom.xml里加这些依赖(Gradle项目可自行转换为对应格式):

<dependencies>
    <!-- Aether核心组件 -->
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-aether-provider</artifactId>
        <version>3.9.6</version>
    </dependency>
    <!-- 基础仓库连接器 -->
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-connector-basic</artifactId>
        <version>2.0.1</version>
    </dependency>
    <!-- HTTP传输组件 -->
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-transport-http</artifactId>
        <version>2.0.1</version>
    </dependency>
</dependencies>

二、核心实现代码

1. 初始化Aether基础环境

先搭建Aether的仓库配置、会话管理等基础组件:

import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResult;

import java.util.ArrayList;
import java.util.List;

public class MavenDependencyHandler {
    // 获取Aether实例
    private static RepositorySystem getRepositorySystem() {
        return org.apache.maven.repository.internal.MavenRepositorySystemUtils.newRepositorySystem();
    }

    // 创建会话,配置本地仓库路径
    private static RepositorySystemSession createSession(RepositorySystem system, String localRepoPath) {
        org.eclipse.aether.DefaultRepositorySystemSession session = org.apache.maven.repository.internal.MavenRepositorySystemUtils.newSession();
        LocalRepository localRepo = new LocalRepository(localRepoPath);
        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
        return session;
    }

    // 配置远程仓库(中央仓库+自定义仓库)
    private static List<RemoteRepository> getRemoteRepos(RepositorySystem system, RepositorySystemSession session) {
        List<RemoteRepository> repos = new ArrayList<>();
        // 加入Maven中央仓库
        repos.add(new RemoteRepository.Builder("central", "default", "https://repo1.maven.org/maven2/").build());
        // 如需私有仓库,可添加以下配置(替换为实际地址和认证信息)
        // repos.add(new RemoteRepository.Builder("private-repo", "default", "https://your-private-repo.com/maven/")
        //         .setAuthentication(new AuthenticationBuilder().addUsername("user").addPassword("pass").build())
        //         .build());
        return repos;
    }
}

2. 下载指定依赖(含传递依赖)

传入标准Maven坐标(如com.google.code.gson:gson:2.8.9),自动下载依赖到本地仓库,并返回Jar文件路径:

// 下载依赖,返回所有下载完成的Jar文件绝对路径
public List<String> downloadDependency(String dependencyCoords, String localRepoPath) {
    RepositorySystem system = getRepositorySystem();
    RepositorySystemSession session = createSession(system, localRepoPath);
    List<RemoteRepository> repos = getRemoteRepos(system, session);

    // 解析依赖坐标
    DefaultArtifact artifact = new DefaultArtifact(dependencyCoords);
    Dependency dependency = new Dependency(artifact, "compile");
    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot(dependency);
    collectRequest.setRepositories(repos);

    DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, null);
    try {
        DependencyResult result = system.resolveDependencies(session, dependencyRequest);
        List<String> jarPaths = new ArrayList<>();
        result.getArtifactResults().forEach(artifactResult -> {
            jarPaths.add(artifactResult.getArtifact().getFile().getAbsolutePath());
        });
        return jarPaths;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

3. 查询依赖的所有可用版本

如果插件开发者填写了版本范围(如gson:2.8.+),或你需要管理版本列表,可通过此方法获取仓库中该依赖的所有版本:

import org.eclipse.aether.resolution.VersionRangeRequest;
import org.eclipse.aether.resolution.VersionRangeResult;

// 获取指定groupId:artifactId的所有可用版本
public List<String> getAllAvailableVersions(String groupId, String artifactId, String localRepoPath) {
    RepositorySystem system = getRepositorySystem();
    RepositorySystemSession session = createSession(system, localRepoPath);
    List<RemoteRepository> repos = getRemoteRepos(system, session);

    // 使用版本范围匹配所有可用版本
    DefaultArtifact artifact = new DefaultArtifact(groupId + ":" + artifactId + "[0,)");
    VersionRangeRequest request = new VersionRangeRequest(artifact, repos, null);
    try {
        VersionRangeResult result = system.resolveVersionRange(session, request);
        List<String> versions = new ArrayList<>();
        result.getVersions().forEach(version -> versions.add(version.toString()));
        return versions;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

三、插件元数据设计建议

让插件开发者在元数据文件(如plugin.json)中按Maven坐标格式填写依赖,示例:

{
  "pluginId": "demo-plugin",
  "pluginName": "示例插件",
  "dependencies": [
    "com.google.code.gson:gson:2.8.9",
    "org.apache.commons:commons-lang3:3.12.0"
  ]
}

你只需解析该JSON,取出每个依赖坐标调用下载方法即可。若允许版本范围(如com.google.code.gson:gson:[2.8,3.0)),Aether会自动解析出符合范围的最新版本。

四、关键注意事项

  • 复用本地Maven仓库:可直接使用用户默认的Maven本地仓库路径(一般为~/.m2/repository),避免重复下载已存在的依赖。
  • 缓存机制:自行维护已下载依赖的缓存列表,记录坐标与本地路径,减少远程仓库请求。
  • 依赖冲突处理:若多个插件依赖同一库的不同版本,需添加冲突仲裁逻辑(如选择最高版本、优先插件指定版本),Aether支持自定义冲突策略。
  • 私有仓库认证:私有仓库需在RemoteRepository配置中添加用户名密码,参考代码注释部分。

内容的提问来源于stack exchange,提问作者Chuanwise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:35:22