Maven实战(Maven In Action)

来源:互联网 发布:旅贸通软件 编辑:程序博客网 时间:2024/05/22 15:06

第1章 Maven简介

  • 自Maven 2.0.9开始,所有核心的插件都设定了稳定版本,这意味着日常使用Maven时几乎不会受到不稳定插件的影响。此外,Maven社区也提倡为你使用的任何插件设定稳定的版本。从Maven 3开始,如果你使用插件时未设定版本,会看到警告信息。 P8

第2章 Maven的安装和配置

  • 新的环境变量配置需要新的cmd窗口才能生效

第3章 Maven使用入门

  • POM(Project Object Model,项目对象模型)
    定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等等。
  • modelVersion指定了当前POM模型的版本,对应Maven 2及Maven 3来说,它只能是4.0.0
  • SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。
  • test依赖范围表示该依赖只对测试有效,只能在测试代码中引用,不能在主代码中引用。如果不声明依赖范围,默认值是compile,表示该依赖对主代码和测试代码都有效。
  • finalName可以自定义打包文件的名称,详见第14章。

第5章 坐标和依赖

  • 当pom中不定义packaging时,Maven会使用默认值jar。
  • packaging并非一定与构件的扩展名对应,比如packaging为maven-plugin的构件扩展名为jar。
  • 依赖范围就是用来控制依赖与三种classpath(编译classpath、测试classpath、运行classpath)的关系。
    • compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对应编译、测试、运行三种classpath都有效。
    • test:测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目时将无法使用此类依赖。
    • provided:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。
    • runtime:运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。
    • system:系统依赖范围。该依赖范围与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量,如:${java.home}
    • import(Maven 2.0.9及以上):导入依赖范围。该依赖范围不会对三种classpath产生实际的影响。只在dependencyManagement元素下才有效果,使用该依赖范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。P134
  • 除import以外的各种依赖范围与三种classpath的关系如下表所示:
依赖范围(scope) 对于编译classpath有效 对于测试classpath有效 对于运行时classpath有效 例子 compile Y Y Y spring-core test - Y - JUnit provided Y Y - servlet-api runtime - Y Y JDBC驱动实现 system Y Y - 本地的,Maven仓库之外的类库文件
  • 传递性依赖:Maven会解析各个直接依赖的POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。
  • 传递性依赖范围,第一列表示第一直接依赖范围,第一行表示第二直接依赖范围。规律:当第二直接依赖依赖的范围是compile时,传递性依赖的范围与第一直接依赖的范围一致;当第二直接依赖的范围是test时,依赖不会得以传递;当第二直接依赖的范围是provided时,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为provided;当第二直接依赖的范围是runtime时,传递性依赖的范围与第一直接依赖的范围一致,当compile例外,此时传递性依赖的范围为runtime。
    参考:http://seanzhou.iteye.com/blog/1688740
compile test provided runtime compile compile - - runtime test test - - test provided provided - provided provided runtime runtime - - runtime
  • 依赖调解
    从Maven 2.0.9开始,为了尽可能避免构建的不确定性,Maven定义了依赖调解的第二原则:第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。第一原则:路径最近者优先。
  • 可选依赖不被传递
  • 排除依赖
  • 归类依赖,使用Maven属性
  • 优化依赖
    mvn dependency:list,查看已解析依赖列表
    mvn dependency:tree,查看已解析依赖树
    mvn dependency:analyze,分析当前项目的依赖
    显示声明任何项目中直接用到的依赖。

第6章 仓库


  • 何为Maven仓库
    得益于坐标机制,任何Maven项目使用任何一个构件的方式都是完全相同的。在此基础上,Maven可以在某个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库。为了实现重用,项目构建完毕后生成的构件也可以安装或者部署到仓库中,供其他项目使用。
  • 仓库的分类
    本地仓库、远程仓库(中央仓库、私服、其他公共库)
  • 超级POM
    $M2_HOME/lib/maven-model-builder-3.0.jar中的org/apache/maven/model/pom-4.0.0.xml
  • 任何一个仓库声明的id必须是唯一的,尤其需要注意的是,Maven自带的中央仓库使用的id为central,如果其他的仓库声明也使用该id,就会覆盖中央仓库的配置。
  • 远程仓库的认证
    仓库信息可以直接配置在POM文件中,但是认证信息必须配置在settings.xml文件中。
  • 快照版本
  • 从仓库解析依赖的机制
    RELEASE和LATEST版本,它们分别对应了仓库中存在的该构件的最新发布版本和最新版本(包含快照)。Maven 3不再支持在插件配置中石油LATEST和RELEASE。如果不设置插件版本,其效果就和RELEASE一样,Maven只会解析最新的发布版本构件。
  • 镜像
    如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为X是Y的一个镜像。换句话说,任何一个可以从仓库Y获得的构件,都能够从它的镜像中获取。存在的意义:有的POM中指定了仓库,这样就可以在拦截去远程仓库的请求了。

It works like this: a POM may declare a repository to use in resolving certain artifacts. However, this repository may have problems with heavy traffic at times, so people have mirrored it to several places.

