注:本文节选自我正在编写的《Maven实战》
任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式。例如log4j:log4j:1.2.15这一依赖,其对应的仓库路径为log4j/log4j/1.2.15/log4j-1.2.15.jar,细心的读者可以观察到,该路径与坐标的大致对应关系为groupId/artifactId/version/artifactId-version.packaging。下面看一段Maven的源码并结合具体的实例来理解Maven仓库的布局方式:
private static final char PATH_SEPARATOR = '/';
private static final char GROUP_SEPARATOR = '.';
private static final char ARTIFACT_SEPARATOR = '-';
public String pathOf( Artifact artifact )
{
ArtifactHandler artifactHandler = artifact.getArtifactHandler();
StringBuilder path = new StringBuilder( 128 );
path.append( formatAsDirectory( artifact.getGroupId() ) ).append( PATH_SEPARATOR );
path.append( artifact.getArtifactId() ).append( PATH_SEPARATOR );
path.append( artifact.getBaseVersion() ).append( PATH_SEPARATOR );
path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
if ( artifact.hasClassifier() )
{
path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
}
if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
{
path.append( GROUP_SEPARATOR ).append( artifactHandler.getExtension() );
}
return path.toString();
}
private String formatAsDirectory( String directory )
{
return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
}
该pathOf()方法的目的是根据构件信息生成其在仓库中的路径。在阅读本段代码之前,读者可以先回顾一下上一章Maven坐标的相关内容。这里,我们根据一个实际的例子来分析路径的生成,考虑这样一个构件:groupId=org.testng、artifactId=testng、version=5.8、classifier=jdk15、packaging=jar,其对应的路径按如下步骤生成:
- 首先基于构件的groupId准备路径,formatAsDirectory()将groupId中的句点分隔符转换成路径分隔符,该例中,groupId org.testng就会被转换成org/testng,之后再加一个路径分隔符斜杠,那么org.testng就成为了org/testng/。
- 基于构件的artifactId准备路径,也就是在前面的基础上加上artifactId以及一个路径分隔符,该例中的artifactId为testng,那么在这一步过后路径就成为了org/testng/testng/。
- 接着使用版本信息,在前面的基础上加上version和路径分隔符,该例中版本是5.8,那么路径就成为了org/testng/tesgng/5.8/。
- 这一步再依次加上artifactId,构件分隔符连字号,以及version,于是构建的路径就变成了org/testng/testng/5.8/testng-5.8。读者可能会注意到这里使用了artifactId.getVersion(),而上一步用的是artifactId.getBaseVersion(),version和baseVersion的区别在本章讨论SNAPSHOT的时候会具体阐述。
- 紧接着如果构件有classifier,就加上构件分隔符和classifier,该例中构件的classifier是jdk15,那么路径就变成org/testng/testng/5.8/testng-5.8-jdk5。
- 最后第检查构件的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无法获得项目声明的依赖时,可以简单该依赖对应的文件在仓库中是否存在,如果不存在,是否有其它版本可用,等等。
分享到:
相关推荐
Maven仓库通常按照groupId、artifactId和version来组织库,这种布局使得库的查找和管理变得简单。例如,一个典型的库路径可能是`com/example/mylibrary/1.0.0/mylibrary-1.0.0.jar`,其中`com.example`是groupId,`...
#### 一、何为Maven仓库? Maven 仓库是指Maven用来存储各种构建项目依赖项的文件系统结构。通过Maven的仓库管理机制,开发人员可以方便地管理项目的依赖关系,使得项目的构建过程更加标准化、自动化。 #### 二、...
Maven仓库分为两种:本地仓库和远程仓库。本地仓库是Maven在本机上缓存的库,用于存储下载的依赖。远程仓库是网络上的服务器,Maven首先会尝试从这里查找所需依赖。默认的远程仓库是Maven中央仓库,包含了大量的开源...
对于初学者来说,Maven简化了项目结构,通常遵循标准的目录布局,如src/main/java存放源代码,src/main/resources存放资源文件,src/test/java存放测试代码。这种结构使得团队协作变得更加清晰和有序。 与IDE的集成...
1 . 仓库简介 没有 Maven 时,项目用到的 .jar 文件通常需要拷贝到 /lib 目录,项目多了,拷贝的文件副本就... 仓库的布局 构件都有唯一的坐标,Maven 根据坐标管理构件的存储。如以下对 spring-orm-3.2.0 的存储
这一插件使得Android项目可以无缝地与Maven仓库交互,方便地发布到Maven仓库,或者引用Maven仓库中的依赖。 在项目结构上,Android Maven Gradle 插件支持标准的Maven布局,例如`src/main/java`用于存放源代码,`...
### 六、Maven仓库 Maven使用中央仓库(Central Repository)存储公共的第三方库。默认情况下,Maven会从中央仓库下载所需依赖。如果需要自定义私有仓库,可以在`settings.xml`中进行配置。 ### 七、Maven的 ...
1. **使用Nexus建立私服**:Nexus是一个开源的仓库管理系统,可以帮助企业搭建私有的Maven仓库,解决外部网络不稳定、下载速度慢等问题。 2. **持续集成**:结合Hudson/Jenkins等工具,实现自动化测试和构建,提高...
- **概念**: Maven通过预设的项目布局和构建过程,减少了开发者手动配置的需求。 - **优势**: 提高了开发效率,降低了维护成本。 3. **一般接口** - **命令行**: Maven主要通过命令行工具进行操作。 - **目标**...
第6章:仓库/6.1 何为Maven仓库 第6章:仓库/6.2 仓库的布局 第6章:仓库/6.3 仓库的分类 第6章:仓库/6.3 仓库的分类/6.3.1 本地仓库 第6章:仓库/6.3 仓库的分类/6.3.1 本地仓库/6.3.1.1 setting.xml文件路径 第6...
- 要确保你的Maven本地仓库已经包含了所有Android库的依赖,否则Maven可能无法正确地下载和构建项目。 - 对于Android的特殊资源,如布局、图片等,Maven可能需要额外的配置才能正确处理。 - 有些特定的Gradle特性...
- **依赖管理:** Maven自动处理项目的依赖关系,从Maven仓库下载所需的库文件,并管理这些依赖的版本。 - **生命周期与构建阶段:** Maven拥有一个预定义的生命周期,包括编译、测试、打包、验证等阶段,开发者...
在使用Maven管理项目依赖时,很多开发者会遇到无法直接通过Maven仓库下载Oracle JDBC驱动包的问题。这是因为Oracle的授权政策,Maven官方中央仓库并不直接提供Oracle JDBC驱动程序。为了在Maven项目中使用Oracle ...
Maven 自动解决这些依赖,从远程仓库下载所需库,避免了手动管理库文件的麻烦。Maven 依赖的传递性使得项目中所有依赖项的版本控制变得简单。 3. **插件系统**:Maven 使用插件机制执行特定任务,如编译、测试、...
Maven的中央仓库存储了大量的开源库,开发者只需在POM中声明依赖,Maven会自动下载并管理这些依赖,避免了版本冲突问题。依赖范围(compile、runtime、test等)的设置,控制了依赖在不同阶段的引入。 3. **构建...
- **Maven仓库**: Maven使用仓库来存储项目依赖,包括本地仓库和远程仓库。 - **Maven依赖管理**: Maven自动处理项目间的依赖关系,避免了手动管理依赖的问题。 - **站点生成和报告**: Maven可以通过插件自动生成...
2. **依赖管理**:Maven通过中央仓库自动下载项目依赖的库文件,解决了JAR包版本冲突的问题。 3. **项目信息管理**:Maven能够自动生成项目的文档,如项目报表、依赖关系图等。 4. **多模块支持**:Maven支持多模块...
- 标准目录布局:解释Maven的约定优于配置原则,介绍标准的项目目录结构。 - POM详解:深入理解POM.xml文件,包括其组成元素,属性,以及如何管理项目信息和依赖。 3. **Maven生命周期** - 生命周期概念:解释...
1. **安装第三方 JAR 到本地仓库**:如果第三方库没有被托管在公共仓库中,可以先将其安装到本地 Maven 仓库中。 2. **部署第三方 JAR 到远程仓库**:对于需要共享的第三方库,可以将其部署到远程仓库中。 3. **处理...