Maven学习笔记(二) 坐标、依赖、仓库

今天学习了Maven中坐标、依赖和仓库三个比较重要的概念。

坐标(Coordinate):
Maven定义的规则,用于唯一标识一个构件。包括groupId,artifactId,version,packaging和classifier。

解释如下:
groupId: 定义当前Maven项目所隶属的实际项目,如org.sonatype.nexus,这是一个大项目的概念。
artifactId: 定义实际项目中的一个Maven项目,或者说是模块,推荐用实际项目名作为artifactId的前缀,如nexus-core。
version: 定义Maven项目当前所处的版本号,Maven在其中定义了一套完整的版本规范。如SNAPSHOT等。
packaging: 定义Maven项目的打包方式,默认为jar,通常会与最终生成的构件的扩展名对应。
classifier: 定义构件输出的一些附属构件。如javadoc,sources等,他们也拥有自己唯一的坐标。值得注意的,不可以直接定义项目的classifier,因为这不

是项目直接默认生成的,而是由附件的插件帮助生成。

当然之后学到的仓库的布局也是基于Maven坐标的。


依赖(Dependency):

pom.xml配置文件根元素project下的dependencies可以包含若干个Dependency元素,以声明项目依赖。而依赖又可包含groupId,artifactId,version三个基本

坐标元素和type,scope,optional,exclusions等元素。

解释如下:
type: 依赖的类型,其实是与坐标中packaging相对应的,默认jar。
scope: 声明依赖的范围,有compile,test,provided,runtime,system几种,稍候详述。
optional: 用于标记依赖是否可选。
exclusions:用于排除依赖传递性,稍候详述。


依赖范围scope: 用来控制依赖于classpath(包括编译、测试、运行三种classpath)的关系。
compile: 默认的依赖范围,对于三种classpath均有效,如spring-core。
test: 只对测试classpath有效,如JUnit。
provided: 对于编译和测试classpath有效,因为一般在运行时环境以提供,如servlet-api。
runtime: 对于测试和运行classpath有效,如JDBC驱动实现。
system: 对于编译和测试classpath有效,但必须通过SystemPath元素显式指定依赖文件的路径,往往与本机系统绑定,可移植性差,慎用。


依赖传递性:避免下载过多不必要的jar包或缺失某些包。Maven会逐层解析各个直接依赖的POM,把必要的间接依赖引入当前项目。

依赖调节:当依赖关系出现不同路径的冲突时,如A->B->C->X(1.0),A->D->X(2.0),Maven根据两个原则进行选择:1、路径短者优先 2、第一声明者优先。

最佳实践:
1、排除依赖:exclusion元素,排除掉或者手工替换某个传递性依赖,以保证稳定性。
2、归类依赖:properties元素定义类似版本号springframwork.version的元素,类似于常量,用${}在后续配置文件中引用,便于统一管理和修改。
3、优化依赖:Maven自动解析所有项目的直接依赖和传递性依赖,并按规则调整一些冲突,保证任何构件只有唯一的版本存在。可用命令mvn dependency:list或

mvn dependency:tree查看当前项目的已解析依赖。


仓库(Repository):

根据我的理解,Maven的仓库其实替代了以前编程中用的lib目录。只不过以前的不同项目lib目录下会有大量的重复而且每次都要手动添加。难以统一管理,也浪

费磁盘空间。而Maven仓库得益于坐标机制,只要在某处统一存储所有Maven项目共享的构件,任何实际项目中只要声明依赖的坐标,Maven便可在需要的时候自动

找到并使用它们。而为了便于重用,项目构建完毕后生成的构件仍可安装或部署到仓库中供后续项目使用。

仓库的布局方式其实简洁明了,基本上与坐标的对应关系是:grouptId/artifactId/version/artifactId-version.packaging。

Maven仓库大体上分为两类:本地和远程。

本地仓库默认在用户目录.m2/repository下,通过这两天的实践,我的本地仓库下也有了不少Maven下载的构件了。这些已经存在的构件在以后的项目中如有需要

就可以直接根据坐标找到来使用而无需重新下载。

远程仓库主要包括了中央仓库,私服和其他公共库。
其中中央仓库包含了绝大多数流行的开源构件,便是Maven“开箱即用”理念的核心体现。
私服则往往应用于局域网内,代理广域网上的远程仓库,共内部用户使用。好处主要在于节省带宽、加速构建、部署第三方构件(有些由于版权问题无法从外部

仓库获得的以及内部自行开发的构件)等等。目前最流行的私服软件是Nexus。名字跟谷歌儿子似的。。。

最后简单提一下快照版本。Maven要求任何项目或构件都有自己的版本号。Maven主要区分了发布版和快照版。版本设定为SNAPSHOT的构件在发布的过程中,Maven

会自动打上时间戳,便于随时找到仓库中该构件的最新文件。快照版本一般应用于内部项目和模块间依赖,因为这往往是不稳定的。因此正式发布的时候应该将版本号改为发布版alpha。

你可能感兴趣的:(maven)