在众多大型互联网企业或者大型app工程中,maven可以说是一个必需品。为什么需要maven私服呢?我们在日常的开发工作中,肯定会使用到一些基础组件或者基础库,在项目初期基本都是源码依赖,这样好处就是改动之后能够立刻生效提高开发效率。
但是随着项目逐渐壮大,像一些基础库会被共享出来给其他业务方用,其实这个时候就不能轻易地改动代码,因为如果两个业务方均采用同一套源码依赖,其中一个业务方修改了代码导致另一个业务方在使用时可能会遇到冲突问题,所以这个时候如果有maven来维护这个基础库的版本信息,不同业务方只需要管理版本号即可。
1 快速搭建maven仓库
从上面的图,我们可以看到maven仓库主要分为两种,分别是本地仓库和远程仓库。对于想要将仓库发布给其他业务方使用,必然要使用到远程仓库。
所以在远程仓库下,又分为3个分支:中央仓库、私服、其他公共库。对于中央仓库想必大家都见过,是google在维护的,在每个项目的setting.gradle下配置;
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
私服就是在局域网的环境下搭建,例如公司内部的maven仓库,只能在公司局域网或者链接vpn才能下载使用。
1.1 nexus repository
搭建maven私服,这里推荐使用Nexus。在Nexus的官网中,也声明支持maven仓库搭建
Nexus桌面工具点击这里下载 这里根据你自己的电脑型号选择对应的包下载即可
1.2 启动maven服务
下载完成之后,可以看到这几个文件夹,进入到nexus这个文件夹下,可以启动maven的服务
根据下面的命令行,最终进入到bin文件下,执行./nexus start命令,就启动了maven服务
怎么验证服务是否启动呢?在浏览器输入 localhost:8081,出现下面的页面就代表maven服务启动了。
2 创建maven仓库
在创建之前,首先需要登录Nexus,用户名默认都是admin,密码的位置是在nexus-3.43.0-01-mac/sonatype-work/nexus3/admin.password文件中,当你登录成功之后,这个文件就自动消失了(这个还是很棒的),然后你自己可以重新设置密码。
创建maven仓库步骤如下:
这样,就创建了一个base_ioc,与依赖注入相关的maven仓库
3 maven仓库接入项目
其实,我们在项目中如果有使用到公司的某个maven仓库,就需要接入到项目中,通常都是在build.gradle中完成的,例如我们现在创建的base_ioc组件maven库。
maven {
url 'http://localhost:8081/repository/base_ioc/'
credentials{
username 'admin'
password 'maven仓库的密码'
}
allowInsecureProtocol true
}
我们介绍一下其中的几个字段:
(1)url:maven仓库对应的url,如下图,点击copy就可以得到这个maven库的地址
(2)credentials:这个用来配置maven仓库的用户名和密码
(3)allowInsecureProtocol:支持http协议,如果不设置这个属性,那么就会编译报错。
4 maven上传
这里大家需要注意一下就是,在gradle 7.0以上的版本中,如果想要上传maven仓库,需要引入一个插件maven-publish
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'maven-publish'
}
如果大家有上传过maven仓库的应该知道,最常用的就是引入maven插件然后使用uploadArchives配置maven仓库和pom,但是这个是在gradle 7.0以下版本有效,如果在gradle 7.0以上的版本中引入这个插件,会直接报错。
如果使用了maven-publish这个插件,那么对应的语法也发生了变化
afterEvaluate {
publishing {
publications {
Production(MavenPublication) {
from components.release
groupId 'com.lay.android'
artifactId 'base_ioc'
version '0.0.1'
artifact generateSourcesJar
pom.withXml {
def dependenciesNode = asNode().appendNode("dependencies")
configurations.implementation.allDependencies.forEach() {
Dependency dependency ->
if (dependency.version != "unspecified" && dependency.name != "unspecified") {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
configurations.api.allDependencies.forEach() {
Dependency dependency ->
if (dependency.version != "unspecified" && dependency.name != "unspecified") {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
}
}
}
在gradle 7.0中,使用了publishing来代替了uploadArchives,因为对于Android Library来说,最终上传到maven仓库上的是aar,因此需要执行一次bundleReleaseAar的任务,最终编译之后,在ioc模块的生成了一个publishing文件夹如下:
点击publish便可以将组件上传至远程maven仓库,点击pushToMavenLocal便可将组件上传至本地仓库里,当然我们都会选择上传远端。
4.1 业务方使用
当提供给业务方使用的时候,就可以直接使用下面这种依赖方式,是不是很熟悉了。
implementation 'com.lay.android:base_ioc:0.0.1'
当然这种好处就是,即便是我们本地源码修改,但是业务方的版本根本不受影响,而且如果我们新版本测试通过没有问题了,就可以升级到下一个版本,而业务方只是换一个版本号即可。