POM文件配置解析

    pom.xml:maven项目的核心,定义了项目的基本信息,用于描述项目如何构建,声明项目的依赖,等等。

    下面一步步解析pom.xml文件的相关配置。

115009_VFkJ_734885.png

如图:

  • project:是pom.xml的根元素,声明了POM相关的命名空间及xsd元素。

  • modelVersion:指定了当前POM的模型版本,对于maven2和maven3来说它只能是4.0.0。

  • groupId:定义了项目属于哪个组,这个组往往和项目所在的组织或公司相关联。例如图中定义理解为:vinuxpay的mvntest项目。

  • artifactId:定义了当前maven项目在组中的唯一ID,用来与其他不同的项目或者模块区别开来。例如图中是为HelloWorld项目定义一个artifactId为hello-world。默认情况下会以artifactId值开头生成文件。

  • version:定义当前项目的版本。SNAPSHOT说明当前项目处于开发中,为不稳定版本,随着项目的升级,version会不断的更新。

  • packaging:定义maven项目的打包方式,如果不定义,默认为jar包。

  • name:项目名称,不是必须的,但是还是推荐为每个POM申明,以方便信息交流。

  • description:对项目的描述,不是必须的。

    最重要的groupId、artifactId、version三个元素定义了maven项目的基本坐标,任何的jar、pom或者war都是基于这些接本的坐标进行区分的。


依赖

依赖配置

如图:

144146_q4Ti_734885.png

project > dependencies元素用来配置项目依赖,一个dependencies下可以配置多个dependency元素用来申明一个或多个项目依赖。

groupId、artifactId、version依赖的基本坐标,对于任何一个依赖来说坐标是最重要的,Maven根据坐标来查找依赖。

type:依赖类型,对应于项目坐标定义的packaging。大部分情况下该属性不必声明,默认为jar。

scope:依赖范围。用来控制依赖与编译、测试、运行三种classpath的关系。Maven有以下依赖范围:

  1. compile:编译依赖范围。如果没有指定,就默认使用该范围,对于编译、测试、运行三种classpath都有效。典型的例子是spring-core,在编译、测试、运行时都要使用该依赖。

  2. test:测试以来范围,只对测试时有效。例如Junit,只有在编译和运行测试的时候有效才需要。

  3. provided:已提供依赖范围。只对编译和测试的classpath有效,运行时无效。例如servlet-API,因为容器已提供,就不需要Maven再引入。

  4. runtime:运行时依赖范围。在测试和运行的classpath有效,编译时无效。例如JDBC驱动实现,项目主代码编译只要提供JDK的JDBC接口,只有在测试和运行时才需要实现上述接口的JDBC驱动。

  5. system:系统依赖范围。依赖关系和provided依赖关系一致。使用时必须通过systemPath显示的指定以来文件路径。由于此依赖不是通过Maven仓库解析,而是与本机系统绑定,会造成项目移植不可用,需谨慎使用。

  6. systemPath也可引用环境变量,如:<systemPath>${JAVA_HOME}/lib/rt.jar</systemPath>

  7. import(Maven2.0.9以上) :  导入依赖范围。    


        

optional:可选依赖。用来标记依赖是否可选(true/false)。

exclusions:声明排除传递性依赖。

传递性依赖

    最基本理解就是:假设项目A对项目B有一个compile范围依赖,而项目B对项目C也有一个compile范围依赖,那么,C就会成为A的一个compile范围依赖。C就是A的一个传递性依赖。好处就是:一方面是简化和方便了依赖申明,另一方面只需关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。

可选依赖(optional)

    假设项目A依赖于项目B,项目B依赖于项目X和Y,但是B对于项目X和Y都是可选依赖。如果三者的依赖范围都是compile,那么X.Y对于A就是传递性依赖,但是由于X、Y是可选的,那么对于A来说一来就不会传递。例如多数据库工具包,在构建这个工具包的时候,需要多种数据库驱动;但是在使用的时候只会依赖一种。

164453_X2u6_734885.png

    上图表示使用optional元素表示mysql-connector-java和postgresql这两个依赖为可选依赖,他们只会对B产生影响。当A依赖B项目的时候,这两个依赖不会被传递。当A依赖B的时候,如果使用基于MySQL的数据库,就需要在A中声明mysql-connector-java这一依赖。

    最后要说明一点:在理想状态下是不应该使用可选依赖的,使用可选依赖的原因就是某一个项目实现了多个特性。基于面向对象的单一性原则,一个类只应该有一项功能,更好的做法是为mysql-connector-java和postgresql分别创建一个maven项目,基于同样的groupId分配不同的artifactId,根据需要选择。

排除依赖(exclusions)

    假设项目A依赖项目B,项目B依赖项目C,但是项目C是SNAPSHOT不稳定版本。由于传递性依赖,会照成项目A不稳定,因此需要在依赖B时排除对项目C SNAPSHOT 版本的依赖,并且在项目A中声明项目C的正式发布版本。

101015_p2Pq_734885.png

