4 Maven仓库

一、何为Maven仓库
    构件:任何一个依赖、插件或者项目构件的输出,都可以成为构件。任何一个构件都有一组坐标唯一标示。
    得益于坐标机制,任何Maven项目使用任务一个构件的方式都是一致的。在此基础上,Maven可以在某个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库。实际的Maven项目将不再各自存储其依赖文件。它们只需要声明这些依赖的坐标,在需要的时候,Maven会自动根据坐标找到仓库中的构件,使用它们。
    为了实现重用,项目构建完毕后生成的构件也可以安装或者部署到仓库中,供其他项目使用。
二、仓库的布局
    任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式。路径和坐标的大致对应关系为groupId/artifactId/version/artifactId-version.packaging
三、仓库的分类
    对于Maven来说,仓库只分为两类:本地仓库和远程仓库。当Maven根据坐标寻找构件的时候,它首先会查看本地的仓库,如果本地仓库存在此构件,则直接使用;如果本地仓库不存在此构件,或者需要查看是否有更新的构件版本的时候,Maven就回去远程仓库查找,发现后下载到本地仓库再使用,如果本地和远程都不存在需要的构件,Maven就会报错。
    仓库分类如下图:
    
    中央仓库:Maven核心自带的远程仓库,包括了绝大数开源的构件。默认如果本地仓库没有的时候从中央仓库下载。
    私服:一个特殊的远程仓库,为了节省宽带和时间,应该在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库,内部的项目还能部署到私服上供其他项目使用。
    3.1 本地仓库
    默认情况下,不管是Windows还是Linux,每个用户在自己的用户目录下都有一个路径名为.m2/repository/的仓库目录。可以通过配置修改仓库目录地址。可以编辑~/.m2/settings.xml或者$M2_HOME/conf/settings.xml。设置localRepository元素的值为想要的仓库地址。
    例如:
    <localRepository>D:/MavenRepository</localRepository>
    一个构件只有在本地仓库之后,才能由其他Maven项目使用,一般通过远程仓库下载,也可以将本地项目构件安装到本地Maven仓库中。使用命令mvn clean install 。install插件的install目标将项目的构建输出文件安装到本地仓库。
    3.2 远程仓库
    安装好Maven后,如果不执行任何Maven命令,本地仓库的目录是不存在的。当用户输入第一条Maven命令之后,Maven才会创建本地仓库,然后根据配置和需要,从远程仓库下载构件至本地仓库。
    3.3 中央仓库
    由于原始的本地仓库是空的,Maven必须知道至少一个可用的远程仓库,才能在执行Maven命令的时候下载需要的构件。重要仓库是默认的远程仓库,Maven的安装目录自带了中央仓库的配置。在$M2_HOME/lib/maven-model-builder-3.0.jar的org/apache/maven/model/pom-4.0.0.xml。存在如下配置:
    
    这个文件是所有Maven项目都会继承的超级POM。之后详细介绍继承和超级POM。
    使用id central对中央仓库进行唯一表示。name url 使用默认的仓库布局。snapshots元素子元素enabled的值为false,表示不会从该中央仓库下载快照版本的构件。快照之后介绍。
    3.4 私服
    私服是特殊的远程仓库,它架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服之后,再为Maven的下载请求提供服务,此外,一些无法从外部仓库下载到的构件也可能从本地上传到私服上供大家使用。
    
    好处:
    ①节省自己的外网带宽
    ②加速Maven构件
    Maven的一些内部机制(例如快照更新检查)要求Maven在执行构件的时候不停的检查远程仓库数据,当项目配置了很多外部远程仓库的时候,构建的速度会大大降低。使用私服解决问题
    ③部署第三方构件
    当某个构件无法从任何一个外部远程仓库获得,怎么办?
    ④提高稳定性。增强控制
    Maven构件依赖远程仓库,Internet不稳定的时候,Maven构建也就不稳定。使用私服解决问题
    ⑤降低中央仓库的负荷
    之后介绍流行的Maven私服软件——Nexus
四、远程仓库的配置
    很多情况,默认的中央仓库无法满足项目需求,需要配置其他远程仓库。可以在pom中配置该仓库。
    
    id:任何一个仓库的声明id必须是唯一的,尤其是注意Maven自带中央仓库的id是central,如果其他仓库声明也使用该id,就会覆盖中央仓库配置。
    url:仓库地址
    release:控制Maven对于发布版构件的下载。
    snapshots:控制Maven对于快照版构件的下载。
    enable:是否开启release或者snapshots的下载支持。
    updatePolicy:用来配置Maven从远程仓库检查更新的频率,默认是daily,表示每天检查一次;never:从不检查更新;always:每次构建都检查更新;interval:X  每隔X分钟检查一次更新。
    checksumPolicy:用来配置Maven检查检验和文件的策略。当构建被部署到Maven仓库中时,会同时部署对于应用的检验和文件,在下载构件的时候,Maven会验证校验和文件,如果失败?checksumPolicy默认值是warn,会执行构建时输出警告信息,其他可用——fail:遇到校验和错误就构件失败;ignore:完全忽略校验和错误。
    4.1 远程仓库的认证
    大部分无需验证就可直接访问,但是出于安全可以配置仓库用户名和密码,所以需要认证。
    配置认证信息和配置仓库信息不同,仓库信息可以直接配置在POM文件中,但是认证信息必须配置在settings.xml文件中。这是因为POM往往被提交代码仓库供所有成员访问,而settings.xml一般只放在本机,所以更安全。
    
    id:必须和POM中需要认证的Repository元素的id完全一致。正是这个id将认证信息和仓库配置联系在一起。
    username:你懂得
    password:你懂得
    4.2 部署至远程仓库
    Maven除了能对项目进行编译、测试、打包之外,还能降项目生成的构建部署到仓库中。
    (1)首先编辑项目的pom.xml文件,配置<distributionManagement>元素
    例子:
    
    distributionManagement包含repository和snapshotRepository子元素,前者发布版本构建的仓库,后者表示快照版本的仓库。这两个元素下都有id、name、url标签。id是仓库的唯一标示,name是为了方便人阅读,url表示该仓库的地址。
    需要认证,上一小节讲述了如何认证。
    (2)配置正确后在命令行运行mvn clean deploy,Maven就会将项目构件部署带配置对应的远程仓库,如果项目当前的版本是快照版本,则部署到快照版本仓库地址,否则就部署到发布版本仓库地址。
