MAVEN 远程私服
MAVEN 远程私服是基于不同公司、组织或团队的个性化构件的共享需要,而定制搭建的私有远程仓库。Nexus 就是一个可用于搭建私服的强大Maven仓库管理器,以下将基于此做相关介绍。
一、私服的工作原理
(一)私服仓库分类

Nexus 的仓库类型有三种:proxy、hosted 以及 group。
1、proxy 类型仓库称为代理仓库,用来代理远程公共仓库,例如 Maven 中央仓库、阿里远程仓库;
2、hosted 类型仓库称为宿主仓库,又称为私服本地仓库,通常用于部署本地项目所产生的构件;
3、group 类型仓库称为组仓库(仓库组),用于聚合代理仓库与宿主仓库,为这些仓库提供统一的服务地址,使 Maven 更方便的获取构件。
(二)构件访问机制

构件的访问下载是 Maven 最常用的能力,任何基于 MAVEN 构建的项目都会使用到。了解构件访问机制是一个不错的决定。
1、本地私服即本地环境安装的Maven软件的构件仓库,默认路径 ${user.home}/.m2/repository,是作为远程仓库的一个缓冲或子集应用。在进行构件访问时,优先在本地私服中查找;
2、本地私服中无法找到所需构件时,会通过本地按照的 MAVEN 远程仓库配置,顺序访问远程 Maven 仓库获取构件(如果本地顺序配置了remote1、remote2,则会优先访问remote1获取构件,如果未找到再访问remote2获取构件);
3、访问远程 Maven 仓库查找过程:
(1)访问的目标地址为远程私服的仓库组,其本身并无法提供构件,而是通过聚合配置,顺序访问聚合的代理仓库与宿主仓库进行构件查找;
(2)访问代理仓库的过程就类似于本地私服访问远程 Maven 仓库获取构件(过程 2 )。
二、本地的私服配置
本地私服的配置文件通常在 ${maven.home}/conf/settings.xml,其中可进行如下配置:
<?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">
<!-- 构建系统本地仓库的路径。其默认值:~/.m2/repository -->
<!-- <localRepository>${user.home}/.m2/repository</localRepository> -->
<!-- 是否需要和用户交互以获得输入。默认为 true -->
<!-- <interactiveMode>true</interactiveMode> -->
<!-- 是否需要使用 ~/.m2/plugin-registry.xml 文件来管理插件版本。默认为 false -->
<!-- <usePluginRegistry>false</usePluginRegistry> -->
<!-- 是否需要在离线模式下运行,默认为 false。当由于网络设置原因或者安全因素,构建服务器不能连接远程仓库的时候,该配置就十分有用 -->
<!-- <offline>false</offline> -->
<!-- 当插件的 groupId 没有显式提供时,供搜寻插件 groupId 的列表。使用某个插件,如果没有指定 groupId 的时候,maven 就会使用该列表。
默认情况下该列表包含了 org.apache.maven.plugins 和 org.codehaus.mojo -->
<!-- <pluginGroups> -->
<!-- plugin 的 groupId -->
<!-- <pluginGroup>org.codehaus.mojo</pluginGroup> -->
<!-- </pluginGroups> -->
<!-- 配置服务端的一些设置。如安全证书之类的信息应该配置在 settings.xml 文件中,避免配置在 pom.xml 中 -->
<!-- <servers> -->
<!-- <server> -->
<!-- 这是 server 的 id(注意不是用户登陆的 id),该 id 与 distributionManagement 中 repository 元素的 id 相匹配 -->
<!-- <id>server001</id> -->
<!-- 鉴权用户名 -->
<!-- <username>my_login</username> -->
<!-- 鉴权密码 -->
<!-- <password>my_password</password> -->
<!-- 鉴权时使用的私钥位置。默认是 ${user.home}/.ssh/id_dsa -->
<!-- <privateKey>${usr.home}/.ssh/id_dsa</privateKey> -->
<!-- 鉴权时使用的私钥密码 -->
<!-- <passphrase>some_passphrase</passphrase> -->
<!-- 文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用该权限。其对应了 unix 文件系统的权限,如:664、775 -->
<!-- <filePermissions>664</filePermissions> -->
<!-- 目录被创建时的权限 -->
<!-- <directoryPermissions>775</directoryPermissions> -->
<!-- </server> -->
<!-- </servers> -->
<!-- 下载镜像列表 -->
<mirrors>
<!-- 设置多个镜像只会识别第一个镜像下载 jar 包-->
<mirror>
<!-- 该镜像的唯一标识符。id 用来区分不同的 mirror 元素 -->
<id>aliyunmaven</id>
<!-- 被镜像的服务器的 id。如果我们要设置了一个 maven 中央仓库(http://repo.maven.apache.org/maven2/)的镜像,就需要将该元素设置成 central。
可以使用 * 表示任意远程库。例如:external:* 表示任何不在 localhost 和文件系统中的远程库,r1,r2 表示 r1 库或者 r2 库,*,!r1 表示除了 r1 库之外的任何远程库 -->
<mirrorOf>*</mirrorOf>
<!-- 镜像名称 -->
<name>阿里云公共仓库</name>
<!-- 镜像的 URL -->
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
<!-- 用来配置不同的代理 -->
<proxies>
<proxy>
<!-- 代理的唯一定义符,用来区分不同的代理元素 -->
<id>myproxy</id>
<!-- 是否激活。当我们声明了一组代理,而某个时候只需要激活一个代理的时候 -->
<active>false</active>
<!-- 代理的协议 -->
<protocol>http</protocol>
<!-- 代理的主机名 -->
<host>proxy.somewhere.com</host>
<!-- 代理的端口 -->
<port>8080</port>
<!-- 代理的用户名,用户名和密码表示代理服务器认证的登录名和密码 -->
<username>proxyuser</username>
<!-- 代理的密码 -->
<password>somepassword</password>
<!-- 不该被代理的主机名列表。该列表的分隔符由代理服务器指定;例子中使用了竖线分隔符,逗号分隔也很常见 -->
<nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
</proxy>
</proxies>
<!-- 根据环境参数来调整构建配置的列表。对应 pom.xml 中 profile 元素(只包含 id、activation、repositories、pluginRepositories 和 properties 元素)
如果一个 settings.xml 中的 profile 被激活,它的值会覆盖任何定义在 pom.xml 中带有相同 id 的 profile -->
<profiles>
<profile>
<!-- profile 的唯一标识 -->
<id>test</id>
<!-- 自动触发 profile 的条件逻辑。也可通过 activeProfile 元素以及使用 -P 标记激活(如:mvn clean install -P test)
在 maven 工程的 pom.xml 所在目录下执行 mvn help:active-profiles 命令可以查看生效的 profile -->
<activation>
<!-- 默认是否激活 -->
<activeByDefault>false</activeByDefault>
<!-- 当匹配的 jdk 被检测到,profile 被激活。例如:1.4 激活 JDK1.4、1.4.0_2,而 !1.4 激活所有版本不是以 1.4 开头的 JDK -->
<jdk>1.8</jdk>
<!-- 当匹配的操作系统属性被检测到,profile 被激活。os 元素可以定义一些操作系统相关的属性 -->
<os>
<!-- 激活 profile的 操作系统的名字 -->
<name>Windows XP</name>
<!--激活 profile 的操作系统所属家族。如:windows -->
<family>Windows</family>
<!--激活 profile 的操作系统体系结构 -->
<arch>x86</arch>
<!--激活p rofile 的操作系统版本 -->
<version>5.1.2600</version>
</os>
<!-- 如果 maven 检测到某一个属性(其值可以在 pom.xml 中通过 ${name} 引用),其拥有对应的 name=值,Profile 就会被激活。如果值字段是空的,
那么存在属性名称字段就会激活 profile,否则按区分大小写方式匹配属性值字段 -->
<property>
<!-- 激活 profile 的属性的名称 -->
<name>mavenVersion</name>
<!-- 激活 profile 的属性的值 -->
<value>2.0.3</value>
</property>
<!-- 通过检测该文件的存在或不存在来激活 profile-->
<file>
<!-- 如果指定的文件存在,则激活 profile -->
<exists>${basedir}/file2.properties</exists>
<!-- 如果指定的文件不存在,则激活 profile -->
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
<!-- 对应 profile 的扩展属性列表。maven 属性和 ant 中的属性一样,可以用来存放一些值。这些值可以在 pom.xml 中的任何地方使用标记 ${X} 来使用,这里 X 是指属性的名称。
属性有五种不同的形式,并且都能在 settings.xml 文件中访问:
1. env.X:在一个变量前加上 "env." 的前缀,会返回一个 shell 环境变量。例如:"env.PATH" 指代了 $path 环境变量(在 Windows 上是 %PATH%)
2. project.x:指代了 pom.xml 中对应的元素值。例如:<project><version>1.0</version></project> 通过 ${project.version} 获得 version 的值
3. settings.x:指代了 settings.xml 中对应元素的值。例如:<settings><offline>false</offline></settings> 通过 ${settings.offline} 获得 offline 的值
4. Java System Properties:所有可通过 java.lang.System.getProperties() 访问的属性都能在 pom.xml 中使用该形式访问,例如:${java.home}
5. x:在 <properties/> 元素中,或者外部文件中设置,以 ${someVar} 的形式使用
-->
<properties>
<!-- 如果该 profile 被激活,则可以在 pom.xml 中使用 ${user.install} -->
<user.install>${user.home}/our-project</user.install>
</properties>
<!-- 远程仓库列表。它是 maven 用来填充构建系统本地仓库所使用的一组远程仓库 -->
<repositories>
<!--包含需要连接到远程仓库的信息 -->
<repository>
<!-- 远程仓库唯一标识 -->
<id>codehausSnapshots</id>
<!-- 远程仓库名称 -->
<name>Codehaus Snapshots</name>
<!-- 如何处理远程仓库里 releases 的下载 -->
<releases>
<!-- 是否开启 -->
<enabled>false</enabled>
<!-- 该元素指定更新发生的频率。maven 会比较本地 pom.xml 和远程 pom.xml 的时间戳。
这里的选项是:always(一直),daily(默认,每日),interval:X(这里 X 是以分钟为单位的时间间隔),或者 never(从不)。 -->
<updatePolicy>always</updatePolicy>
<!-- 当 maven 验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者 warn(警告)-->
<checksumPolicy>warn</checksumPolicy>
</releases>
<!-- 如何处理远程仓库里快照版本的下载。有了 releases 和 snapshots 这两组配置,pom.xml 就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。
例如:可能有人会决定只为开发目的开启对快照版本下载的支持 -->
<snapshots>
<enabled/>
<updatePolicy/>
<checksumPolicy/>
</snapshots>
<!-- 远程仓库 URL -->
<url>http://snapshots.maven.codehaus.org/maven2</url>
<!-- 用于定位和排序构件的仓库布局类型。可以是 default(默认)或者 legacy(遗留)-->
<layout>default</layout>
</repository>
</repositories>
<!-- 插件的远程仓库列表。和 repositories 类似,repositories 管理 jar 包依赖的仓库,pluginRepositories 则是管理插件的仓库 -->
<pluginRepositories>
<!-- 每个 pluginRepository 元素指定一个 maven 可以用来寻找新插件的远程地址 -->
<pluginRepository>
<id/>
<name/>
<releases>
<enabled/>
<updatePolicy/>
<checksumPolicy/>
</releases>
<snapshots>
<enabled/>
<updatePolicy/>
<checksumPolicy/>
</snapshots>
<url/>
<layout/>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<!-- 手动激活 profiles 的列表 -->
<!-- <activeProfiles> -->
<!-- 要激活的 profile id。例如:env-test,则在 pom.xml 或 settings.xml 中对应 id 的 profile 会被激活。如果运行过程中找不到对应的 profile 则忽略配置 -->
<!-- <activeProfile>env-test</activeProfile> -->
<!-- </activeProfiles> -->
</settings>
与 Maven 远程私服相关的配置重点关注:<mirrors></mirrors> 与 <servers></servers> 部分。以下是配置示例:
<?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">
<!-- 配置服务端的一些设置。如安全证书之类的信息应该配置在 settings.xml 文件中,避免配置在 pom.xml 中 -->
<servers>
<server>
<!-- 这是 server 的 id(注意不是用户登陆的 id),该 id 与 distributionManagement 中 repository 元素的 id 相匹配 -->
<id>histo-release</id>
<!-- 鉴权用户名 -->
<username>my_username</username>
<!-- 鉴权密码 -->
<password>my_password</password>
</server>
<server>
<!-- 这是 server 的 id(注意不是用户登陆的 id),该 id 与 distributionManagement 中 repository 元素的 id 相匹配 -->
<id>histo-snapshot</id>
<!-- 鉴权用户名 -->
<username>my_username</username>
<!-- 鉴权密码 -->
<password>my_password</password>
</server>
</servers>
<!-- 下载镜像列表 -->
<mirrors>
<!-- 设置多个镜像只会识别第一个镜像下载 jar 包-->
<mirror>
<!-- 该镜像的唯一标识符。id 用来区分不同的 mirror 元素 -->
<id>nexus-histo</id>
<!-- 镜像名称 -->
<name>衡道公共仓库</name>
<!-- 镜像的 URL -->
<url>https://nexus-zt.histo.cn/repository/maven-public/</url>
<!-- 被镜像的服务器的 id。如果我们要设置了一个 maven 中央仓库(http://repo.maven.apache.org/maven2/)的镜像,就需要将该元素设置成 central。
可以使用 * 表示任意远程库。例如:external:* 表示任何不在 localhost 和文件系统中的远程库,r1,r2 表示 r1 库或者 r2 库,*,!r1 表示除了 r1 库之外的任何远程库 -->
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
</settings>
三、项目工程私服配置
对于产生构件需部署至远程私服的 MAVEN 项目工程,可在 pom.xml 中配置 distributionManagement 的 repository 与 snapshotRepository 元素支持构件部署。以下以 ecp-sdk 项目工程的 pom.xml 配置示例:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<distributionManagement>
<!--稳定版部署库-->
<repository>
<id>histo-release</id>
<name>Release Repository</name>
<url>https://nexus-zt.histo.cn/repository/maven-releases/</url>
</repository>
<!--不稳定版部署库-->
<snapshotRepository>
<id>histo-snapshot</id>
<name>Snapshot Repository</name>
<url>https://nexus-zt.histo.cn/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
全部评论