Gradle从0入门到实战系列【九】仓库与私服

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Gradle沿用了Maven仓库,在使用仓库时能够很友好的基于Maven仓库提供功能,但Gradle所产生的构建并不会提供给Maven仓库,因为Gradle自己拷贝了一份Maven本地仓库缓存到了自己仓库目录下。

image.png

  1. 本地仓库:指存在于我们本机的仓库,在我们加入依赖时候,首先会跑到我们的本地仓库去找,如果找不到则会跑到远程仓库中去找。
  2. 远程仓库:指其他服务器上的仓库,包括全球中央仓库,公司内部的私服,又或者其他公司或组织提供的公共库。

    • 中央仓库:Maven中央仓库,服务于全球
    • 私服:私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。有了私服之后,当 Gradle、Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载。

      私服的优点:解决中央仓库网络、重复下载、本公司非公开组件多项目依赖等问题。
      在团队协作开发中,为了提高开发效率,每个公司会有自己的私有仓库,私服是一种特殊的远程仓库,部署在局域网内,开发人员需要构建提交自己的项目组件至服务器,方便其他同事可以下载下来进行协同开发,如下就是围绕私服进行的团队开发协作流程。

    • 其他公共库:阿里云镜像的远程仓库

构件的坐标

  • 坐标使用示例

    <!-- maven -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.3.20</version>
    </dependency>
    
    // gradle
    dependencies {
        implementation 'org.springframework:spring-core:5.3.20'
    }
  • 坐标解析

    • groupId:项目所属的组,由java中的package命衍生而来,通常与域名反向一 一对应
    • artifactId:模块名或项目名
    • version:定义项目版本
  • 坐标查询

本地仓库

如果不指定,默认为: ${user.home}/.gradle

  • Linux:~/.gradle
  • WIn:~\.gradle

若要改变默认的本地仓库,可以在环境变量中通过GRADLE_USER_HOME进行指定,如下:

image.png

细心的同学也会发现,在之前的课程中,gradle-wrapper.properties文件中就使用到了GRADLE_USER_HOME这个变量。

Gradle仓库目录说明

.gradle
  - .tmp
  - caches:缓存目录,除了缓存jar还会缓存一些运行时的缓存,使用构建缓存的目的是为了让构建更快,像单元测试任务、Jacoco任务都是可以被缓存
  - daemon:守护进程相关存储目录,gradle的守护进程是一个长期存在的进程,这可以节约jvm启动成本,在内存中缓存项目结构、文件、任务等信息,从而加快gradle的构建,在3.0时就已经默认启用,可以通过no-deamon参数不启用守护进程或配置gradle.properties停用守护进程,守护进程默认驻守3个小时候会自动关闭
  - jdks:环境标志,如go语言就是go目录
  - native:用于存放平台相关(Win/Linux/Mac)的库。
  - notifications
  - workers
  - wrapper:gradle-wrapper下载目录
  

Gradle交互进程剖析

$ ./gradlew build
1. 会启动一个jvm进程,启动的jvm进程为deamon进程
2. 当前运行的窗口作为client,client会将

守护进程剖析

# 查看daemon进程是否有启动
$ ./gradlew --status
No Gradle daemons are running.

# 执行build命令,如果daemon没启动,那么会先启动
$ ./gradlew build
Starting Gradle Daemon...
Gradle Daemon started in 3 s 473 ms

# 查看已经存在一个空闲的守护进程了
$ ./gradlew --status
   PID STATUS   INFO
  9140 IDLE     7.4.1
  
# 停止守护进程
$ ./gradle --stop
Stopping Daemon(s)
1 Daemon stopped
为什么会启动多个守护进程

Gradle 将创建一个新的守护进程而不是使用一个已经在运行的守护进程有几个原因。基本规则是,如果没有现有的空闲或兼容的守护程序,Gradle 将启动一个新的守护程序。Gradle 将杀死任何闲置 3 小时或更长时间的守护进程,因此不必手动清理它们。

远程仓库

是指非本地的远程网络上的仓库。私服、其他公共仓库、中央仓库均被称为远程仓库,远程仓库可以看做为一个庞大的项目组件仓库中心,私服是一种特殊远程仓库,它是部署局域网内的仓库。

