- 本地仓库:指存在于我们本机的仓库,在我们加入依赖时候,首先会跑到我们的本地仓库去找,如果找不到则会跑到远程仓库中去找。
远程仓库:指其他服务器上的仓库,包括全球中央仓库,公司内部的私服,又或者其他公司或组织提供的公共库。
- 中央仓库: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
进行指定,如下:
细心的同学也会发现,在之前的课程中,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中央仓库作为下载源,速度更快更稳定。
私服
私服的优点:解决中央仓库网络、重复下载、本公司非公开组件多项目依赖等问题。
在团队协作开发中,为了提高开发效率,每个公司会有自己的私有仓库,私服是一种特殊的远程仓库,部署在局域网内,开发人员需要构建提交自己的项目组件至服务器,方便其他同事可以下载下来进行协同开发,如下就是围绕私服进行的团队开发协作流程。
私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。有了私服之后,当 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
如果出现端口占用无法启动的情况,可以修改sonatype-work\nexus3\etc\nexus.properties
文件
Docker安装
环境:CentOS 7、 JDK8 、Sonatype Nexus、Docker,服务器IP:192.168.2.195
拉取镜像
$ docker pull sonatype/nexus3
运行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配置界面:
私服仓库
仓库类型
- 宿主类型:此类型所描述的仓库,主要用于存放内部发布的的项目构件,和外部没有连接关系,是由公司内部用户发布上来的项目(其典型代表为:
release
仓库、snapshots
仓库) - 代理类型:此类型所描述的仓库,主要是提供下载缓存构件和插件、比如你请求一个jar,它实际从远程中央仓库中寻找数据的仓库,如果只是从远程仓库下载构件和插件、那么代理仓库完全足够(其典型代表为:central中央仓库、阿里云仓库、apache仓库)。
- 仓库组类型:用于聚合多个仓库,为外部提供统一的地址,此类型描述的仓库,把其他的仓库使用同一个地址暴露出去,组仓库用来方便我们开发人员进行设置的仓库,不具有实际的功能,只是一个概念,简单来说就是访问这个group设置的一个地址,其他仓库的jar都能获取到
<!--我们配置阿里云镜像仓库时就可以使用它的public-->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>https://maven.aliyun.com/repository/public/</url>
</mirror>
Format
maven2
:maven
类型仓库,区别于老版本中的maven1
nuget
:.net
使用,NuGet
是一个Visual Studio
的扩展。在使用Visual Studio
开发基于.NET Framework
的应用时,NuGet
能够令你在项目中添加、移除和更新引用的工作变得更加快捷方便。
Name
- maven-central:用来代理Maven中央仓库,其策略为Release,只会下载和缓存中央仓库中的发布版本的构件
- maven-public:该仓库组将上述所有存储策略为Release的仓库聚合并通过统一的地址提供服务。
- maven-releases:策略为Release的宿主仓库,用来部署公司或组织内部的发布版本构件。
- maven-snapshots:策略为Snapshot的宿主仓库,用来部署公司或组织内部的快照版本构件。
使用私服
下载构建
- 将中央仓库的代理地址改代理为阿里云镜像仓库
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/' } }
添加依赖,并检查私服和本地仓库是否有该jar包
implementation 'org.apache.commons:commons-compress:1.20'
如果出现jar包无法拉下来,如何解决,这里我以
org.springframework.boot:spring-boot-starter:2.6.4
为例- 先确认
maven-central
中的代理地址是否是https://maven.aliyun.com/repository/public/
,其他地址有可能因为网络原因导致从中央仓库拉取jar包失败 再确认你的
maven-central
仓库中是否存在该jar包- 如果私服存在,则删除你本地
caches
目录下的modules-2
目录,重启IDEA即可
- 如果私服存在,则删除你本地
- 如果
maven-central
不存在,则需要去中央仓库查看是否存在该jar
包 - 如果
maven-central
中的文件不完整,比如只有pom
没有其他文件,且以上操作均无效,则可能需要重建私服索引
- 先确认
publishing插件发布
plugins{
id 'maven-publish'
}
publishing {
publications { ... }
repositories.maven { ... }
}
// 通过上述配置我们可以知道publishing有2个属性publications和repositories,而publishing作为maven-publish提供的插件类,实际上是一个PublishingExtension
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); } }
PublicationContainer
publications
就是PublicationContainer
的实例,PublicationContainer
负责创建和管理Publication
实例。具体的Publication
实例,需要看你使用的事什么插件,当前有ivy-publish
和maven-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 } } }
RepositoryHandler
repositories
闭包可以设置具体的RepositoryHandler
实例,提供了众多方法,用于指定仓库或本地目录FlatDirectoryArtifactRepository
:指定目录,如:libs里面的jar包IvyArtifactRepository
:ivy仓库MavenArtifactRepository
:Maven仓库repositories { maven { ... } }
编写完整的
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' } } } }
执行
publish
任务上述闭包配置作用在于创建两个实现了
MavenPublication
接口的task
。publishOrderJarPublicationToMavenLocal
发布到本地仓库publishOrderJarPublicationToMavenRepository
发布到远程仓库。
也可以直接双击
publish
任务执行- 查看
nexus
服务是否已经存在it235-order
手工发布
总结
在企业中一般会使用自己搭建的nexus私服,其次是直接使用阿里云镜像仓库,通过这篇文章的学习应该让你对repository的了解更加深入,接下来我们继续进入下一篇的学习。