第五节:Maven仓库(下)

来源:互联网 发布:汽车网络销售 编辑:程序博客网 时间:2024/06/06 13:02
快照版本:
     定义:Snapshot版本代表不稳定、尚处于开发中的版本。
    我们知道,Maven的依赖管理是基于版本管理的,对于发布状态的artifact,如果版本号相同,即使我们远程服务器上的组件比本地新,Maven也不会主动下载的。如果我们在开发阶段都是基于正式发布版本来做依赖管理,那么遇到这个问题,就需要升级组件的版本号,可这样就明显不符合要求和实际情况了。
     定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写)
maven2会根据模块的版本号(pom文件中的version)中是否带有-SNAPSHOT来判断是快照版本还是正式版本。如果是快照版本,那么在mvn deploy时会自动发布到快照版本库中,会覆盖老的快照版本,而在使用快照版本的模块,在不更改版本号的情况下,直接编译打包时,maven会自动从远程服务器上下载最新的快照版本。如果是正式发布版本,那么在mvn deploy时会自动发布到正式版本库中,而使用正式版本的模块,在不更改版本号的情况下,编译打包时如果本地已经存在该版本的模块则不会主动去远程服务器上下载。
     试想一下这样的情况,小张在开发模块A的2.1版本,该版本还未正式发布,与模块A一同开发的还有模块B,它由小张的同事季MM开发,B的功能依赖于A。在开发的过程中,小张需要经常将自己最新的构建输出,交给季MM,供她开发和集成调试,Maven的快照版本机制就是为了解决上述问题。在该例中,小张只需要将模块A的版本设定为2.1-SNAPSHOT,然后发布到私服中,在发布的过程中,Maven会自动为构件打上时间戳。比如:2.1-20091214.221414-13就表示2009年12月14日 22点14分14秒的第13次快照。有了该时间戳,Maven就能随时找到仓库中该构件2.1-SNAPSHOT版本最新的文件。这时,季MM配置对于模块A的2.1-SNAPSHOT版本的依赖,当她构件模块B的时候Maven会自动从仓库中检查模块A的2.1-SNAPSHOT的最新构件,当发现有更新时便进行下载。默认情况下,Maven每天检查一次更新(由仓库配置的updatePolicy控制),用户也可以使用命令行-U参数强制让Maven检查更新,如:mvn clean install-U
     注意:快照版本应该只在组织内部的项目和模块间依赖使用(开发阶段),项目不应该依赖于任何组织外部的快照版本的构件,因为由于快照版本的不稳定性,会使构建存在潜在的危险。

从仓库解析依赖的机制:
     Maven是根据怎样的规则从仓库解析并使用依赖构件的呢?
     当本地仓库没有依赖构件的时候,Maven会自动从远程仓库下载。当依赖版本为快照版本的时候,Maven会自动找到最新的的快照。这背后的依赖解析机制可以概括如下:
  1. 当依赖的范围是system的时候,Maven直接从本地文件系统解析构件。
  2. 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如果发现相应构件,则解析成功。
  3. 在本地仓库不存在相应构件的情况下,如果依赖的版本是显式的发布版本构件,如:1.2,2.1等,则遍历所有的远程仓库,发现后,下载并解析使用。
  4. 如果依赖的版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/version/mavenmetadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库,或者从远程仓库下载。
  5. 如果最后解析得到的构件版本是时间戳格式的快照,如:1.4-20091104.121450-121,则复制其时间戳格式的文件到非时间戳格式,如:SNAPSHOT,并使用该非时间戳格式的构件
      当依赖的版本不明晰的时候,如:RELEASE,LATEST和SNAPSHOT,Maven就需要基于我们在POM文件中配置的远程仓库的更新策略来检查更新。首先是<releases><enabled>和<snapshots><enabled>,只有仓库开启了对于发布版本的支持时,才能访问该仓库的发布版本构件信息,对于快照版本也是同理;
     其次要注意的是<releases>和<snapshots>的子元素<updatePolicy>,该元素配置了检查更新的频率。最后,用户还可以从命令行加入参数-U,强制检查更新,使用参数后,Maven就会忽略<updatePolicy>的配置。