中央仓库

Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。

中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。

中央仓库的关键概念:

  • 这个仓库由 Maven 社区管理。
  • 不需要配置。
  • 需要通过网络才能访问。

镜像仓库

阿里云Maven中央仓库为 阿里云云效 提供的公共代理仓库,帮助研发人员提高研发生产效率,使用阿里云Maven中央仓库作为下载源,速度更快更稳定。

私服

私服的优点:解决中央仓库网络、重复下载、本公司非公开组件多项目依赖等问题。
在团队协作开发中,为了提高开发效率,每个公司会有自己的私有仓库,私服是一种特殊的远程仓库,部署在局域网内,开发人员需要构建提交自己的项目组件至服务器,方便其他同事可以下载下来进行协同开发,如下就是围绕私服进行的团队开发协作流程。

image.png

image.png

私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载。

私服的优点:解决中央仓库网络、重复下载、本公司非公开组件多项目依赖等问题。
在团队协作开发中,为了提高开发效率,每个公司会有自己的私有仓库,私服是一种特殊的远程仓库,部署在局域网内,开发人员需要构建提交自己的项目组件至服务器,方便其他同事可以下载下来进行协同开发,如下就是围绕私服进行的团队开发协作流程。

Windows安装

网上下载安装包

  • nexus-3.31.1-01:服务及可执行文件
  • sonatype-work:文件存储的工作目录

找到nexus-3.31.1-01-win64\nexus-3.31.1-01\bin\nexus.exe,通过CMD命令行的方式进入,然后在bin目录下运行nexus.exe/run

image.png

如果出现端口占用无法启动的情况,可以修改sonatype-work\nexus3\etc\nexus.properties文件

image.png

image.png

image.png

Docker安装

环境:CentOS 7、 JDK8 、Sonatype Nexus、Docker,服务器IP:192.168.2.195

  1. 拉取镜像

    $ docker pull sonatype/nexus3
  2. 运行nexus容器

    # 创建一个目录用于存放容器挂载的数据
    mkdir –p /usr/local/nexus3/nexus-data/
    chmod 777 /usr/local/nexus3/
    
    docker run -d \
    --privileged=true \
    --name=nexus3 \
    -p 5000:5000 \
    -p 8081:8081 \
    -v /usr/local/nexus3/nexus-data:/var/nexus-data \
    -e INSTALL4J_ADD_VM_PARAMS="-Xms1024M -Xmx1024M" \
    b7c023b6a9b9   # 注意此处是镜像ID
    
    # 查看启动日志,是否成功启动
    $ docker logs nexus3
    
    # 启动成功的日志如下
    2022-05-14 09:04:38,819+0000 INFO  [jetty-main-1] *SYSTEM org.eclipse.jetty.server.Server - Started @55942ms
    2022-05-14 09:04:38,820+0000 INFO  [jetty-main-1] *SYSTEM org.sonatype.nexus.bootstrap.jetty.JettyServer -
    -------------------------------------------------
    
    Started Sonatype Nexus OSS 3.38.1-01
    
    -------------------------------------------------
    
    
    # 如果http://ip:8081访问不到,则需要配置一下防火墙加入端口
    $ firewall-cmd --zone=public --add-port=8081/tcp --permanent
    $ firewall-cmd --zone=public --add-port=5000/tcp --permanent
    $ firewall-cmd --reload
    
    # 获取登录密码
    $ docker exec -it nexus3 /bin/bash
    $ cat /nexus-data/admin.password
    

访问nexus3

登录仓库页面:http://ip:8081

默认账号admin,初始始密码则存在容器中的/nexus-data/admin.password文件中。

进入Nexus配置界面:

image.png

image.png

私服仓库

仓库类型

  1. 宿主类型:此类型所描述的仓库,主要用于存放内部发布的的项目构件,和外部没有连接关系,是由公司内部用户发布上来的项目(其典型代表为:release仓库、snapshots仓库)
  2. 代理类型:此类型所描述的仓库,主要是提供下载缓存构件和插件、比如你请求一个jar,它实际从远程中央仓库中寻找数据的仓库,如果只是从远程仓库下载构件和插件、那么代理仓库完全足够(其典型代表为:central中央仓库、阿里云仓库、apache仓库)。
  3. 仓库组类型:用于聚合多个仓库,为外部提供统一的地址,此类型描述的仓库,把其他的仓库使用同一个地址暴露出去,组仓库用来方便我们开发人员进行设置的仓库,不具有实际的功能,只是一个概念,简单来说就是访问这个group设置的一个地址,其他仓库的jar都能获取到