五、快照版本
    在Maven的世界中,任何一个项目或者构件都必须有自己的版本。例如:1.1.0、2.1-SNAPSHOT、2.1-20160828.221414-13等。第一个是稳定的发布版本,后两个是不稳定的快照版本。
    Maven为何需要区分发布版本和快照版本?例子:模块A与模块B同时不同的人开发,而B依赖A;如果只使用发布版本,处理比较麻烦,可能需要不断修改两个模块的POM文件的版本号。会比较麻烦。
    快照版本机制:只需要将A模块设定为2.1-SNAPSHOT,然后发布到私服中,发布过程中,Maven会自动为构件打上时间戳。有了时间戳,Maven就能随时找到仓库中该构件2.1-SNAPSHOT版本的最新文件。这时B模块只需要配置对A模块的2.1-SNAPSHOT版本依赖,当B模块构建的时候Maven会自动从仓库中检查模块A的2.1-SNAPSHOT的最新构建,当发现更新的时候便进行下载。默认每天更新一次,可以配置,上文讲述过。用户也可以使用命令-U参数强制让Maven检查更新:mvn clean install -U。
    当项目开发完成后,将快照版本更改为发布版本。    
    注意:快照版本一般是不稳定的,所以只能内部依赖,不能依赖第三方类库的快照版本,很危险!!!
六、从仓库解析依赖的机制
    当本地仓库没有依赖构件时候,Maven会自动从远程仓库下载;当依赖版本为快照版本的时候,Maven会自动找到最新的快照。依赖解析机制如下:
    1)当依赖范围是system,Maven直接从本地文件系统解析构件。
    2)根据依赖坐标计算仓库路径,先从本地仓库查询构件,如果发现则解析成功。
    3)本地不存在,如果依赖版本是显示的发布版本构件,如:1.2.0等,则遍历所有远程仓库,发现后下载解析使用。
    4)如果依赖版本是release或者latest,则基于更新策略读取所有远程仓库的元数据/groupId/artifactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出release或者latest的真实的值,然后基于这个真实的值检查本地和远程仓库到2),3)。
    5)如果依赖版本是snapshot,则基于更新策略得到最新的快照版本的值,然后基于这个真实的值检查本地和远程仓库到2),3)。
    6)如果解析后得到的构件版本是时间戳格式的快照,则将时间戳改成非时间戳,并使用这个构件。
    当依赖的版本不明晰的时候,如:snapshot,latest,release,Maven就需要基于更新远程仓库的策略来检查更新。上节有讲,此处不在多说。可以在命令行加上参数-U强制检查更新,使用后Maven会忽略<updatePolicy>的配置。
    当Maven检查完更新策略,并决定检查依赖更新的时候,就需要检查仓库元数据maven-metadata.xml。
    release版本:仓库中存在该构件的最新发布版本。
    latest版本:仓库中存在该构件的最新版本(包含快照)。最新是基于/groupId/artifactId/maven-metadata.xml计算出来(远程仓库)。
    如下例子:
    
    注意:依赖声明的latest和release是不推荐使用的,因为Maven随时都可能解析到不同的构件,并且Maven不会明确告诉用户这种变化,如果出现构件失败,查找问题比较复杂。
    仓库的元数据并不是永远正确的,当用户发现无法解析某些构件或者解析到错误构件的时候,就可能出现仓库元数据错误,需要手动的或者使用工具(如Nexus)对其进行修复。
七、镜像
    如果仓库X可以提供仓库Y存储的所有内容,那么就可以说X是Y的一个镜像。
    配置在settings.xml中。
    例子:
    
    <mirrorOf>标签的值是central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像。id,name,url 和一般仓库配置无异。
     <mirrorOf>* </mirrorOf>:所有仓库的镜像,任何对于远程仓库的请求都会转至镜像。
    
    
八、仓库搜索服务
    如何找到需要的依赖,我们一般知道类库的项目名称,需要知道Maven确切的Maven坐标;所以需要使用仓库搜索服务来根据关键字得到Maven坐标。
    常用工具:Sonatype Nexus、Javana、MVNbrowser、MVNNrepository。
 
 
 
 
 
 
 
 
posted @ 2016-08-30 21:27  张宗星  阅读(265)  评论(0编辑  收藏  举报