1 简介
私服不是Maven的核心概念,它仅仅是一种衍生出来的的特殊的Maven仓库。可以这么说私服是通向Maven高手的必经之路,如果一个Java开发人员从来没有使用私服管理过自己的依赖下载,这个开发者不是一个Maven高手。原生的通过拷贝本地仓库repository的方式太过原始和粗暴,而且一旦问题出现,几乎无法在内网环境下解决依赖和传递性依赖。这给使用Maven管理依赖的开发人员会带来很大的困扰。
上述图片阐述了私服的作用,私服就相当于书房,书桌上没有要读的书时,会先从书架上找(书架相当于本地仓库),如果没有则在私服中找,私服若不存在,则会通过远程代理下载中央仓库的依赖到本地仓库中,同时会缓存依赖到私服中,供下次使用。
因为如果某个依赖你下载过一次,那么很有可能,你会下载第二次。
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服不存在该构件,则从外部仓库下载,缓存在私服之上,再为Maven下载请求提供服务。私服还有如下的好处:
2 Nexus安装和使用
2.1 前提
Nexus Repository OSS的运行需要提前安装JAVA和Maven,并且确保系统中配置JAVA_HOME和MAVEN_HOME环境变量。
Microsoft Windows [版本 6.3.9600]
(c) 2013 Microsoft Corporation。保留所有权利。
C:\Users\lenovo>echo %JAVA_HOME%
C:\Program Files\Java\jdk1.8.0_131
C:\Users\lenovo>echo %MAVEN_HOME%
C:\Program Files\apache-maven-3.5.4
C:\Users\lenovo>
至于安装JDK和环境Mave环境变量的配置问题不大,不再赘述。
2.2 获取安装包
Nexus Repository OSS下载地址,需要注意的是,当前想要下载,需要填写Email和选择用户类型如下图所示:
根据PC类型选择相应版本的安装包下载即可。
2.3 运行
解压下载好的nexus-3.16.2-01-win64.zip到指定目录,比如说D:
sonatype的工作目录结构如下:
执行命令
nexus.exe /run
若出现如下运行界面表示服务成功启动。
2.4 验证
可以登录sonatype的运行界面验证服务成功启动:
程序默认端口为8080,可以通过修改配置文件的方式修改默认端口,防止端口冲突出现:
\nexus-3.16.2-01\etc\nexus-default.properties
以如下方式修改默认端口:
## DO NOT EDIT - CUSTOMIZATIONS BELONG IN $data-dir/etc/nexus.properties
##
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/
# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature
页面访问如下:
2.5 POM配置下载缓存
2.5.1 配置阿里云镜像
配置阿里云镜像的过程参考docker安装nexus私服 4.1.3章节。
Remote Storage配置如下:
http://maven.aliyun.com/nexus/content/groups/public/
2.5.2 下载
比如要缓存依赖
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-maven-plugin -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.19.v20190610</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.cargo/cargo-maven2-plugin -->
<dependency>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.7.5</version>
</dependency>
而该插件并不存在于私服中,如何把缓存从中央仓库下载到私服中呢?
在系统中找到一个POM,在其中指定如下内容:
注意:当然上述如果作为依赖应该放置在,如果作为插件,可以放置在目录下。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>profile</artifactId>
<version>1.3-SNAPSHOT</version>
<name>profile</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>nexus</id>
<name>Nexus3</name>
<url>http://localhost:8081/repository/maven-central/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>nexus-release</id>
<name>Local Nexus Repository</name>
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshot</id>
<name>Local Nexus Repository</name>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.19.v20190610</version>
</plugin>
<plugin>
<!-- https://mvnrepository.com/artifact/org.codehaus.cargo/cargo-maven2-plugin -->
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.7.5</version>
</plugin>
</plugins>
</build>
</project>
在当前POM所在目录,用命令行打开,执行如下命令即可下载依赖、相关源码和文档
mvn dependency:sources -DdownloadSources=true -DdownloadJavadocs=true
出现上图表示正在下载依赖到私服中。这样就可以直接供其他人使用额了。
当然更加常见的情形是下载依赖,这样只要把groupId:artifactId:version这些信息填写在中即可,执行相同的命令就行了。
2.6 查看依赖
然后就这样不断的叠加,累计,形成自己常用的依赖。
2.7 内网同步
当上述下载过需要的依赖之后,一种很常见的情境是内网无法连接互联网,但也需要私服的支持,因此,使用这种方式可以完美解决这个问题。
首先把解压过后的文件夹nexus-3.16.2-01-win64压缩成压缩包nexus-3.16.2-01-win64.zip,然后拷贝至内网,解压,cd 到bin目录命令行运行nexus.exe /run即可运行一个私服,非常轻便。
另外,如果修改了类似端口等配置,不希望每次都重新,那么则可以直接压缩…\nexus-3.16.2-01-win64\sonatype-work目录,替换内网中旧有的sonatype-work目录,然后直接运行即可。因为…\nexus-3.16.2-01-win64\nexus-3.16.2-01目录下每个版本的内容是一致的,对于配置的修改位于…\nexus-3.16.2-01-win64\nexus-3.16.2-01\etc目录下,仅仅复制sonatype-work不影响配置信息。因此更加方便。
3 页面概览
由于没有修改默认端口,因此笔者私服的访问地址为:
http://localhost:8081/
首先以**admin(密码admin123)**的默认管理员登录系统。界面如下:
3.1 索引和构件搜索
Nexus能够维护宿主仓库并代理缓存远程仓库(Maven中央库),Nexus为我们提供了搜索服务。下图中包含了在nexus私服上以关键字spring-boot搜索私服中的依赖,可以看到私服帮助我们检索出了需要的依赖。
点击某个依赖查看详细视图:
继续点击要引入的依赖.jar,查看该依赖的Usage,即groupId:artifactId:version。单击上述中某一行,会弹出一个更具体的构件信息面板。在Summary可以看到构件在仓库中的相对位置,并且也可以看到构件具体的大小,更新时间,SHA1和MD5校验和以及下载链接。除了关键字搜索,Nexus还提供了GAV搜索、校验和搜索、类名搜索等。
3.2 权限管理
Nexus提供了全面的权限控制特性,能让用户自由根据需要配置Nexus用户、角色、权限等。
Nexus是基于权限Privildge做访问控制的。服务器的每一个资源都有相应的权限来控制,因此用户执行特定的操作就必须具有相应的权限。管理员必须以角色(Role)的方式将权限赋予Nexus用户,例如要访问Nexus界面就必须拥有Status-(read)这个权限。
用户可以被赋予一个或者多个角色,角色可以包含一个或多个权限,角色还可以包含一个或者多个其他角色。
对于某些应用场景,例如只希望管理员才能配置Nexus,只有某些团队成员才能部署构件,或者更细的一些要求,例如每个项目都有自己的宿主仓库,且只能部署项目到该仓库中等应用场景需要权限管理的支持。此处暂时用处不多,不做进一步的扩展。
3.3 调度任务
Nexus 提供了一系列可配置的调度任务来方便用户管理系统。用户可以设定这些人物运行的方式,例如每天,每周,手动等。调度任务会在适当的时候在后台运行。用户也可以在界面观察它们的状态。
服务器管理和配置→系统配置→Tasks可以看到任务界面:
至于具体的任务含义,不进一步开展,可查看相关网页了解。
4 仓库和仓库组
4.1 内置仓库
在私服运行之后,点击Repository->Repositories可以看到如下的内容:
在shiji 工作中maven-central,maven-public,maven-releases,maven-snapshots足够我们使用了,因此在本文不会谈及nuget仓库的使用。
从上文可以看到仓库一共有三种类型:group,proxy,hosted。可以借助下图理解三种仓库的概念:
4.2 宿主仓库
宿主仓库的,用来组织内部的发布版本构件和快照版本构件,例如上图中maven-release和maven-snapshots。
4.3 代理仓库
maven-central:该仓库代理Maven中央仓库,其策略为Release,因此只会下载和缓存中央仓库中的发布版构件。
对代理仓库来说,最重要的是远程仓库的地址,即Remote Storage Location,用户必须输入有效的值
4.4 仓库组
仓库组没有实际内容,它会转向其包含的宿主仓库或者代理仓库获得实际构件的内容。
需要注意的是:仓库组没有Release和Snapshot的区别,这不同于宿主仓库和代理仓库。在配置页面用户可以非常直观的选择Nexus中的仓库,将其聚合成一个虚拟的仓库组。注意,仓库组中所包含的仓库顺序决定了仓库组遍历其所含昂哭的次序,因此最好将常用的仓库放在前面。
4.5 仓库分类总结
5 Nexus配置
5.1 从配置Maven从Nexus下载构件
5.1.1 POM配置
当需要为项目添加Nexus私服上的public仓库时,可以在POM中如下配置:
配置仓库时, ,属性的含义如下图所示:
5.1.2 Settings.xml配置
当然这样的配置仅对当前Maven项目有效,在实际应用中,我们往往想要通过一次配置就能让本机所有的Maven项目都使用自己的Maven私服。这个时候就需要在Settings.xml文件中配置,但settings.xml不支持直接配置repositories和pluginRepositories,但Maven提供了Profile机制,能让用户将仓库配置放置在settings.xml中的Profile中。
5.1.2.1 Profile
<settings>
...
<profiles>
<profile>
<id>development</id>
<!-- 仓库。仓库是Maven用来填充构建系统本地仓库所使用的一组远程项目。而Maven是从本地仓库中使用其插件和依赖。
不同的远程仓库可能含有不同的项目,而在某个激活的profile下,可能定义了一些仓库来搜索需要的发布版或快照版构件。有了Nexus,这些应该交由Nexus完成 -->
<repositories>
<repository>
<id>central</id>
<!-- 虚拟的URL形式,指向镜像的URL,因为所有的镜像都是用的是nexus,这里的central实际上指向的是http://repos.d.xxx.com/nexus/content/groups/public -->
<url>http://central</url>
<!-- 表示可以从这个仓库下载releases版本的构件-->
<releases>
<enabled>true</enabled>
</releases>
<!-- 表示可以从这个仓库下载snapshot版本的构件 -->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<!-- 插件仓库。仓库是两种主要构件的家。第一种构件被用作其它构件的依赖。这是中央仓库中存储大部分构件类型。
另外一种构件类型是插件。Maven插件是一种特殊类型的构件。由于这个原因,插件仓库独立于其它仓库。
pluginRepositories元素的结构和repositories元素的结构类似。每个pluginRepository元素指定一个Maven可以用来寻找新插件的远程地址。 -->
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<!--this profile will allow snapshots to be searched when activated-->
<id>public-snapshots</id>
<repositories>
<repository>
<id>public-snapshots</id>
<!-- 虚拟的URL形式,指向镜像的URL,这里指向的是http://repos.d.xxx.com/nexus/content/groups/public-snapshots -->
<url>http://public-snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public-snapshots</id>
<url>http://public-snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<!-- 激活的Profile。activation元素并不是激活profile的唯一方式。settings.xml文件中的activeProfile元素可以包含profile的id,
任何在activeProfile中定义的profile id,不论环境设置如何,其对应的profile都会被激活。如果没有匹配的profile,则什么都不会发生。
profile也可以通过在命令行,使用-P标记和逗号分隔的列表来显式的激活(如,-P test)
要了解在某个特定的构建中哪些profile会激活,可以使用maven-help-plugin(mvn help:active-profiles)。 -->
<activeProfiles>
<!-- 没有显示激活public-snapshots -->
<activeProfile>development</activeProfile>
</activeProfiles>
...
</settings>
5.1.2.2 mirror元素
也可以使用mirror元素配置Nexus私服。
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>C:\Users\lenovo\.m2\repository</localRepository>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf> * </mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<name>Nexus</name>
<url>http://localhost:8081/repository/maven-public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Nexus</name>
<url>http://localhost:8081/repository/maven-public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
这也是笔者实际使用的settings.xml文件内容。
细心的读者可能注意到,Maven除了从Nexus下载构件之外,还会时不时的反问中央仓库central,我们希望所有Maven下载请求都仅仅通过Nexus,以全面发挥私服的作用。这就要借助Maven镜像的配置。可以创建一个匹配任何仓库的镜像,镜像的地址为私服,这样Maven对任何仓库的构件下载都会转到私服中。
注意:仓库及插件仓库配置,它们的id都为central,也就是说,覆盖了超级POM中央仓库的配置,它们的url已无关简要,因为所有请求都会通过镜像访问私服地址。配置仓库及插件仓库的主要目的是开启对快照版本下载的支持。
5.2 部署构件至Nexus
5.2.1 自动部署
5.2.1.1 POM配置
日常开发生成的快照版本构件可以直接部署到Nexus中策略为Snapshot的宿主快照中,项目正式发布的构件则应该部署到Nexus中策略为Release的宿主仓库中。例如下图:
由于某个项目产生的构件要部署到某个特定的宿主仓库,该信息特定于项目,因此应该把待部署的仓库信息填写于项目的POM中,如下图所示:
5.2.1.2 认证信息配置在settings.xml中
由于Nexus的仓库对于匿名用户是只读的,为了能够部署构件,还需要在settings.xml中配置认证信息,如下图所示:
5.2.2 手动部署
某些Java jar文(如Oracle驱动)的JDBC驱动,由于许可证的因素,它们无法公开地放在公共仓库中,此外,还有大量的小型开源项目,它们没有把自己的构件分发到中央仓库中,也没有维护自己的仓库,因此也无法从公共仓库获得,这时候需要用户将这类构件下载到本地,通过Nexus的界面上传到私服中。
使用maven-releases即可,这样其他用户可以使用maven-public的group仓库直接从私服获取依赖使用。
上传之后,可以通过Browse按钮,浏览maven-releases,详情如下:
6 总结
该篇文章是笔者在阅读许晓斌《Maven 实战》使用Nexus创建私服之后重新整理过的理解和总结,尤其Nexus的安装和使用帮助了许多东西,自己再也不用通过拷贝许多repository来解决jar包依赖问题了。另外文章也总结了Nexus中仓库的集中类型,并且对配置从Nexus下载构件的过程进行了详细的描述,主要涉及POM和Settings.xml的配置。另外对自动部署和手动部署构件到Nexus仓库也进行了较为详细的描述。希望通过对本文的阅读能够对使用Maven的开发者能够有一定的帮助。在日常工作中通过对Maven的深入理解不断熟悉maven的使用,不断提升自己的工作效率和工作质量,这是文章总结的初衷了,通过总结和整理加深自己对maven的理解,把整理的过程输出成文章希望能帮助更多的人。
7参考
8下载
2019年7月14日11:35:10于马塍路36号