当Maven检查完更新策略,并决定检查依赖更新的时候,就需要检查仓库元数据maven-metadata.xml。如:

     在XML文件列出了仓库中存在的该构件所有可用的版本,同时latest元素指向了这些版本中最新的那个版本。而release元素指向了这些版本中最新的发布版本Maven通过合并多个远程仓库及本地仓库的元数据,就能计算出基于所有仓库的latest和release分别是什么,然后再解析具体的构件。这是Maven2时期使用的,Maven3不再支持在插件配置中使用LATEST和RELEASE。
     当依赖的版本设为快照版本的时候,Maven也需要检查更新,这时,Maven会检查仓库元数据groupId/artifactId/version/maven-metadata.xml,如例:
     
     该xml文件的snapshot元素包含timestamp和buildNumber两个子元素,分别代表了这一快照的时间戳和构建号,基于这两个元素可以得到该仓库中此快照的最新构件版本实际为1.4.2-20091213.221414-13。通过合并所有远程仓库和本地仓库的元数据,Maven就能知道所有仓库中该构件的最新快照。 

     下面我们来回忆一下SNAPSHOT版本构件的部署与下载流程:
  1. 在版本号后加上大写的-SNAPSHOT
  2. mvn deploy的时候会Maven自动为构件打上时间戳,然后覆盖远程仓库的旧版本。
  3. 当另一个项目需要引用此构件时,先基于更新策略读取所有远程仓库的元数据groupId/artifactId/version/mavenmetadata.xml,将其与本地仓库的对应元数据合并后,如果我们发现远程仓库中的版本比本地仓库中的版本要新,则需要更新本地仓库中的构件。
镜像:
    定义:如果仓库X可以提供仓库Y储存的所有内容,那么我们就认为X时Y的一个镜像。
    好处:
  • 对于默认的中央仓库来说,在不配置镜像的情况下,maven默认会使用中央库.
  • maven中央库在国外,有时候访问会很慢,尤其是下载较大的依赖的时候,有时候速度会很慢,甚至会出现无法下载的情况.
  • 为了解决依赖下载速度的问题,需要配置maven国内镜像
     配置:maven镜像有两种配置,一种是在settings.xml中进行配置,这会对所有的Maven项目产生影响;第二种是在项目的pom.xml中进行配置,这只会对当前项目产生影响。我们需要配置的是mirrors下的的子元素mirror:
    • id:镜像仓库的唯一标识。
    • name:镜像仓库的名称。
    • url:镜像仓库的地址。
    • mirrorof:表示是谁的镜像
如果仓库镜像需要认证,也可以基于该id配置仓库认证。
      关于镜像的一个常见的用法是与私服相结合。我们可以利用私服配置一个外部公共仓库的镜像,即我们将所有对外部公共仓库,远程服务器的访问都路由到这个私服上。这样做将配置集中到了私服,简化了对远程服务器的配置。在这种情况下,所有的构件都从私服获得,私服就是所有仓库的镜像。

     该例子中<mirrorOf>的值为*,表示配置的是所有Maven仓库的镜像。为了应对复杂情况,<mirrorOf>还有其他配置。
    • <mirrorOf> * </mirrorOf>:匹配所有的远程仓库。
    • <mirrorOf>external: *  </mirrorOf>:匹配所有不在本机上的远程仓库,即使用localhost的除外,使用file://协议的除外。
    • <mirrorOf>A,B  </mirrorOf>:匹配仓库A和B,多个仓库用逗号间隔。
    • <mirrorOf>*,!C  </mirrorOf>:匹配所有的远程仓库,仓库C除外。
0 0