如图,代码中使用了executions声明排除依赖,可以包含一个或者多个execution子元素,因此可以排除一个或多个传递性依赖。但要注意的是:声明execution只需要groupId和artifactId,而不需要version元素。这是因为只要groupId和artifactId就能唯一定位依赖中的某个依赖。换句话说,Maven解析后的依赖中,不可能出现两个groupId和artifactId都相同,而version不同的两个依赖。

归类依赖

    有点类似于定义java常量的意思,在一处定义了直接调用就行,而不需要重复定义,或者修改常量值得时候,只需修改一处而不是逐个修改,避免了因为遗漏带来的不必要麻烦。

104424_RshP_734885.png

    如图,首先使用properties元素定义Maven属性,然后定义子元素springframework,值为2.5.6。maven在运行的时候会将POM中的所有${springframework.version}替换成实际值2.5.6。

----------------------------------------------------------------------------------------------------------------

   Maven会自动解析所有项目的直接依赖和传递性依赖,并且根据规则正确判断每个依赖的范围,对于一些依赖冲突也能进行调节,确保任何一个构建只有唯一的版本在依赖中存在。

-----------------------------------------------------------------------------------------------------------------


仓库

    Maven用某一位置存储所有Maven项目共享构建,这位置就叫仓库。任何构建都有groupId、artifactId、version这一坐标,根据坐标可以确定其在仓库存储的唯一路径。

路径与坐标的关系大致是:groupId/artifactId/version/artifactId-version.packaging。例如上图的MVN测试hello-world依赖,在仓库的路径就是:vinuxpay.mvntest/vinuxpay.mvntest.hello-world/0.0.1-SNAPSHOT/vinuxpay.mvntest.hello-world-0.0.1-SNAPSHOT.jar。

分类

    分为两类:本地仓库和远程仓库。远程仓库又包括:中央仓库(Maven核心自带)、私服、其他类型仓库。如图:

102608_5hVW_734885.png

   构建查找顺序: 先查找本地仓库,如果本地仓库存在此构建,直接使用。如果不存在,就去远程仓库查找,并且下载到本地。如果本地和远程都没有,Maven就会报错。

本地仓库

    默认路径: ${user.home}/.m2/repository。

    自定义路径:修改MAVEN_HOME/config/setting.xml文件的localRepository元素值,如图:

104039_NKnl_734885.png

    对于本地仓库的依赖,一种是从远程仓库中下载至本地仓库,另一种是将本地项目的构建通过在该项目路径下执行mvn clear install安装。

远程仓库

    默认:Maven自带的核心--中央仓库。

    配置:在repositories元素下使用repository配置一个或者多个远程仓库。

111634_uBd1_734885.png

    id:仓库名称,必须唯一。不能声明和Maven自带中央仓库的id一样(central),否则就会覆盖掉中央仓库。

    url:仓库地址,基于http协议。

    releases和snapshots:用来控制Maven对发布版和SNAPSHOTS版本构建的下载。如果enabled元素值为true,表示开启发布版本的下载支持,但不支持SNAPSHOTS版本的下载支持。

    updatePolicy:表示远Maven对程仓库检查更新的频率。默认daily,表示每天检查一次;never:从不检查更新;always:每次构建都检查;interval:X--每隔X分钟检查一次更新。

    checksumPolicy:用来配置Maven检查检验和文件的策略。当构建被部署到仓库时,会同时部署对应的校验和文件。默认为warn:Maven会在构建时输出警告信息;fail:Maven会在遇到校验和错误就会让构建失败;ignore:完全忽略校验和错误。

远程仓库部署(mvn clean deploy)

    将项目构建部署到远程仓库(一般是自建的私服)中POM配置如下:

140657_qaFN_734885.png

    repository:发布版本构建的仓库。

    snapshotRepository:SNAPSHOT版本的仓库。

    id:该仓库的唯一标识。

    对远程仓库进行构建部署时候,出于安全方面的考虑,有时我们要对远程仓库的访问进行认证,一般将认证信息配置在settings.xml中:

114316_MNV4_734885.png

    id :要与POM中repository元素id一致。

    username:认证名。

    password:认证密码。

   

镜像

    如果仓库A能够提供仓库B的所有内容,那么A就是B的一个镜像。例如http://maven.net.cn/content/groups/public就是Maven中央仓库http://repol.maven.org/maven2在中国的一个镜像。由于地理位置因素,该镜像往往能够比中央仓库提供更快的服务。因此,可以配置该镜像来代替中央仓库。配置setting.xml如下:

中央仓库镜像配置

102559_3XBJ_734885.png

配置私服镜像

103308_l7I1_734885.png

<mirrorOf>的相关配置:

  •     <mirrorOf>*</mirrorOf>:配置所有远程仓库

  •     <mirrorOf>external:*</mirrorOf>:匹配所有不在本机上的远程仓库

  •     <mirrorOf>repo1,repo2</mirrorOf>:匹配仓库repo1和repo2,多个仓库之间用逗号分隔。

  •     <mirrorOf>*,!repo1</mirrorOf>:匹配除repo1以外的所有远程仓库。感叹号表示排除


****************************************************未完,后续更新****************************************

转载于:https://my.oschina.net/u/734885/blog/638359