image.png

<!--我们配置阿里云镜像仓库时就可以使用它的public-->
<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>https://maven.aliyun.com/repository/public/</url>
</mirror>

image.png

image.png

Format

  1. maven2maven类型仓库,区别于老版本中的maven1
  2. nuget.net使用,NuGet 是一个Visual Studio的扩展。在使用Visual Studio开发基于.NET Framework的应用时,NuGet能够令你在项目中添加、移除和更新引用的工作变得更加快捷方便。

Name

  1. maven-central:用来代理Maven中央仓库,其策略为Release,只会下载和缓存中央仓库中的发布版本的构件
  2. maven-public:该仓库组将上述所有存储策略为Release的仓库聚合并通过统一的地址提供服务。
  3. maven-releases:策略为Release的宿主仓库,用来部署公司或组织内部的发布版本构件。
  4. maven-snapshots:策略为Snapshot的宿主仓库,用来部署公司或组织内部的快照版本构件。

使用私服

下载构建

  1. 将中央仓库的代理地址改代理为阿里云镜像仓库

    image.png

  1. build.gradle中,使用私服的public地址

    buildscript {
        repositories {
            maven {
                allowInsecureProtocol = true
                url 'http://192.168.2.195:8081/repository/maven-public/'
            }
        }
    }
    
    repositories {
        maven { 
            //忽略https
            allowInsecureProtocol = true
            url 'http://192.168.2.195:8081/repository/maven-public/' 
        }
    }
    
  2. 添加依赖,并检查私服和本地仓库是否有该jar包

    implementation 'org.apache.commons:commons-compress:1.20'
  3. 如果出现jar包无法拉下来,如何解决,这里我以org.springframework.boot:spring-boot-starter:2.6.4为例

    image.png

    • 先确认maven-central中的代理地址是否是https://maven.aliyun.com/repository/public/,其他地址有可能因为网络原因导致从中央仓库拉取jar包失败
    • 再确认你的maven-central仓库中是否存在该jar包

      • 如果私服存在,则删除你本地caches目录下的modules-2目录,重启IDEA即可
    • 如果maven-central不存在,则需要去中央仓库查看是否存在该jar

      image.png

    • 如果maven-central中的文件不完整,比如只有pom没有其他文件,且以上操作均无效,则可能需要重建私服索引

      image.png

publishing插件发布

