最近在公司开发时,重新开始捡起五年左右没有用过的JAVA,从零开始学习Spring和Springboot,由于内部环境无法访问外网,很多依赖无法从外网获取,于是开始灰头土脸地开始折腾起Maven、Nexus、IDEA这三个玩意儿地连通。

Maven是什么

Maven就是是专门为Java项目打造的管理和构建工具,它的主要功能有:

  • 提供了一套标准化的项目结构;
  • 提供了一套标准化的构建流程(编译,测试,打包,发布……);
  • 提供了一套依赖管理机制。

其中,在项目中需要引用依赖时,Maven请求构件的流程图如下
Maven请求构件流程图
其中远程仓库和镜像仓库地址皆可为我们的私服地址,目前主流的私服搭建工具为Nexus,例如阿里云的Maven旧版仓库就是搭建在Nexus上的。

Nexus3仓库的搭建

Nexus是什么

Nexus 的全称是 Nexus Repository Manager(Nexus 仓库管理器),是 Sonatype 公司的一个产品。Nexus 是一个强大的仓库管理器,极大地简化了内部仓库的维护和外部仓库的访问。Nexus常被用来搭建 Maven 私服,所以也有人将 Nexus 称为“Maven仓库管理器”。除此之外,Nexus还可创建npm、pypi等的仓库。

Nexus3下载

进入Nexus官网下载页面

填好一些信息后,选择所需要的版本,因为我的开发环境是Windows,所以下面以Windows作为示例。

Nexus3的安装与配置

官网上下载下来的Nexus3是个zip压缩包,解压到合适的路径下,解压好后包含两个文件夹,分别为nexus-3.xx.xx-xx和sonatype-work,我的版本为nexus-3.47.1-01,进入该文件夹下的etc目录,用文本处理软件打开nexus-default.properties
修改application-port自定义私服仓库端口号,修改application-host自定义私服仓库IP,默认为localhost和8081,例如,可以设置端口为9999(ps:chrome等浏览器会限制6666等的部分端口,将其视为不安全的端口,如果遇到此类问题可以查查是否是因为端口受到限制而无法打开。)

保存配置文件后,返回nexus-3.47.1-01目录,进入bin目录,在命令提示符中打开该路径,输入nexus.exe /install安装服务,默认服务名是nexus,安装后的服务可以在开机后自动启动。接着输入nexus.exe /start启动服务,稍等片刻后输入http://localhost:9999/ 即可进入Nexus3仓库。

首次进入Nexus仓库会提示输入用户名和密码,与Nexus2不同,Nexus3默认的用户名为admin,但是密码不再默认为admin123,需要进入sonatype-work文件夹,该文件夹下有个admin.password文件,用文本处理软件打开复制即可,后续会提示输入新密码,是否允许匿名登录等,根据需求进行配置即可。

Nexus仓库分类

Nexus仓库分为以下 3 个类型:
代理仓库(proxy):用来代理远程公共仓库,如 Maven 中央仓库、JBoss 远程仓库。
宿主仓库(hosted):又称 Nexus 本地仓库,该仓库通常用来部署本地项目所产生的构件。
仓库组(group):用来聚合代理仓库和宿主仓库,为这些仓库提供统一的服务地址,以便 Maven 可以更加方便地获得这些仓库中的构件。
为了更加直观的理解仓库组、代理仓库和宿主仓库的概念,我们通过下图展示它们的用途和区别。
Nexus 仓库分类

由上图可知:
Maven 可以直接从宿主仓库中下载构件。
Maven 也可以从代理仓库中下载构件,代理仓库会从远程仓库下载并缓存构件。
Maven 还可以从仓库组中下载构件,仓库组会从其包含的宿主仓库和代理仓库中获取构件。

创建宿主仓库

依次点击页面上的齿轮,Repositories,Create repository,maven2(hosted)来创建一个宿主仓库。