第7章 生命周期和插件

  • Maven的生命周期是抽象的,其实际行为都是由插件来完成。
  • 三套生命周期:clean、default和site
    • clean生命周期
      clean生命周期的目的是清理项目,它包含三个阶段:
    • default生命周期
      default生命周期定义了真正构建时所需要的执行的所有步骤,它是所有生命周期中最核心的部分,其包含的阶段如下,只对重要的阶段进行解释:

    • site生命周期
      site生命周期的目的是建立和发布项目站点,Maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。该生命周期包含如下阶段:
  • 较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。
    当用户调用clean生命周期的clean阶段的时候,不会触发default生命周期的任何阶段,反之亦然,当用户调用default生命周期的compile阶段的时候,也不会触发clean生命周期的任何阶段。
  • 插件目标:插件功能就是一个插件目标。
  • 插件绑定,Maven的生命周期与插件相互绑定,用以完成实际的构建任务。
  • 内置绑定,为了能让用户几乎不用任何配置就能构建Maven项目,Maven在核心为一些主要的生命周期阶段绑定了很多插件目标,当用户通过命令行调用生命周期阶段的时候,对应的插件目标就会执行相应的任务。P100
  • 自定义绑定:除了内置绑定以外,用户还能够自己选择将某个插件目标绑定到生命周期的某个阶段上,这种自定义绑定方式能让Maven项目在构建过程中执行更多更富特色的任务。比如:使用maven-source-plugin创建项目的源码jar包。
    • 对应自定义绑定的插件,用户总是应该声明一个非快照版本,这样可以避免由于插件版本变化造成的构建不稳定性。
    • 有很多插件的目标在编写时已经定义了默认绑定阶段。
  • 插件配置
    • 命令行插件配置
    • POM中插件全局配置
    • POM中插件任务配置
  • 从命令行调用,目标前缀(Goal Prefix)
  • 插件的默认groupId
    在POM中配置插件时,如果该插件是Maven的官方插件(即如果其groupId为org.apache.maven.plugin),就可以省略groupId配置。虽然可以省略,但是不建议使用Maven这一机制,这样的配置会让团队不熟悉Maven的同学感到费解。
  • 解析插件版本
    Maven在超级POM中为所有核心插件设定了版本,超级POM是所有Maven项目的父POM,所有项目都继承这个超级POM的配置。
    Maven 3调整了解析机制,当插件没有声明版本时,不再解析至latest,而是使用release。这样就可以避免由于快照频繁更新而导致的插件行为不稳定。
  • 解析插件(目标)前缀
    插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中。

第8章 聚合与继承

  • 聚合
    • 打包方式packaging的值必须为pom
    • 元素modules是实现聚合的最核心配置
  • 继承
    • 打包方式packaging的值必须为pom
    • 使用parent元素声明父模块
    • 可继承的POM元素,groupId、version、distributionManagement、properties、dependencies、dependencyManagement、build等
    • Maven提供的dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块的依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependencies下的依赖的使用。
    • 插件管理,pluginManagement元素帮助管理插件。
  • 聚合与继承的关系
    聚合主要是为了方便快速构建项目,继承主要是为了消除重复配置。在实际项目中,一个POM即是聚合POM又是父POM。
  • 约定由于配置(Convention Over Configuration)
    • 超级POM说明 P141
  • 反应堆(Reactor)
    在一个多模块的Maven项目中,反应堆(Reactor)是指所有模块组成的一个构建结构。对于单模块的项目,反应堆就是该模块本身,但对于多模块项目来说,反应堆就包含了个模块之间继承与依赖的关系,从而能够自动计算出合理的模块构建顺序。

第14章 灵活的构建

  • Maven属性
    • 通过<properties>元素用户可以自定义一个或多个Maven属性,然后在POM的其他地方使用${属性名称}的方式引用该属性,这种做法的最大意义在于消除重复。
    • 内置属性:主要有两个常用内置属性——${basedir}表示项目的跟目录,即包含pom.xml文件的目录;${version}表示项目版本。
    • POM属性:用户可以使用该类属性引用POM文件中对应元素的值。例如${project.artifactId}就对应了<project><artifactId>元素的值,常用的POM属性如下图所示,这些属性都对应了一个POM元素,他们中的一些属性的默认值都是在超级POM中定义的。
    • 自定义属性:用户可以在POM的<property>元素下自定义Maven属性。例如:

      然后在POM中其他地方使用${my.prop}时被替换成hello。
    • Settings属性:与POM属性同理,用户使用以settings.开头的属性引用settings.xml文件中XML元素的值,如常用的${settings.localRepository}指向用户本地仓库的地址。
    • Java系统属性:所有Java系统属性都可以使用Maven属性引用,例如${user.home}指向了用户目录。可以使用mvn help:system查看所有的Java系统属性。
    • 环境变量属性:所有环境变量都可以使用以env.开头的Maven属性引用。例如${env.JAVA_HOME}指代了JAVA_HOME环境变量的值。可以使用mvn help:system查看所有的环境变量。
  • 构建环境的差异
  • 资源过滤
  • Maven Profile
0 0
原创粉丝点击