plugins{
    id 'maven-publish'
}
publishing {
    publications { ... }
    repositories.maven { ... }
}
// 通过上述配置我们可以知道publishing有2个属性publications和repositories,而publishing作为maven-publish提供的插件类,实际上是一个PublishingExtension
  1. PublishingExtension

    public class DefaultPublishingExtension implements PublishingExtension {
        private final RepositoryHandler repositories;
        private final PublicationContainer publications;
    
        public DefaultPublishingExtension(RepositoryHandler repositories, PublicationContainer publications) {
            this.repositories = repositories;
            this.publications = publications;
        }
    
        public RepositoryHandler getRepositories() {
            return this.repositories;
        }
    
        public void repositories(Action<? super RepositoryHandler> configure) {
            configure.execute(this.repositories);
        }
    
        public PublicationContainer getPublications() {
            return this.publications;
        }
    
        public void publications(Action<? super PublicationContainer> configure) {
            configure.execute(this.publications);
        }
    }
  2. PublicationContainer

    publications就是PublicationContainer的实例,

    PublicationContainer 负责创建和管理 Publication 实例。具体的Publication实例,需要看你使用的事什么插件,当前有ivy-publishmaven-publish,对应的实例是(IvyPublication以及MavenPublication)

    • ivy

      plugins {
           id 'ivy-publish'
      }
      
      publishing.publications.create('publication-name', IvyPublication) {
           // Configure the ivy publication here
      }
      或
      publishing {
          publications {
              myOrderJar(IvyPublication) {
                  // Configure the ivy publication here
              }
          }
      }
    • maven

      plugins {
           id 'maven-publish'
       }
      
       publishing.publications.create('publication-name', MavenPublication) {
           // Configure the ivy publication here
       }
      或
      publishing {
          publications {
              myOrderJar(MavenPublication) {
                  // Configure the maven publication here
              }
          }
      }
  3. RepositoryHandler

    repositories闭包可以设置具体的RepositoryHandler实例,提供了众多方法,用于指定仓库或本地目录

    • FlatDirectoryArtifactRepository:指定目录,如:libs里面的jar包
    • IvyArtifactRepository:ivy仓库
    • MavenArtifactRepository:Maven仓库

      repositories {
          maven {
              ...
          }
      }
  4. 编写完整的build.gradle

    plugins {
        ...
        id 'maven-publish'
        ...
    }
    
    publishing {
        publications {
            //打springboot-jar包
            orderJar(MavenPublication) {
                artifact bootJar
                from components.java
            }
            //可以配置多个,如下:
            /*
            dbchangelog(MavenPublication) {
                //指定包名
                artifactId 'order-db-changelog'
                //可以依赖一个task
                artifact dbChangelogZip
            }
            */
        }
    
        repositories {
            maven {
                //忽略https
                allowInsecureProtocol true
                name = 'it235-order'
                //nexus3的url
                def releasesRepoUrl = "http://192.168.2.195:8081/repository/maven-releases/"
                def snapshotsRepoUrl = "http://192.168.2.195:8081/repository/maven-snapshots/"
    
                url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
                credentials {
                    username 'admin'
                    password 'abc123'
                }
            }
        }
    }
  5. 执行publish任务

    上述闭包配置作用在于创建两个实现了MavenPublication接口的task

    • publishOrderJarPublicationToMavenLocal发布到本地仓库
    • publishOrderJarPublicationToMavenRepository发布到远程仓库。

    也可以直接双击publish任务执行

  6. 查看nexus服务是否已经存在it235-order

手工发布

image.png

image.png

总结

在企业中一般会使用自己搭建的nexus私服,其次是直接使用阿里云镜像仓库,通过这篇文章的学习应该让你对repository的了解更加深入,接下来我们继续进入下一篇的学习。

相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。 &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
6月前
|
XML Java 测试技术
Gradle安装部署与基础入门详解
Gradle安装部署与基础入门详解
725 0
|
Java 测试技术 Spring
Gradle从0入门到实战系列【八】SpringBoot集成Junit单元测试
JUnit 是一个 Java 编程语言的单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。
1615 1
Gradle从0入门到实战系列【八】SpringBoot集成Junit单元测试
|
3月前
|
Java 开发工具 Maven
Flutter和Android中覆盖gradle中的repositories仓库地址
Flutter和Android中覆盖gradle中的repositories仓库地址
190 4
|
5月前
|
Java Maven Kotlin
在 build.gradle.kts 添加 阿里云仓库
在 build.gradle.kts 添加 阿里云仓库
491 0
|
6月前
|
XML 缓存 Java
Gradle 构建自动化工具入门
Gradle 构建自动化工具入门
|
Java Maven Android开发
android之gradle配置仓库与引入依赖
android之gradle配置仓库与引入依赖
603 0
|
XML Java Apache
Gradle极简入门
Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,而不是传统的XML。Gradle构建脚本是用Groovy编写的,也可以使用Kotlin编写,两者都是基于JVM的语言。
319 0
|
Java 编译器 API
Gradle筑基篇(五)-Gradle自定义插件实战
前面几篇文章笔者对Gradle的一些基础认知,groovy基础语法,以及Gradle 项目中常用的一些api进行了讲解。今天笔者再来讲解一些关于`Gradle插件`的使用
|
XML 存储 缓存
|
弹性计算 Java jenkins
Gradle从0入门到实战系列【十】集成Dockerfile构建Docker镜像
在工作中,我们会将SpringBoot程序打包成Docker镜像,这就需要在Gradle中配置Dockerfile构建程序,并且能将打包后的镜像部署并启动为一个容器,Gradle的插件能够帮我们完成这件事
1201 0
Gradle从0入门到实战系列【十】集成Dockerfile构建Docker镜像