例如,我打算创建一个用来存放中央仓库中没有的第三方jar包仓库,可以给它起名3rd-party,Version policy默认为Release,此处强烈推荐使用Mixed,否则若之后想要上传SNAPSHOT版本的jar包会很麻烦。Deployment policy默认为Disable redepoly,此处推荐使用Allow redeploy。

点击页面最下方的Create repository按钮即可完成仓库的创建。

配置代理仓库

和上一步相似,依次点击页面上的齿轮,Repositories,maven-central来进行代理仓库的配置。
Remote storage可以修改为阿里云maven组仓库的地址https://maven.aliyun.com/repository/public,来提升构件下载的速率,点击页面最下方的Save按钮即可完成代理仓库的配置修改。需要注意的是,Nexus默认存在的代理仓库的版本策略是Release的,如果需要Mixed策略,则需要重新创建一个代理仓库。

批量上传构件

和Nexus2可以直接拖动整个仓库到Nexus文件夹下不同,Nexus3仅提供了手动上传的方法,该方法单次只能上传一个构件,效率十分低下,而且在输入构件信息的过程中,很容易出错。

这里推荐使用批量上传的方法:
前提:windows执行shell脚本,务必安装git 客户端工具。(因为需要执行sh文件)

  1. 在Maven仓库根目录下创建 “mavenimport.sh” 脚本
    脚本内容为:
   #!/bin/bash
   # copy and run this script to the root of the repository directory containing files
   # this script attempts to exclude uploading itself explicitly so the script name is important
   # Get command line params
   while getopts ":r:u:p:" opt; do
    case $opt in
        r) REPO_URL="$OPTARG"
        ;;
        u) USERNAME="$OPTARG"
        ;;
        p) PASSWORD="$OPTARG"
        ;;
    esac
   done

find . -type f -not -path './mavenimport\.sh*' -not -path '*/\.*' -not -path '*/\^archetype\-catalog\.xml*' -not -path '*/\^maven\-metadata\-local*\.xml' -not -path '*/\^maven\-metadata\-deployment*\.xml' | sed "s|^\./||" | xargs -I '{}' curl -u "$USERNAME:$PASSWORD" -X PUT -v -T {} ${REPO_URL}/{} ;
  1. 在该目录下点击右键,点击Git Bash Here

  2. 打开的窗口中,执行命令

    ./mavenimport.sh -u 用户名 -p 密码 -r http://IP:端口/repository/仓库名/
    

运行结束后,即可在Nexus仓库中查看上传的构件。

配置组仓库

我在开发中所采用的组仓库配置策略为,组仓库包含了三方包仓库、代理仓库、发行版仓库、快照版仓库,后续只暴露组仓库的地址即可满足项目从这些仓库中下载构件。

Nexus仓库的配置与使用

修改settings.xml文件

