四时宝库

程序员的知识宝库

Java 借助 aether 实现从指定 Maven 仓库下载 Jar 包

导读:笔者最近实现了一个用户只需在页面上提供 Maven dependency 描述(groupId、artifactId、version)后系统就会到指定的 maven 仓库中下载将对应 Jar 的小功能,该功能可用于打 fat Jar 时灵活获取所需的外部依赖。笔者主要是借助 Aether 来实现的,下面将展开具体讨论。

1. 项目依赖

<dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-aether-provider</artifactId>
            <version>3.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.aether</groupId>
            <artifactId>aether-connector-basic</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.aether</groupId>
            <artifactId>aether-transport-http</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>

2. 实现思路

用户在前端界面文本框中输入 dependency 描述

<dependency>
  	<groupId>org.eclipse.aether</groupId>
		<artifactId>aether-transport-http</artifactId>
		<version>1.1.0</version>
</dependency>

后台处理:

  1. 先将每个 dependency 描述映射为一个 Artifact 对象(关于映射的方案有多种这里就不给出具体方案了)
  2. 准备好要下载的 Artifact 列表
  3. 创建 RepositorySystem 这是用于操作 maven 仓库的主要接口
  4. 创建 RepositorySystemSession 同时指定下载路径
  5. 指定 RemoteRepository 远程仓库,此处笔者设置为 Maven 公共仓库(可自定义为私库等)
  6. 构建及发送请求下载 Jar 包到指定目录中

3.具体实现

3.1 指定要下载的 Artifact 列表

public static void main(String[] args) throws Exception {
        List<Artifact> artifacts = Lists.newArrayList(new DefaultArtifact("org.eclipse.aether", "aether-transport-http", "jar", "1.1.0"));
        resolveArtifacts(artifacts);
}

3.2 创建 RepositorySystem

private static RepositorySystem buildRepositorySystem() {
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
        locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
        return locator.getService(RepositorySystem.class);
    }

3.3 创建 RepositorySystemSession

private static RepositorySystemSession newSessopm(RepositorySystem repoSystem, String target) {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
        session.setLocalRepositoryManager(repoSystem.newLocalRepositoryManager(session, new LocalRepository(target)));
        return session;
    }

3.4 指定 RemoteRepository 远程仓库

private static List<RemoteRepository> getRemoteRepos() {
        List<RemoteRepository> reps = new ArrayList<>();
        RemoteRepository.Builder builder = new RemoteRepository.Builder("central", "default", "https://repo1.maven.org/maven2/");
        reps.add(builder.build());
        return reps;
    }

3.5 下载 Jar 包

private static void resolveArtifacts(List<Artifact> artifacts) throws Exception {
        RepositorySystem repoSystem = buildRepositorySystem();
        RepositorySystemSession session = newSessopm(repoSystem, DOWNLOAD_PATH);
        List<RemoteRepository> remoteRepos = getRemoteRepos();

        // read relevant artifact descriptor info
        List<Artifact> resolvedArtifacts = artifacts.stream()
                .map(artifact -> new ArtifactDescriptorRequest(artifact, remoteRepos, null))
                .map(artDescReq -> {
                    try {
                        return repoSystem.readArtifactDescriptor(session, artDescReq);
                    } catch (ArtifactDescriptorException e) {
                        throw new RuntimeException(e);
                    }
                })
                .flatMap(ar -> ar.getDependencies().stream())
                .filter(dependency -> "compile".equals(dependency.getScope()))
                .map(Dependency::getArtifact)
                .collect(Collectors.toList());

       artifacts.addAll(resolvedArtifacts);

        //download jar
        List<ArtifactRequest> artReqs = resolvedArtifacts.stream().map(artifact -> new ArtifactRequest(artifact, remoteRepos, null)).collect(Collectors.toList());
        Set<File> files = repoSystem.resolveArtifacts(session, artReqs).stream().map(artifactResult -> artifactResult.getArtifact().getFile()).collect(Collectors.toSet());
        for (File file : files) {
            System.out.println(file);
        }
    }

3.6 结果打印

/usr/local/test/mvnrepo/org/eclipse/aether/aether-api/1.1.0/aether-api-1.1.0.jar
/usr/local/test/mvnrepo/org/eclipse/aether/aether-util/1.1.0/aether-util-1.1.0.jar
/usr/local/test/mvnrepo/org/slf4j/jcl-over-slf4j/1.6.2/jcl-over-slf4j-1.6.2.jar
/usr/local/test/mvnrepo/org/eclipse/aether/aether-spi/1.1.0/aether-spi-1.1.0.jar
/usr/local/test/mvnrepo/org/apache/httpcomponents/httpclient/4.3.5/httpclient-4.3.5.jar
Disconnected from the target VM, address: '127.0.0.1:57506', transport: 'socket'

4.关于代码

完整代码已上传至 Github 上

https://github.com/senlizishi/aether-download-maven-jar.git

最后

以上就是笔者借助 aether 实现从指定 maven 仓库下载 Jar 包的方式,希望对各位有所帮助。

感谢您的阅读,如果喜欢本文欢迎关注和转发,转载需注明出处,本头条号将持续分享IT技术知识。对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步。

参考文章

https://www.cnblogs.com/xiaosiyuan/articles/5887642.html

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接