首页 » Maven实战 » Maven实战全文在线阅读

《Maven实战》6.2 仓库的布局

关灯直达底部

任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式。例如,log4j:log4j:1.2.15这一依赖,其对应的仓库路径为log4j/log4j/1.2.15/log4j-1.2.15.jar,细心的读者可以观察到,该路径与坐标的大致对应关系为groupId/artifactId/version/artifactId-version.packaging。下面看一段Maven的源码,并结合具体的实例来理解Maven仓库的布局方式,见代码清单6-1:

代码清单6-1 Maven处理仓库布局的源码

该pathOf()方法的目的是根据构件信息生成其在仓库中的路径。在阅读本段代码之前,可以先回顾一下第5章的相关内容。这里根据一个实际的例子来分析路径的生成,考虑这样一个构件:groupId=org.testng、artifactId=testng、version=5.8、classifier=jdk15、packaging=jar,其对应的路径按如下步骤生成:

1)基于构件的groupId准备路径,formatAsDirectory()将groupId中的句点分隔符转换成路径分隔符。该例中,groupId org.testng就会被转换成org/testng,之后再加一个路径分隔符斜杠,那么,org.testng就成为了org/testng/。

2)基于构件的artifactId准备路径,也就是在前面的基础上加上artifactId以及一个路径分隔符。该例中的artifactId为testng,那么,在这一步过后,路径就成为了org/testng/testng/。

3)使用版本信息。在前面的基础上加上version和路径分隔符。该例中版本是5.8,那么路径就成为了org/testng/tesgng/5.8/。

4)依次加上artifactId,构件分隔符连字号,以及version,于是构建的路径就变成了org/testng/testng/5.8/testng-5.8。读者可能会注意到,这里使用了artifactId.getVersion(),而上一步用的是artifactId.getBaseVersion(),baseVersion主要是为SNAPSHOT版本服务的,例如version为1.0-SNAPSHOT的构件,其baseVersion就是1.0。

5)如果构件有classifier,就加上构件分隔符和classifier。该例中构件的classifier是jdk15,那么路径就变成org/testng/testng/5.8/testng-5.8-jdk5。

6)检查构件的extension,若extension存在,则加上句点分隔符和extension。从代码中可以看到,extension是从artifactHandler而非artifact获取,artifactHandler是由项目的packaging决定的。因此,可以说,packaging决定了构件的扩展名,该例的packaging是jar,因此最终的路径为org/testng/testng/5.8/testng-5.8-jdk5.jar。

到这里,应该感谢Maven开源社区,正是由于Maven的所有源代码都是开放的,我们才能仔细地深入到其内部工作的所有细节。

Maven仓库是基于简单文件系统存储的,我们也理解了其存储方式,因此,当遇到一些与仓库相关的问题时,可以很方便地查找相关文件,方便定位问题。例如,当Maven无法获得项目声明的依赖时,可以查看该依赖对应的文件在仓库中是否存在,如果不存在,查看是否有其他版本可用,等等。