系列文章目录
Maven之POM介绍
maven命令上传jar包到nexus
前言
由于在具体项目开发过程中对于maven的理解和掌握处于基本运用的阶段,了解maven过于片面,所以本篇博客是博主学习《maven实战》书籍之后的总结,绝大多数内容源于《maven》实战这本书籍。
一、什么是maven仓库?
在maven世界中,任何一个依赖,插件或者项目构建的输出,都可以成为构件。
maven在某个位置统一存储所有Maven项目共享的构建,这个统一的位置就是仓库。
maven项目只需要声明这些依赖的坐标,在需要的时候(如:编译时)maven会自动根据坐标找到仓库中的构件,并使用他们。
为了实现重用,项目构建完毕后生成的构建也可以安装或部署到仓库中,供其他项目使用。
二、仓库的分类
在maven 中仓库分为两类:本地仓库和远程仓库。
当maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在此构件,就直接使用。
如果本地不存在此构件,或者需要查看是否有更新的构建版本,maven就会去远程仓库中寻找,发现需要的构件之后下载到本地仓库之后再使用。
如果本地和远程都没有需要的构建maven就会报错。
一些特殊的远程仓库:中央仓库是maven自带的远程仓库,它包含了绝大部分开源的构建。在默认配置中,当本地仓库没有maven需要的构件的时候,他就会从中央仓库下载。
私服:私服是另一种特殊的远程仓库,为了节省时间和宽带。应该在局域网内架设一个私有的仓库服务器,用于代理所有外部的远程仓库。内部的项目还能部署到私服上供其他项目使用。
除了中央仓库和私服,还有很多其他公开的远程仓库,常见的有http://repository.jboss.com/maven2/和我们国内的阿里云仓库。
建立私服的优势
- 节省外网带宽:减少组织自己的开支,大量的对于外部仓库的请求会消耗很大的带宽。
- 加速maven构件。不停的请求外部仓库十分耗时,使用私服之后,maven只需要检查局域网内私服的数据,构建速度能得到很大程度的提升。
- 部署第三方构件。当某个构件无法从任何一个外部仓库获得。如组织自行开发的构建或其他。建立私服之后,便可以将这些构件部署到私服上,共内部的maven项目使用。
- 提高稳定性,增强控制。maven构建高度依赖与远程仓库。因此当Internet不稳定是,maven构建也会变得不稳定,使用私服之后,及时暂时没有internet连接,由于私服中已经缓存了大量构建,maven也能正常运行。
- 降低中央仓库的负荷。
三、远程仓库的配置
在很多情况下,默认的中央仓库无法满足项目的需求,可能项目需要的构件存在于另外一个远程仓库,如JBoss Maven仓库。
这是我们可以在POM中配置该仓库
如:
在repositories元素下,可以使用repository子元素声明一个或者多个远程仓库。
该示例中声明了一个id为Jboss,名称为JBoss Repository仓库。
任何一个仓库声明的id必须是唯一的,需要注意的是Maven自带的中央仓库使用的id为central,
如果有其他仓库声明也使用了该id,则会覆盖中央仓库的配置。
上述示例的配置中的releases和snapshots他们是用来控制maven对于发布版构件和快照版构件的下载。
这里需要注意的是enabled子元素,该示例中releases的enabled的值为true,表示开启JBoss仓库的发布版本下载支持,
而snapshots的enabled值为false,表示关闭了JBoss仓库的快照版本的下载支持。
因此,在该配置下maven只会从JBoss仓库下载发布版的构件,而不会下载快照版的构件。
该示例中的layout元素值default表示仓库的布局是maven2及maven3的默认布局,而不是maven1的布局。
对于releases和snapshots来说,除了enabled,他们还有另外两个子元素updatePolicy和checksumPolicy
元素updatePolicy用来配置maven从远程仓库检查更新的频率,默认的值为daily,表示maven每天检查一次,其他值包括:never——从不检查更新;always——每次构建都检查更新;X——每隔X分钟检查一次更新(X为任意整数)。
元素checksumPolicy用来配置Maven检查验证和文件的策略。当构件被部署到maven仓库中时,会同时部署读音的校验和文件。在下载构件的时候,maven会验证校验和文件。
如果校验和验证失败,当checksumPolicy的值为默认的warn时,maven会在执行构件时输出警告信息,其他值包括:fail——maven遇到校验和错误就让构件失败;ignore——使maven完全忽略校验和错误。
四、远程仓库的认证
大部分远程仓库无须认证就可以访问,但是有时候出于安全方面的考虑,我们需要提供认证信息才能访问。例如:组织内部有一个maven仓库,该服务器为每个项目都提供了独立的maven仓库,我了防止非法的仓库访问,管理员为每个仓库提供了一组用户名和密码。
这种情况下,为了能够访问远程仓库,就需要配置认证信息。
配置认证信息与配置仓库信息不同,仓库信息可以直接配置在POM文件中,但是认证信息必须配置在settings.xml文件中。
这是因为POM往往是被提交到代码仓库中供所有成员访问,而settings.xml一般放在本机,因此settings.xml中配置认证信息更为安全。
例如:需要为一个id为my-proj的仓库配置认证信息,编辑settings.xml文件如下:
使用servers元素和server子元素配置仓库的认证信息。
注意settings.xml中的id必须与POM中需要认证的repository元素的id完全一致。
这里的id将认证信息与仓库配置联系在一起。
部署至远程仓库
私服的一大作用是部署第三方构件,包括组织内部生成的构建以及一些无法从外部仓库直接获取的构建。无论是日常
开发中生成的构建,还是正式版本发布的构建,都需要部署到仓库中,供其他团队成员使用。
distributionManagement包含repository和snapshotRepository子元素,前者表示发布版本构建的仓库,
后者表示快照版本的仓库。这两个元素下都需要配置id、name和url,id为该远程仓库的唯一标识,那么是为了便于阅读,
url表示该仓库的地址。
往远程仓库部署构建的时候,一般都需要认证,就需要上面讲的在settings.xml文件中配置远程仓库的认证。
配置之后在命令行运行mvn clean deploy,maven就会将项目构建输出的构建部署到对应的远程仓库,如果项目当前的版本是快照版本,则部署到快照版本仓库地址。
否则就部署到发布版本仓库地址。
五、快照版本&why
在maven的世界中,任何一个项目或者构件都必须有自己的版本,版本的值可能是1.0.0、1.3-alpha-4、2.0、2.1-SNAPSHOT或者2.1-20230711.221414-13.
其中1.0.0、1.3-alpha-4、2.0都是稳定的发布版本,2.1-SNAPSHOT或者2.1-20230711.221414-13是不稳定的快照版本。
**maven为什么要区分发布版本和快照版本呢?**试想一下这样的情况,张三在开发模块A的2.1版本,该版本还未正式发布,与模块A一同开发的还有模块B
它有李四开发,B的功能依赖于A。在开发的过程中,张三需要经常将自己最新的构建输出,交给李四,通他开发和测试,那么这个工作如何进行呢?
在整个开发过程中,会不定更新版本2.1.1、2.1.2、2.1.3…,那么张三和李四都需要频繁的更新POM,如果有更多的模块依赖模块A,就会涉及到更多的POM更改,其次,大量的版本其实仅仅包含了微小的差异。有时候就是对版本号的滥用。
maven的快照版本就是为了解决上述的问题。在上面的场景中,张三只需要将模块A的版本设定为2.1-SNAPSHOT,然后发布到私服中,在发布的过程中,maven会自动为构建打上时间戳。比如2.1-20230711.2213414-13就表示2023年7月11日22点14分14秒的第13次快照。有了该时间戳,maven就能随时找到仓库中该构建2.1-SNAPSHOT版本最新的文件。
这是李四对于模块A的2.1-SNAPSHOT版本的依赖,当他构建模块B的时候,maven会自动从仓库中检查模块A的2.1-SNAPSHOT的最新构建,当发现有更新时边进行下载。
默认情况下,Maven每天检查一次更新,用户也可以使用命令行-U参数强制让maven检查更新,如mvn clean install-U。
当项目经过完善的测试后需要发布的时候,就应该将快照版本更改为发布版本。例如将2.1-SNAPSHOT更改为2.1,表示该版本已经稳定,且只对应了唯一的构件。
六、从仓库解析依赖的机制
- 当依赖的范围是system的时候,maven直接从本地文件系统解析构件。
- 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如果发现相应构件则解析成功。
- 在本地仓库不存在相应构件的情况下,如果依赖的版本是显示的发布版本构件,如1.2、2.10bata-1等,则遍历所有的远程仓库,发现之后,下载并解析使用。
- 如果依赖版本是SNAPSHOT如1.2-SNAPSHOT,则基于更新策略读取所有远程的元数据groupId/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库或者从远程仓库下载。
- 如果最后解析得到的构建版本是时间戳格式的快照,如1.4.1-20231104.12.1414-121,则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该非时间戳格式的构建。
七、镜像
如果仓库库X可以提供仓库Y存储的所有内容,那么就可以认为X是Y的一个镜像。也就是任何一个可以从仓库Y获得的构件,都能够从它的镜像中获取。
例如:http://maven.net/cn/content/groups/public是中央仓库http://repol.maven.org/maven2/在中国的镜像,由于地理位置的因素,该镜像往往能够提供比中央仓库更快的服务。
因此可以配置maven使用该镜像来代替中央仓库,编辑settins.xml文件
如:
上面的示例中的值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像,用户也可以使用同样的配置其他仓库的镜像。
如果该镜像需要认证,也可以基于该id配置仓库认证。
关于镜像的更为常见的用法是结合私服。由于私服可以代理任何外部的公共仓库(包括中央仓库)因此,对于组织内部的maven用户来说,使用一个私服地址就等于使用所有需要的外部仓库,这可以将配置集中到私服,从而简化maven本身的配置。
上面的示例中,的值为星号,表示该配置是所有Maven仓库的镜像,任何对于远程的请求都会被转至http://192.168.1.100/maven2/。如果该仓库需要认证,这需要配置一个id为internal-repository的.
maven还支持更高级的镜像配置。
匹配所有远程仓库
external:</mirrorOf匹配所有远程仓库,使用localhost的除外,使用file://协议的除外。也就是匹配所有不在本机上的远程仓库。
repo1,repo2匹配仓库repo1和repo2,使用逗号分隔多个远程仓库
*,! repo1匹配所有与远程仓库,repo1除外,使用感叹号将仓库从匹配中排除。
总结
本篇博客主要是讲解的maven仓库的内容,通过本篇博客对仓库的思维导图,以及本篇博客的具体内容,能够对maven仓库有一个更为全面的理解。并且在具体项目开发过程中也能够十分明确maven仓库有什么、maven仓库是什么。