settings.xml是用来设置Maven参数的配置文件,并且settings.xml是maven的全局配置文件,而pom.xml文件是所在项目的局部配置。
settings.xml中包含类似本地仓储位置、修改远程仓储服务器、认证信息等配置。
最好直接复制一个配置好的文件进行修改,自己配置容易出错。我在Maven的根目录下,复制了一个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">

    <!-- 本地仓库地址 -->
    <!-- <localRepository>C:\Users\Azha\.m2\repository</localRepository> -->


    <!-- 以下配置为上传jar包配置 -->
    <pluginGroups>

    </pluginGroups>

    <proxies>

    </proxies>

    <servers>
        <server>
            <!-- id,对应项目里面pom.xml里面distributionManagement配置的id -->
            <id>maven-releases</id>
            <!-- 登录nexus的用户名 -->
            <username>admin</username>
            <!-- 登录nexus的密码 -->
            <password>admin123</password>
        </server>
        <server>
            <!-- id,对应项目里面pom.xml里面distributionManagement配置的id -->
            <id>maven-snapshots</id>
            <!-- 登录nexus的用户名 -->
            <username>admin</username>
            <!-- 登录nexus的密码 -->
            <password>admin123</password>
        </server>
        <!-- 配置拦截器mirror登录的用户名密码。他会拦截所有的请求到mirror指定的地址下载jar包 如果只需要去私服下载jar包则只需配置此项 -->
        <server>
            <!-- id,对应mirror中id -->
            <id>nexus</id>
            <username>admin</username>
            <password>admin123</password>
        </server>
    </servers>

    <!-- 以下配置为下载jar包配置 通用 -->

    <mirrors>
        <!-- 强制让jar包下载走私服 -->
        <mirror>
            <id>nexus</id>
            <mirrorOf>*</mirrorOf>
            <url>http://localhost:9999/repository/maven-public/</url>
        </mirror>
    </mirrors>

    <profiles>
        <profile>
            <!-- 对应activeProfiles-activeProfile的内容 -->
            <id>nexus</id>
            <!-- 仓库地址 -->
            <repositories>
                <repository>
                    <!-- 私服id,覆盖maven-model模块下的父id,让maven不走中央仓库下载,走私服下载 -->
                    <id>central</id>
                    <!-- 名字 -->
                    <name>Nexus</name>
                    <!-- 私服地址,写central后,会去mirror里面找 -->
                    <url>http://localhost:9999/repository/maven-public/</url>
                    <!-- 支持releases版本 -->
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <!-- 支持snapshots版本 -->
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
            <!-- 插件地址 -->
            <pluginRepositories>
                <pluginRepository>
                    <id>central</id>
                    <name>Nexus Plugin Repository</name>
                    <url>http://localhost:9999/repository/maven-public/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </pluginRepository>
            </pluginRepositories>
            <!-- 配置全局的url地址 供上传jar包时动态获取 -->
            <properties>
                <ReleaseRepository>http://localhost:9999/repository/maven-releases/</ReleaseRepository>
                <SnapshotRepository>http://localhost:9999/repository/maven-snapshots/</SnapshotRepository>
            </properties>
        </profile>
    </profiles>

    <!-- 选择使用的profile -->
    <activeProfiles>
        <activeProfile>nexus</activeProfile>
    </activeProfiles>

</settings>

settings.xml参数较多,建议多看看资料,才能有较为深入的了解,否则很容易配置出错导致无法接入Nexus仓库。

修改pom.xml文件

若无需对代码进行打包发布,则无需进行此步骤。如果需要将代码打包上传到Nexus仓库中,则需要配置pom.xml文件,在标签范围内加入如下代码:

<distributionManagement>
    <repository>
        <id>maven-releases</id>
        <name>maven-releases</name>
        <url>http://localhost:9999/repository/maven-releases/</url>
    </repository>

    <snapshotRepository>
        <id>maven-snapshots</id>
        <name>maven-snapshots</name>
        <url>http://localhost:9999/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

需要注意的是,仓库的id需要与settings.xml中server的id对应!

IDEA配置

打开IDEA的Settings,打开Maven配置,Maven home path选择Maven根目录路径,User settings file选择上个步骤中写好的settings.xml文件,这里千万要记得勾选Override才可选择自定义的settings.xml,我将该文件放在了Maven的根目录下,便于后续修改。Local repository是本地仓库的地址,默认为C:\Users\你的用户名.m2\repository下,但会默认读取settings.xml中定义的仓库地址,勾选了Override后生效,也可以进一步选择自定义的本地仓库地址。

刷新,Reload All Maven Projects,构件就自动开始下载了!

如果需要发布自己的代码到仓库中,以此执行Maven的clean-deploy即可,可以在对应release或者snapshot仓库中看到打包好的jar包,后续在生产环境或者测试环境中即可随时拉取使用。

参考资料

Maven基础
Nexus(Maven私服搭建)教程
nexus 3.x私服配置(windows版)
Nexus3.x批量导入本地库(Windows版)
Nexus简介及小白使用IDEA打包上传到Nexus3私服详细教程