技术前提:熟练的掌握Maven基础知识
Maven 私服是一种特殊的Maven远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的远程仓库(中央仓库、其他远程公共仓库)。
当然也并不是说私服只能建立在局域网,也有很多公司会直接把私服部署到公网,具体还是得看公司业务的性质是否是保密的等等,因为局域网的话只能在公司用,部署到公网的话员工在家里也可以办公使用。
建立了 Maven 私服后,当局域网内的用户需要某个构件时,会按照如下顺序进行请求和下载。
此外,一些无法从外部仓库下载到的构件,也能从本地上传到私服供其他人使用。
下图中展示了 Maven 私服的用途。
Maven 私服具有以下 5 点优势:
节省外网带宽
:大量对于外部远程仓库的重复请求,会消耗很大量的带宽,利用 Maven私服代理外部仓库后,能够消除对外部仓库的大量重复请求,降低外网带宽压力。下载速度更快
:Maven 私服位于局域网内,从私服下载构建更快更稳定。便于部署第三方构件
:有些构件是无法从任何一个远程仓库中获得的(例如,某公司或组织内部的私有构件、Oracle 的 JDBC 驱动等),建立私服之后,就可以将这些构件部署到私服中,供内部 Maven 项目使用。提高项目的稳定性,增强对项目的控制
:如果不建立私服,那么 Maven 项目的构件就高度依赖外部的远程仓库,若外部网络不稳定,则项目的构建过程也会变得不稳定。建立私服后,即使外部网络状况不佳甚至中断,只要私服中已经缓存了所需的构件,Maven 也能够正常运行。降低中央仓库得负荷压力
:由于私服会缓存中央仓库得构件,避免了很多对中央仓库的重复下载,降低了中央仓库的负荷。能够帮助我们建立 Maven 私服的软件被称为 Maven 仓库管理器(Repository Manager),主要有以下 3 种:
其中,Sonatype Nexus 是当前最流行、使用最广泛的 Maven 仓库管理器。本篇文章也是重点讲解Sonatype Nexus。
关于nexus安装:https://blog.csdn.net/weixin_43888891/article/details/130675829
本篇直接基于nexus3最新版进行讲解!
Nexus 的全称是 Nexus Repository Manager(Nexus 仓库管理器),是 Sonatype 公司的一个产品。Nexus 是一个强大的仓库管理器,极大地简化了内部仓库的维护和外部仓库的访问。Nexus 分为开源版和专业版,其中开源版足以满足大部分 Maven 用户的需求。
Nexus 开源版具有以下优点:
这里我直接用的nexus最新版3.54.1版本。
点击左边导航栏中的 Repositories(仓库),可以看到 Nexus 自带的几个内置仓库,如下图所示。
在仓库列表中,每个仓库都具有一系列属性:
为了更加直观的理解仓库组、代理仓库和宿主仓库的概念,我们通过下图展示它们的用途和区别。
由上图可知:
我们使用nexus私服,配置文件中配置的也就是仓库组地址,因为仓库组可以把代理仓库、宿主仓库聚合,这样就完美实现:从私服下载依赖,私服仓库找不到还能去代理仓库那找。找到了之后缓存到私服这样下次就能从私服直接获取了。
刚安装好的nexus一共给我们创建了7个仓库(不同的nexus版本可能有一点差距),我们只需要关注Format为maven2的仓库即可,也就是一共有4个:
下面进行一个一个讲解:
(1)maven-central
我们也可以再新建一个代理仓库,然后代理到阿里云镜像地址。通过阿里云镜像下载依赖要比maven中央仓库快的多。
选择maven2 (proxy)
其他配置默认即可。然后代理地址写:
https://maven.aliyun.com/repository/public
(2)maven-public
maven-public仓库组就是将这几个仓库汇集到一块,然后项目使用nexus,不需要配置其他仓库的地址,只需要配置仓库组的地址即可。
(3)maven-releases
release仓库需要把这块改一下,设置为Allow redeploy代表允许我们对仓库中的依赖维护升级新版本,如果设置为disable redeploy意味着我们无法将升级版本上传上来。
nexus预定了两个用户
在低的版本当中可能会有一个deployment角色,不知道为什么新的版本当中这个角色给取消了。
一般我们不建议maven当中直接去配置admin账户,因为admin账户有新增和删除仓库的权限,我们可以选择新增一个账户,只给这个账号赋予上传依赖和下载依赖的权限即可,由于nexus是用户角色制,所以新增账户前,首先我们需要新建一个角色。然后让角色只具备上传依赖和下载依赖的权限。然后再给用户赋予该角色权限。
(1)新增角色
Role ID和Role Name自定义即可。
具体的需要新增的权限如下:
别忘了右下角保存!
(2)新增用户,并指定该角色
这时候可以使用新账号登录测试一下,登录后会发现他没有设置的权限,这就是我们要的效果!
接下来我们可能会频繁接触SNAPSHOT版本,在这里我们先熟悉一下这个版本号。
在我们是实际开发的项目当中很少会定义beat 、alpha 这些里程碑版本,因为这些一般都是开源框架才会定义的,他代表了一个特殊的寓意,例如beat就是测试版本,而我们经常在开发中会定义SNAPSHOT版本。SNAPSHOT不同于里程碑版本,里程碑版本他也就是一个普通的版本名称,说白了只是用这些英文来代表这个版本的含义,而SNAPSHOT对于私服来说是有特殊功能的。
使用场景: 大型的应用软件通常由多个功能模块组成,这些模块有时候分别于不同的团队负责开发。假设有两个团队,他们分别负责项目中的 member-service(会员服务) 和 user-service(用户服务) 两个模块,且 member-service 需要依赖 user-service 项目。
基于以上假设,若 user-service 团队正在进行快节奏的 bug 修复及功能增强,会在短时间内高频率地更新代码以及发布版本。就会出现以下情况:
这样,势必会影响开发效率,甚至会影响项目的验收及投产。要解决这个问题,其实很简单,那就是使用 SNAPSHOT(快照)版本。
版本介绍: SNAPSHOT(快照)是一种特殊的版本,它表示当前开发进度的副本。与常规版本不同,快照版本的构件在发布时,Maven 会自动为它打上一个时间戳,有了这个时间戳后,当依赖该构件的项目进行构建时,Maven 就能从仓库中找到最新的 SNAPSHOT 版本文件。
默认情况下对于快照本本的构件,Maven 会每天从仓库中获取一次更新,用户也可以在任何 Maven 命令中使用 -U
参数强制 Maven 检查更新。命令如下:mvn clean package -U
SNAPSHOT 版本 VS RELEASE 版本
Maven 仓库分为两种,Snapshot 快照仓库和 Release 发行仓库。Snapshot 快照仓库用于保存开发过程中的不稳定 SNAPSHOT 版本,Release 发行仓库则用来保存稳定的 RELEASE 版本。Maven 会根据模块的版本号(pom.xml 文件中的 version 元素)中是否带有 -SNAPSHOT 来判断是 SNAPSHOT 版本还是正式 RELEASE 版本。带有 -SNAPSHOT 是SNAPSHOT(快照)版本,不带 -SNAPSHOT 的就是正式 RELEASE(发布)版本。
首先找到本地maven的setting.xml(在maven安装目录的conf目录下),打开后找到servers标签。加入以下内容
<servers>
<server>
<id>self-mavenid>
<username>deplymentusername>
<password>deplyment123password>
server>
servers>
maven配置好了,接下来去maven项目中设置:
在你想上传的模块的pom文件中,写入:
<distributionManagement>
<repository>
<id>self-mavenid>
<url>http://ip:port/repository/maven-releases/url>
repository>
<snapshotRepository>
<id>self-mavenid>
<url>http://ip:port/repository/maven-snapshots/url>
snapshotRepository>
distributionManagement>
会根据该模块的版本进行自动选择,如果你的版本号带有SNAPSHOT如:
,那么会上传到SNAPSHOT仓库,release也是这个道理,如果版本号不存在这两个单词,如1.0.0,那么会选择release仓库上传。
0.0.1-SNAPSHOT
(1)接下来我们进行测试,首先第一步准备一个不是web工程的项目,如下:
(2)然后进行以下步骤:
当然也可以直接运行maven命令:mvn clean deploy -DskipTests
(3)deploy执行完不报错的话就上传成功了。
(4)由于我的项目设置的是1.0-SNAPSHOT,也就是SNAPSHOT版本,所以他会自动上传到maven-snapshots仓库当中,如下:
接下来,配置本地maven。还是打开setting.xml,然后添加一个如下配置:
<profiles>
<profile>
<id>nexusid>
<repositories>
<repository>
<id>self-mavenid>
<name>nexusname>
<url>http://localhost:8081/repository/maven-public/url>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>trueenabled>
snapshots>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
<id>self-mavenid>
<name>nexusname>
<url>http://localhost:8081/repository/maven-public/url>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>trueenabled>
snapshots>
pluginRepository>
pluginRepositories>
<properties>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
profiles>
以上配置中使用了一个 id 为 nexus 的 profile,这个 profile 中包含了与仓库相关的配置,同时配置中activeByDefault为true。当本机有 Maven 项目构建时,profile 中的仓库配置就会应用到项目中。配置当中的url就配置我们的仓库组地址即可:
(1)接下来进行测试下载依赖,首先让一个web工程引用该项目坐标
(2)紧接着我们需要找到本地maven仓库当中的introduce包给删除掉
根据坐标就可以在本地仓库找到进行删除,删除前要保证引用该依赖的工程不是启动状态,不然删除不了
(3)再次测试web工程看看能否获取到依赖,需要刷新该工程,让他再次去获取依赖。
(4)刷新过后查看仓库已经存在了该依赖jar,我们并没有手动去install该项目,那也就意味着他是通过私服进行下载的。
(5)假如缺少依赖,除了上面通过idea当中的刷新,也可以选择执行命令来下载依赖,mvn clean install
的时候也会自动下载仓库当中缺少的依赖,通过下载依赖的信息我们可以知道他从哪个仓库进行下载依赖的:
Nexus 私服通常会与镜像(mirror)结合使用,使 Nexus 成为所有远程仓库的私服,这样不仅可以从 Nexus 中获取所有所需构件,还能将配置集中到 Nexus 私服中,简化 Maven 本身的配置。
我们可以创建一个匹配任何仓库的镜像,镜像的地址为 Nexus 中仓库的地址,这样 Maven 对于任何构件的下载请求都会被拦截跳转到 Nexus 私服中,在maven的setting.xml当中配置,其具体配置如下。
<mirrors>
<mirror>
<id>self-mavenid>
<name>nexus namename>
<mirrorOf>*mirrorOf>
<url>http://localhost:8081/repository/maven-public/url>
mirror>
mirrors>
之前阿里的镜像可以注释了,添加的镜像标签解释:
*
代表所有的依赖都从私服找这样的话项目就完全依赖于nexus仓库了,假如一旦nexus挂了,整个项目都没办法下载包了,这时候可以将镜像替换为阿里云,这样一来除了公司内部包无法下载,最起码中央仓库的包还是可以下载的。
<mirror>
<id>alimavenid>
<name>aliyun mavenname>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
<mirrorOf>centralmirrorOf>
mirror>
我们基于上面提到的introduce工程和demo工程再顺便测一下SNAPSHOT版本。一般SNAPSHOT版本是为了解决多个人同时开发所产生的问题,而我没有多台电脑,所以模拟起来也比较费劲。
(1)我们需要手动保留一份仓库当中修改前的代码。
(2)修改一下introduce工程,然后将该工程重新deploy到仓库。
(3)删除本地仓库的introduce工程,将刚刚备份的introduce1改为introduce。这时候introduce1的工程代码当中那个输出的还是1111111。
(4)看看demo工程通过mvn clean install -DskipTests -U
(-U是强制更新)是否会更新
(5)成功更新了
有些 Jar 文件(如 Oracle 的 JDBC 驱动)由于许可证等原因,无法存放在公开仓库中。此外,还有一些小型的开源项目,它们没有将自己的构件分发到公共仓库中,也没有维护自己的仓库,因此这些构件是无法从公共仓库中获得的。若 Maven 项目中需要这类构件,我们就需要将构件下载到本地,然后手动上传到 Nexus 私服。
(1)准备一个项目,版本号不要是SNAPSHOT版本的
(2)mvn clean install,进行打包
(3)在 Nexus 界面的upoad上传,默认是只允许上传releases仓库。
生成的就是一个带有该项目坐标的pom。
如果该jar包还有其他依赖,那么需要手动上传pom.xml文件,就不能点击上面的generate生成了,通过点击add another asset 增加,操作如下
手动上传jar需要注意:
新建的代理仓库都是 online-ready to connect状态。
代理仓库还有一个如下配置: