一、先看一些概念
1、Maven仓库分类
从Maven的依赖下载管理角度来看, Maven仓库分为远程仓库和本地仓库,远程仓库的使用需要添加仓库地址才能正常连接下载依赖。Maven的远程仓库分为中央仓库和私服仓库,中央仓库存放了世界各地上传的依赖包,比较出名的是Jcenter和MavenCentral,开源的第三方依赖一般都会上传到这两个中央仓库,这样我们只要添加这两个中央仓库的链接地址,就可以下载我们需要的依赖包了。
由于每次构建压从中央仓库下载依赖,对于中央仓库的服务器来说压力很大,因此下载速度会很慢,并且上传到中央仓库的包都是开源的,但是由于每个公司的特殊需要,并不能开源这些包,因此我们就可以把它保存到私服仓库中。在公司局域网搭建一个Nexus仓库,把公司内部不想开源的依赖包上传到私服仓库中。
2、私服是一种特殊的远程仓库
私服是一种特殊的远程仓库, 它设在局域网内, 通过代理广域网上的远程仓库, 供局域网内的 Maven 用户使用。私服的存在,特殊于,它改变了 Maven 下载依赖的机制。
只有本地仓库和远程中央仓库时,当 Maven 根据坐标寻找依赖包时, 首先会检索本地仓库, 如果本地存在则直接使用, 否则去远程仓库下载.
但是,当有了一个私服后:
当检索本地仓库发现不存在的时候, Maven 客户端先向私服请求, 如果私服不存在该依赖包, 则从外部的远程仓库下载, 并缓存在私服上, 再为客户提供下载服务。简单的理解是私服相当于本地仓库和远程中央仓库的中间缓存,因此,私服的存在,可以节省公网带宽,利用内网下载依赖项速度快。
下面是一张本地仓库,私服仓库和远程中央仓库的依赖下载示意图(构件可理解为三方的依赖包,是比较专业的说法):
二、Nexus私服的搭建
1、有三种比较流行的 Maven 仓库管理软件可以创建私服,Apache基金会的 Archiva,JFrog 的 Artifactory ,Sonatypec的 Nexus,本博客的内容是使用 Nexus 搭建私服
首先进入Nexus官网,下载最新版本,注意选择红框里的oss免费版本,目前免费版最新版本是2.14.9,点击nexus-2.14.9-01-buidle.zip下载下来
2、下载下来以后,在D盘创建文件夹,然后把解压好的文件放进去:
压缩包里面有两个文件夹, nexus-2.14.9-01和 sonatype-work, 以管理员身份打开命令行,进入nexus-2.14.9-01/bin,然后执行:
nexus install, 执行完后瞬间就安装上了, 然后再执行nexus start命令,服务就启动了
在浏览器输入网址:http://localhost:8081/nexus, 如果nexus服务正常启动则会显示以下页面:默认账号密码为admin/admin123
nexus还支持以下命令:start、stop、install、uninstall、restart
3、用默认用户名和密码(admin/admin123)登录后:
4、注意 Type 列,展示了 Nexus 的仓库分类:
proxy(远程代理仓库)
这种类型的仓库,可以设置一个远程仓库的链接。当用户向 proxy 类型仓库请求下载一个依赖构件时,就会先在自己的库里查找,如果找不到的话,就会从设置的远程仓库下载到自己的库里,然后返回给用户,相当于起到一个中转的作用。
例如 maven-central 用来存储从 Maven 中央仓库下载过的构件。
group (聚合仓库)
在 Maven 里没有这个概念,是 Nexus 特有的。目的是将多个仓库聚合,对用户暴露统一的地址,这样用户就不需要配置多个地址,只要统一配置 group 的地址就可以了。group 仓库的聚合成员可以在仓库设置中添加和移除。
例如 maven-public 是一个 group 类型的仓库,通过引用这个地址,可以访问组内成员仓库的所有构件。
hosted(宿主仓库)
我们自己的依赖仓库,目前 maven-releases 和 maven-snapshots 是 hosted 类型的仓库。我们可以上传到这两个仓库,也可以自己创建 hosted 仓库。
三、上传依赖包到Nexus私有仓库
通过上述步骤Nexus私库就搭建完毕了,接下来可以上传私有库
1、首先我们创建一个工程,然后紧接着创建一个Module
2、由于library里面没有gradle.properties文件, 我们需要自己创建一个或者复制外面的gradle.properties到library的根目录下,然后添加以下信息,GROUP_ID、ARTIFACTID、LIBRARY_VERSION都是自己可以任意写的,中间的两个URL是要上传到哪个仓库, 一个是正式环境仓库,一个是开发中的临时仓库,当我们的版本中有snapshot(不区分大小写)字样的话就会上传到snapshots仓库,如果没有就会上传到正式仓库,上传的时候会根据版本是否有snapshot来区分
3、在最外层的build.gradle中添加maven打包插件
3、在library的build.gradle中配置脚本:
(1)首先在apply plugin: 'com.android.library'下面加如下代码:
apply plugin: 'maven'
def isReleaseBuild() {
return LIBRARY_VERSION.toUpperCase().contains("SNAPSHOT") == false
}
def getRepositoryUsername() {
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
}
def getRepositoryPassword() {
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
}
def getRepositoryUrl() {
return isReleaseBuild() ? RELEASE_REPOSITORY_URL : SNAPSHOT_REPOSITORY_URL
}
注意:上面代码在android {}外面
(2)在android {}中加如下脚本
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
pom.groupId = GROUP_ID
pom.artifactId = ARTIFACTID
pom.version = LIBRARY_VERSION
repository(url: getRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
}
}
}
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
//解决 JavaDoc 中文注释生成失败的问题
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
options.addStringOption('charSet', 'UTF-8')
}
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
}
同步一下工程后,会生成:
双击后就会打包上传了,可以看看上传后的包:
我已经上传了3个版本了
四、引用上传的包
1、在allprojects下面添加下载私有库的路径,表示从哪里下载私有库
2、在dependencies中添加如下引用就可以了
格式是gradle.properties中的三个变量:implementation 'GROUP_ID : ARTIFACTID : LIBRARY_VERSION'
dependencies {
implementation 'online.com.testimplementationonline:implementationonline:1.3-SNAPSHOT'
}
五、release和snapshot仓库的区别和使用
1、release 仓库不能重复上传同一版本号,版本不能覆盖,只能迭代,snapshot 仓库允许版本覆盖。当我上传多次上传同一个版本到 snapshot 仓库,会自动在版本号后面添加时间戳来区分
迭代开发的不稳定版本放到snapshot仓库中,版本可覆盖,测试的时候不需要改版本号,最多清理一下maven的依赖缓存就可以下载到最新版本,正式发布的时候使用release版本
2、release和snapshot的使用场景
release库的使用注意:
release库是存放稳定版本包的仓库,线上发布的程序都应从release库中引用正确版本进行使用
(1)release库不允许删除版本
(2)release库不允许同版本覆盖
(3)release库的版本号不能以-snapshot结束
(4)非公司内部人引用第三方包仅可用release版本
snapshot库是存放中间版本包的仓库,代表该库中依赖包的程序处于不稳定状态。当代码在开发过程中有其他程序需要引用时,可以提供snapshot版用于调试和测试。由于snapshot库的包依然处于测试状态,所以随时可以上传同版本最新包来替换旧包,基于这种不稳定状态,maven允许snapshot库中的包被编译时随时更新最新版,这就可能会导致每次打包编译时同一个版本jar会包含不同的内容,所以snapshot库中的包是不能用来发布的
(1)snapshot仓库名中带有‘snapshots’标识
(2)snapshot库可以删除版本
(3)snapshot库可以版本覆盖
(4)非公司内部的人不能引用snapshot版本
当snapshot版本重复发布时前端拉取不到最新的包,这时候可以打开android studio命令行,输入如下命令来刷新一下就好了
//Windows小伙伴们用这个 gradlew build --refresh-dependencies
//Mac小伙伴们用这个 ./gradlew build --refresh-dependencies
六、设置代理仓库
新建一个Proxy Repositories,然后设置Remote Storage Location, 这样就可以使用国内比较快速的镜像,例如阿里云的镜像:http://maven.aliyun.com/nexus/content/groups/public/
七、使用代理仓库代理jcenter、jitpack
jitpack仓库URL:https://jitpack.io
jcenter仓库URL:http://jcenter.bintray.com/
首先我们还是按照第六步来,创建一个Proxy Repositories,然后设置Remote Storage Location为上面两个地址, 然后复制新创建的url,在allprojects{} 中引用, 然后注释掉jcenter,重新构建, 以后从jcenter中下载包都会经过nexus。
第六点中还有阿里云的maven仓库镜像, 可以直接在allprojects中使用, 注释掉mavenCenter()即可,这个强烈推荐
声明:本章博客是参考https://blog.csdn.net/qq_32452623/article/details/79385595所写, 但是这篇博客用的是nexus收费版,我用的是免费版的最新版本