。
- Begin -
Maven 介绍
什么是 Maven
Maven 是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具,简单的说就是用来管理项目所需要的依赖且管理项目构建的工具。
Maven 的安装与配置
- 从 Maven 官网下载压缩包,解压到本地。
- 配置环境变量
MAVEN_HOME
为 Maven 的解压目录。 - 添加 Maven 目录下的 bin 目录到环境变量
PATH
中。 - 可以在 Maven 目录下的 conf/setting.xml 文件中,通过 来指定本地仓库路径。
- 打开终端,输入
mvn -version
验证时是否成功。
Idea 中配置本地安装的 Maven
打开 Idea 的配置面板,找到 Maven 配置页。
-
Maven home directory
:设置为本地的 Maven 路径 -
User settings file
:勾选后面的 Override 可以自定义 settings 文件,可以指向 Maven 路径下的conf/settings.xml
-
Local repository
:勾选 Override 同样可以自定义仓库路径,默认会从配置的 settings 文件中读取。
Maven 坐标与依赖
坐标
Maven 通过 groupId、artifactId、version 三个变量来唯一确定一个具体的依赖,俗称 GAV。
依赖
在 pom.xml 中我们通过 dependency 来声明坐标信息(GAV),如我们需要声明对 4.2.6.RELEASE 版本 spring-core 包的依赖。
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>4.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>4.2.6.RELEASEversion>
dependency>
依赖 scope
- compile:编译依赖范围,在编译,测试,运行时都需要,依赖范围默认值
- test:测试依赖范围,测试时需要。编译和运行不需要,如 junit
- provided:已提供依赖范围,编译和测试时需要。运行时不需要,如 servlet-api
- runtime:运行时依赖范围,测试和运行时需要。编译不需要,例如面向接口编程,JDBC 驱动实现 jar
- system:系统依赖范围。本地依赖,不在 Maven 中央仓库,结合 systemPath 标签使用
依赖排除
使用 标签下的 标签指定 GA 信息来排除,例如:排除 xxx.jar 传递依赖过来的 yyy.jar
<dependency>
<groupId>com.xxxgroupId>
<artifactId>xxxartifactId>
<version>x.versionversion>
<exclusions>
<exclusion>
<groupId>com.xxxgroupId>
<artifactId>yyyartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.xxxgroupId>
<artifactId>xxxartifactId>
<version>x.versionversion>
<exclusions>
<exclusion>
<groupId>com.xxxgroupId>
<artifactId>yyyartifactId>
exclusion>
exclusions>
dependency>
依赖关系查看
进入工程根目录,在命令行中运行
-
mvn dependency:tree
命令会列出依赖关系树及各级依赖关系 -
mvn dependency:analyze
分析依赖关系
Maven 项目的结构
Maven 项目有其他标准的目录组织结构,如上图所示:
|- project: 项目目录
|- src: 源码目录
|- src/main/java: 项目 java 源码文件存放目录
|- src/main/resources: 项目资源文件存放目录
|- src/test/java: 项目单元测试源码文件存放目录
|- src/test/resources: 项目单元测试资源文件存放目录
|- target: 项目编译/打包后存放的目标路径
|- pom.xml: 项目依赖管理配置文件
|- project: 项目目录
|- src: 源码目录
|- src/main/java: 项目 java 源码文件存放目录
|- src/main/resources: 项目资源文件存放目录
|- src/test/java: 项目单元测试源码文件存放目录
|- src/test/resources: 项目单元测试资源文件存放目录
|- target: 项目编译/打包后存放的目标路径
|- pom.xml: 项目依赖管理配置文件
Maven 的生命周期
Maven 有 3 套生命周期,每套生命周期都包含了一些阶段,这些阶段是有序的,后面的阶段依赖前面的阶段。这三套生命周期是相互独立的,可以仅仅调用 clean 生命周期的某个阶段, 或者调用 default 生命周期的某个阶段,而不会对其他生命周期产生任何影响。
- clean:清理项目
- default:构建项目
- compile:编译项目的源代码
- package:打包编译好的代码
- install:将包安装至本地仓库,提供给其他项目依赖
- deploy:将最终的包复制到远程的仓库,提供给其他开发人员和项目共享。
site:建立项目站点
生命周期的执行:
# 清理项目
mvn clean
# 打包项目
mvn package
# 打包并安装到本地仓库
mvn install
# 清理项目
mvn clean
# 打包项目
mvn package
# 打包并安装到本地仓库
mvn install
可以组合各阶段进行执行:
# 清理项目后打包并发布到远程仓库
mvn clean package deploy
# 清理项目后打包并发布到远程仓库
mvn clean package deploy
settings 文件详解
settings 文件的作用
settings 是用来设置 Maven 参数的配置文件,并且,settings.xml 是 Maven 的全局配置文件。settings.xml 中包含类似本地仓库、远程仓库和联网使用的代理信息等配置。
settings 文件的位置
全局配置:${MAVEN_HOME}/conf/settings.xml
用户配置:${user.home}/.m2/settings.xml
settings 文件配置优先级
其实相对于多用户的 PC 机而言,在 Maven 安装目录的 conf 子目录下面的 settings.xml 才是真正的全局的配置。而用户目录的 .m2 子目录下面的 settings.xml 的配置只是针对当前用户的。当这两个文件同时存在的时候,那么对于相同的配置信息用户目录下面的 settings.xml 中定义的会覆盖 Maven 安装目录下面的 settings.xml 中的定义。用户目录下的 settings.xml 文件一般是不存在的,但是 Maven 允许我们在这里定义我们自己的 settings.xml,如果需要在这里定义我们自己的 settings.xml 的时候就可以把 Maven 安装目录下面的 settings.xml 文件拷贝到用户目录的 .m2 目录下,然后改成自己想要的样子。
settings.xml 元素
顶级元素概览
<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
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
settings>
<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
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
settings>
LocalRepository
该值表示构建系统本地仓库的路径。其默认值:~/.m2/repository
。
Servers
一般,仓库的下载和部署是在 pom.xml 文件中的 repositories 和 distributionManagement 元素中定义的。然而,一般类似用户名、密码(有些仓库访问是需要安全认证的)等信息不应该在 pom.xml 文件中配置,这些信息可以配置在 settings.xml 中。
<servers>
<server>
<id>server001id>
<username>my_loginusername>
<password>my_passwordpassword>
<privateKey>${usr.home}/.ssh/id_dsaprivateKey>
<passphrase>some_passphrasepassphrase>
<filePermissions>664filePermissions>
<directoryPermissions>775directoryPermissions>
server>
servers>
<servers>
<server>
<id>server001id>
<username>my_loginusername>
<password>my_passwordpassword>
<privateKey>${usr.home}/.ssh/id_dsaprivateKey>
<passphrase>some_passphrasepassphrase>
<filePermissions>664filePermissions>
<directoryPermissions>775directoryPermissions>
server>
servers>
Mirrors
用于定义一系列的远程仓库的镜像。对于一个 Maven 项目,如果没有特别声明,默认使用 Maven 的 central 库,url 为 http://repo.maven.apache.org/maven2/。但是这些远程库往往需要连接互联网访问,由于访问互联网的限制或安全控制的需要,在企业内部往往需要建立对远程库的镜像,即远程库的 mirror。
注意:
- 定义多个远程仓库镜像时,只有当前一个 mirror 无法连接的时候,才会去找后一个,类似于备份和容灾。
- mirror 也不是按 settings.xml 中写的那样的顺序来查询的。所谓的第一个并不一定是最上面的那个。当有 id 为 B、A、C 的顺序的 mirror 在 mirrors 节点中,Maven 会根据字母排序来指定第一个,所以不管怎么排列,一定会找到 A 这个mirror来进行查找,当A无法连接,出现意外的情况下,才会去B查询。
Mirror
当 Maven 需要到的依赖 jar 包不在本地仓库时,就需要到远程仓库下载。这个时候如果 settings.xml 中配置了镜像,而且镜像配置的规则中匹配到目标仓库时,Maven 认为目标仓库被镜像了,不会再去被镜像仓库下载依赖 jar包,而是直接去镜像仓库下载。简单而言,mirror 可以拦截对远程仓库的请求,改变对目标仓库的下载地址。
<mirrors>
<mirror>
<id>mirrorIdid>
<name>PlanetMirror Australianame>
<url>http://downloads.planetmirror.com/pub/maven2url>
<mirrorOf>repositoryIdmirrorOf>
mirror>
mirrors>
<mirrors>
<mirror>
<id>mirrorIdid>
<name>PlanetMirror Australianame>
<url>http://downloads.planetmirror.com/pub/maven2url>
<mirrorOf>repositoryIdmirrorOf>
mirror>
mirrors>
加速远程依赖的下载
使用镜像可以解决远程依赖下载慢的问题。
<mirrors>
<mirror>
<id>aliyun_nexusid>
<mirrorOf>centralmirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
mirror>
mirrors>
<mirrors>
<mirror>
<id>aliyun_nexusid>
<mirrorOf>centralmirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
mirror>
mirrors>
在 settings.xml 中配置如上 mirrors,远程的依赖就会从阿里云镜像中下载。
高级镜像配置
为了满足一些复杂的需求,Maven 还支持更高级的镜像配置:
-
*
:匹配所有远程仓库。 -
external:*
:匹配所有远程仓库,使用 localhost 的除外,使用file://
协议的除外。也就是说,匹配所有不在本机上的远程仓库。 -
repo1,repo2
:匹配仓库 repo1 和 repo2,使用逗号分隔多个远程仓库。 -
*,!repo1
:匹配所有远程仓库,repo1 除外,使用感叹号将仓库从匹配中排除。
案例
个人的 Maven 配置了阿里的镜像,而项目中需要使用到一些第三方 jar 包,为了方便引入,已上传到192.168.0.201 的 nexus 私服下。但由于个人 Maven 阿里的镜像配置为 *
,所有的仓库都被镜像,不会再去 192.168.0.201 下下载第三方 jar 包。
上传的第三方 jar 包目标路径:http://192.168.0.201:8081/nexus/content/groups/public/com/alipay/sdk-java/20170615110434/sdk-java-20170615110434.pom 被镜像后路径:http://maven.aliyun.com/nexus/content/groups/public/com/alipay/sdk-java/20170615110434/sdk-java-20170615110434.pom
所以需要修改镜像的 mirrorOf 规则,避免默认从镜像中下载。
Maven的 conf/settings.xml
<mirrors>
<mirror>
<id>aliyun_nexusid>
<mirrorOf>*,!maven_nexus_201mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
mirror>
mirrors>
<mirrors>
<mirror>
<id>aliyun_nexusid>
<mirrorOf>*,!maven_nexus_201mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
mirror>
mirrors>
Maven 项目下的 pom.xml 配置一个远程仓库
<repositories>
<repository>
<id>maven_nexus_201id>
<name>maven_nexus_201name>
<layout>defaultlayout>
<url>http://192.168.0.201:8081/nexus/content/groups/public/url>
<snapshots>
<enabled>trueenabled>
snapshots>
repository>
repositories>
<repositories>
<repository>
<id>maven_nexus_201id>
<name>maven_nexus_201name>
<layout>defaultlayout>
<url>http://192.168.0.201:8081/nexus/content/groups/public/url>
<snapshots>
<enabled>trueenabled>
snapshots>
repository>
repositories>
pom 文件详解
顶级元素概览
<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/maven-v4_0_0.xsd ">
<parent />
<modelVersion />
<groupId />
<artifactId />
<version />
<packaging />
<name />
<url />
<description />
<prerequisites />
<issueManagement />
<ciManagement />
<inceptionYear />
<mailingLists />
<developers />
<contributors />
<licenses />
<scm />
<organization />
<build />
<profiles />
<modules />
<repositories />
<pluginRepositories />
<dependencies />
<reports />
<reporting />
<dependencyManagement />
<distributionManagement />
<properties />
project>
<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/maven-v4_0_0.xsd ">
<parent />
<modelVersion />
<groupId />
<artifactId />
<version />
<packaging />
<name />
<url />
<description />
<prerequisites />
<issueManagement />
<ciManagement />
<inceptionYear />
<mailingLists />
<developers />
<contributors />
<licenses />
<scm />
<organization />
<build />
<profiles />
<modules />
<repositories />
<pluginRepositories />
<dependencies />
<reports />
<reporting />
<dependencyManagement />
<distributionManagement />
<properties />
project>
parent
<parent>
<artifactId>xxxartifactId>
<groupId>xxxgroupId>
<version>xxxversion>
<relativePath>xxxrelativePath>
parent>
<parent>
<artifactId>xxxartifactId>
<groupId>xxxgroupId>
<version>xxxversion>
<relativePath>xxxrelativePath>
parent>
groudId、artifactId、version、packaging
<groupId>xxxgroupId>
<artifactId>xxxartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>jarpackaging>
<groupId>xxxgroupId>
<artifactId>xxxartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>jarpackaging>
默认构件类型为 jar,当作为父级 Maven 项目的时候,构件类型为 pom。
modules
<modules>
<module>module>
modules>
<modules>
<module>module>
modules>
通过 Maven 项目之间可以形成父子关系,可以有多个层级。
repositories
<repositories>
<repository>
<releases>
<enabled><enabled>
<updatePolicy>updatePolicy>
<checksumPolicy>checksumPolicy>
releases>
<snapshots>
<enabled><enabled>
<updatePolicy>updatePolicy>
<checksumPolicy>checksumPolicy>
snapshots>
<id>banseon-repository-proxyid>
<name>banseon-repository-proxyname>
<url>http://192.168.1.169:9999/repository/url>
<layout> default layout>
repository>
repositories>
<repositories>
<repository>
<releases>
<enabled><enabled>
<updatePolicy>updatePolicy>
<checksumPolicy>checksumPolicy>
releases>
<snapshots>
<enabled><enabled>
<updatePolicy>updatePolicy>
<checksumPolicy>checksumPolicy>
snapshots>
<id>banseon-repository-proxyid>
<name>banseon-repository-proxyname>
<url>http://192.168.1.169:9999/repository/url>
<layout> default layout>
repository>
repositories>
可以配合 settings.xml 中的远程仓库配置进行使用,见上一节中的案例。
properties
<properties>
<name>valuename>
properties>
<properties>
<name>valuename>
properties>
dependencies
<dependencies>
<dependency>
<groupId>org.apache.mavengroupId>
<artifactId>maven-artifactartifactId>
<version>3.8.1version>
<type>jartype>
<classifier>classifier>
<scope>testscope>
<systemPath>systemPath>
<exclusions>
<exclusion>
<artifactId>spring-coreartifactId>
<groupId>org.springframeworkgroupId>
exclusion>
exclusions>
<optional>trueoptional>
dependency>
dependencies>
<dependencies>
<dependency>
<groupId>org.apache.mavengroupId>
<artifactId>maven-artifactartifactId>
<version>3.8.1version>
<type>jartype>
<classifier>classifier>
<scope>testscope>
<systemPath>systemPath>
<exclusions>
<exclusion>
<artifactId>spring-coreartifactId>
<groupId>org.springframeworkgroupId>
exclusion>
exclusions>
<optional>trueoptional>
dependency>
dependencies>
dependencyManagement
- 只能出现在父 pom 里
- 用于统一版本号
- 只是依赖声明,并不直接依赖,需要时在子项目中在声明要使用依赖的 GA 信息,V 信息可以省略。
<dependencyManagement>
<dependencies>
<dependency>
dependency>
dependencies>
dependencyManagement>
<dependencyManagement>
<dependencies>
<dependency>
dependency>
dependencies>
dependencyManagement>
build
<build>
<sourceDirectory>sourceDirectory>
<testSourceDirectory>testSourceDirectory>
<outputDirectory>outputDirectory>
<testOutputDirectory>testOutputDirectory>
<resources>
<resource>
<filtering>filtering>
<directory>directory>
<includes>
<include>include>
includes>
<excludes>
<exclude>exclude>
excludes>
resource>
resources>
<pluginManagement>
<plugins>
plugins>
pluginManagement>
<plugins>
<plugin>
<groupId>groupId>
<artifactId>artifactId>
<version>version>
<executions>
<execution>
<id>id>
<phase>phase>
<goals>goals>
<configuration>configuration>
execution>
executions>
<dependencies>
<dependency>
dependency>
dependencies>
<configuration>configuration>
plugin>
plugins>
build>
<build>
<sourceDirectory>sourceDirectory>
<testSourceDirectory>testSourceDirectory>
<outputDirectory>outputDirectory>
<testOutputDirectory>testOutputDirectory>
<resources>
<resource>
<filtering>filtering>
<directory>directory>
<includes>
<include>include>
includes>
<excludes>
<exclude>exclude>
excludes>
resource>
resources>
<pluginManagement>
<plugins>
plugins>
pluginManagement>
<plugins>
<plugin>
<groupId>groupId>
<artifactId>artifactId>
<version>version>
<executions>
<execution>
<id>id>
<phase>phase>
<goals>goals>
<configuration>configuration>
execution>
executions>
<dependencies>
<dependency>
dependency>
dependencies>
<configuration>configuration>
plugin>
plugins>
build>
使用 Nexus 搭建 Maven 私服
Nexus 是一个强大的 Maven 仓库管理器,它极大的简化了本地内部仓库的维护和外部仓库的访问。
Docker 搭建 Nexus
我们采用 Docker 方式来安装:
1. 拉取 nexus3 镜像
# 拉取 nexus3 镜像
docker pull sonatype/nexus3:3.16.0
# 拉取 nexus3 镜像
docker pull sonatype/nexus3:3.16.0
2. 启动 nexus3 容器
# 通过镜像启动容器
docker run -d --name nexus -p 8081:8081 -v /Users/linfuyan/Develop/nexus-data:/nexus-data sonatype/nexus3:3.16.0
# 通过镜像启动容器
docker run -d --name nexus -p 8081:8081 -v /Users/linfuyan/Develop/nexus-data:/nexus-data sonatype/nexus3:3.16.0
-d:后台模式运行容器
--name:容器命名为 nexus
-p:映射本地 8081 端口到容器内的 8081 端口
-v:将容器内的 /nexus-data 目录挂载到本地目录
3. 浏览器中访问 localhost:8081 就可以看到 Nexus 页面了。
注意:
3.6.0 版本的 sonatype/nexus3 无法查看到 upload 页面。
3.27.0 版本的 sonatype/nexus3 在我电脑上跑不起来,而且初始密码存在 admin.password 文件中。
最终选择了 3.16.0 版本。
Nexus 基础使用
通过右上角的 sign in 按钮,输入默认账号密码 admin/admin123
可以对仓库等进行管理。
创建远程仓库
可选 Maven2 group、hosted、proxy 类型。
hosted:本地仓库,通常我们会部署自己的构件到这一类型的仓库。比如公司的第二方库。
proxy:代理仓库,它们被用来代理远程的公共仓库,如 Maven 中央仓库。
group:仓库组,用来合并多个hosted/proxy仓库,当你的项目希望在多个 repository 使用资源时就不需要多次引用了,只需要引用一个 group 即可。
新建 hosted 类型仓库
把 craft4j 添加到 maven-public 中。
创建具有上传权限的角色
创建具有上传权限的角色的用户
上传 jar 组件到 Nexus
通过网页手动上传第三方 jar 到 Nexus
上传成功以后,就可以在对应的远程仓库中查看到上传完成的组件信息。
通过 mvn deploy:deploy-file 上传到 Nexus
➜ ron-jwt git:(master) ✗ mvn deploy:deploy-file -DgroupId=io.craft4j -DartifactId=checkstyle -Dversion=1.0.1-SNAPSHOT -Dpackaging=jar -Dfile=/Users/linfuyan/Code/java-lab/airplan-java-server/codestyle/checkstyle-7.0-all.jar -DrepositoryId=craft4j -Durl=http://127.0.0.1:8081/repository/craft4j/
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-deploy-plugin:2.7:deploy-file (default-cli) @ standalone-pom ---
Downloading from remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/maven-metadata.xml
Downloaded from remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/maven-metadata.xml (770 B at 3.7 kB/s)
Uploading to remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/checkstyle-1.0.1-20200910.081245-2.jar
Uploading to remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/checkstyle-1.0.1-20200910.081245-2.pom
➜ ron-jwt git:(master) ✗ mvn deploy:deploy-file -DgroupId=io.craft4j -DartifactId=checkstyle -Dversion=1.0.1-SNAPSHOT -Dpackaging=jar -Dfile=/Users/linfuyan/Code/java-lab/airplan-java-server/codestyle/checkstyle-7.0-all.jar -DrepositoryId=craft4j -Durl=http://127.0.0.1:8081/repository/craft4j/
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-deploy-plugin:2.7:deploy-file (default-cli) @ standalone-pom ---
Downloading from remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/maven-metadata.xml
Downloaded from remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/maven-metadata.xml (770 B at 3.7 kB/s)
Uploading to remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/checkstyle-1.0.1-20200910.081245-2.jar
Uploading to remote-repository: http://127.0.0.1:8081/repository/craft4j/io/craft4j/checkstyle/1.0.1-SNAPSHOT/checkstyle-1.0.1-20200910.081245-2.pom
repositoryId 依赖 settings.xml 中的 server 配置,主要是用户名与密码。
通过 mvn deploy 方式上传到 Nexus
在上面的步骤中,已经将新建的 craft4j 仓库添加到 maven-public 仓库组中。
在 settings.xml 中修改配置:
<servers>
<server>
<id>nexus-releasesid>
<username>devusername>
<password>dev123password>
server>
<server>
<id>craft4jid>
<username>devusername>
<password>dev123password>
server>
servers>
<servers>
<server>
<id>nexus-releasesid>
<username>devusername>
<password>dev123password>
server>
<server>
<id>craft4jid>
<username>devusername>
<password>dev123password>
server>
servers>
在项目 pom.xml 中修改配置:
<distributionManagement>
<repository>
<id>maven-releasesid>
<name>Nexus Release Repositoryname>
<url>http://127.0.0.1:8081/repository/maven-releases/url>
repository>
<snapshotRepository>
<id>craft4jid>
<name>Nexus Snapshot Repositoryname>
<url>http://127.0.0.1:8081/repository/craft4j/url>
snapshotRepository>
distributionManagement>
<distributionManagement>
<repository>
<id>maven-releasesid>
<name>Nexus Release Repositoryname>
<url>http://127.0.0.1:8081/repository/maven-releases/url>
repository>
<snapshotRepository>
<id>craft4jid>
<name>Nexus Snapshot Repositoryname>
<url>http://127.0.0.1:8081/repository/craft4j/url>
snapshotRepository>
distributionManagement>
pom.xml 中的 repository id 与 settings.xml 中的 server id 相对应,需要保持一致。
在需要发布的项目中执行 mvn deploy
,看到如下日志,就说明发布成功了,同样可以在 Nexus 的仓库浏览页中查看。
➜ ron-jwt git:(master) ✗ mvn clean deploy
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------
[INFO] Building ron-jwt 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ...
[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ ron-jwt ---
Downloading from craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/maven-metadata.xml
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.jar
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.jar (15 kB at 21 kB/s)
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.pom
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.pom (1.3 kB at 2.6 kB/s)
Downloading from craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/maven-metadata.xml
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/maven-metadata.xml
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/maven-metadata.xml (757 B at 2.0 kB/s)
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/maven-metadata.xml
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/maven-metadata.xml (271 B at 1.0 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.243 s
[INFO] Finished at: 2020-09-10T15:16:42+08:00
[INFO] ------------------------------------------------------------------------
➜ ron-jwt git:(master) ✗ mvn clean deploy
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------
[INFO] Building ron-jwt 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ...
[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ ron-jwt ---
Downloading from craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/maven-metadata.xml
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.jar
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.jar (15 kB at 21 kB/s)
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.pom
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/ron-jwt-1.0-20200910.071640-1.pom (1.3 kB at 2.6 kB/s)
Downloading from craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/maven-metadata.xml
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/maven-metadata.xml
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/1.0-SNAPSHOT/maven-metadata.xml (757 B at 2.0 kB/s)
Uploading to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/maven-metadata.xml
Uploaded to craft4j: http://127.0.0.1:8081/repository/craft4j/io/ron/ron-jwt/maven-metadata.xml (271 B at 1.0 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.243 s
[INFO] Finished at: 2020-09-10T15:16:42+08:00
[INFO] ------------------------------------------------------------------------
Maven 构件的版本管理
使用 Maven 作为依赖管理工具,一般我们对于依赖的版本号,常见两种类型:一种以“-RELEASE”结尾,另一种以“-SNAPSHOT”结尾。
私服中,会存在 snapshot 快照仓库和 release 发布仓库,snapshot 快照仓库用于保存开发过程中的不稳定版本,release 正式仓库则是用来保存稳定的发行版本。
Maven 会根据模块的版本号(pom 文件中的 version)中是否带有“-SNAPSHOT”(注意这里必须是全部大写)来判断是快照版本还是正式版本。如果是快照版本,那么在 mvn deploy 时会自动发布到私服的快照版本库中;如果是正式发布版本,那么在 mvn deploy 时会自动发布到正式版本库中。
快照版本的依赖,Maven 编译打包的时候无论本地是否存在,都会去私服拉取最新的,而正式版本的依赖,如果本地仓库已经存在,Maven 不会去私服拉取最新的版本,所以我们要基于快照版本进行开发,但是上线的时候一定记得变成正式版,否则如果本地正在进行开发另一个功能,提交到私服的代码有可能会被误上线。
那我们有什么好的方法来避免这种情况呢?
1. 在 settings.xml 中修改私服配置,通过 updatePolicy 为 always 强制更新。
<profile>
<id>nexusid>
<repositories>
<repository>
<id>nexusid>
<name>Nexusname>
<url>http://127.0.0.1:8081/repository/groups/maven-public/url>
<releases>
<enabled>trueenabled>
<updatePolicy>alwaysupdatePolicy>
releases>
<snapshots>
<enabled>trueenabled>
<updatePolicy>alwaysupdatePolicy>
snapshots>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
pluginRepository>
pluginRepositories>
profile>
<profile>
<id>nexusid>
<repositories>
<repository>
<id>nexusid>
<name>Nexusname>
<url>http://127.0.0.1:8081/repository/groups/maven-public/url>
<releases>
<enabled>trueenabled>
<updatePolicy>alwaysupdatePolicy>
releases>
<snapshots>
<enabled>trueenabled>
<updatePolicy>alwaysupdatePolicy>
snapshots>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
pluginRepository>
pluginRepositories>
profile>
2. 在构建的时候加上“-U”参数,强制拉取所有依赖的最新代码
mvn clean install -U
mvn clean install -U
3. 语义化版本
首先,我们在团队协作时,要定义好开发中的依赖一定不要忘记升级版本号,然后开发的过程中还要保持版本号以“-SNAPSHOT”结尾,来把该依赖作为快照版本进行开发,这样每次别人更新完上传到私服以后,你本地打包时会自动拉取最新代码,从而方便我们的开发和维护。
- End -
参考与致谢
[1]
带你深度解析Maven:
[2]
史上最全的maven的pom.xml文件详解:
[3]
setting.xml 配置详解:
[4]
上传jar包到nexus私服:
[5]
Maven私服:Docker安装nexus3: https://www.jianshu.com/p/09a6cab3785a
[6]
Maven版本号中隐藏的惊天大秘密:
[7]
Maven全局配置文件settings.xml详解: