zoukankan      html  css  js  c++  java
  • Maven:学习笔记

    Maven 是一个跨平台的项目管理工具,主要服务于基于 Java 平台的项目构建、依赖管理和项目信息管理。

    坐标

    Maven 定义了这样这样一组规则:世界上任何一个构件都可以用 Maven 坐标唯一标识,Maven 坐标元素包括:

    • groupId
    • artifactId
    • version
    • packaging
    • classifier

    我们自己开发的项目也要为其定义适当的坐标,这是 Maven 强制要求的,在这个基础上,其他 Maven 项目可以应用此项目生成的构件。

    依赖

    当我们的项目要用依赖别的构件时,需要添加依赖申明,一个依赖申明包含如下元素:

    • groupId artifactId version 依赖的基本坐标
    • type 依赖的类型,对应项目坐标定义的 packaging,一般不必申明,缺省值 jar
    • scope 依赖范围
    • optional 标记依赖是否可选
    • exclusions 用来排除传递性依赖

    Maven 项目生命周期中有三套 classpath (classpath 是指 JVM 的一个环境变量,用来指示 JVM 如何搜索 class), 分别是 编译 测试 运行。而上面的 scope 则指定了当前构件的依赖范围,scope 值有如下几个:

    • compile 对编译 测试 运行三个 classpath 均有效,如果没有指定,就会使用此值
    • test 仅对测试有效
    • provided 对编译和测试有效,运行时无效
    • runtime 对测试运行有效,编译时无效
    • system 对编译和测试有效,运行时无效,需通过 systemPath 元素显式指定依赖文件路径
    • import 不会对三种 classpath 产生实际影响

    依赖传递

    假设 A 依赖与于 B,B 依赖于 C,我们说 A 对于 B 是第一直接依赖,B 对于 C 是第二直接依赖,A 对于 C 是传递性依赖。第一依赖范围和第二依赖范围决定了依赖传递的范围。

    下表 左边第一行表示第一直接依赖范围,最上面一行表示第二直接依赖范围。

    依赖传递可以参考上图。

    依赖调解

    项目 A 有这样的依赖关系:A - B - C - X(1.0)  A - D - X(2.0),其中 X 是 A 的传递性依赖,但是两条依赖路径上有两个版本的 X,那么哪个版本的 X 会被 A 依赖呢?Maven依赖调解 dependency mdeiation 的第一原则是:路径最近者优先。因此上例中 X(2.0)会被依赖。依赖调解的第二原则:路径相同时,第一声明者优先。

    生命周期

    Maven 的生命周期就是为了对所有的构建过程进行抽象和统一。Maven 从大量项目和构建工具中进行学习和反思,总结了一套高度完善易于扩展的生命周期。Maven 生命周期是抽象的,这意味着生命周期本身不做任何实际的工作。在 Maven 的设计中,实际工作都交由插件来完成。

    Maven 有三套相互独立的生命周期,分别是:

    • clean 清理项目
    • default 构建项目
    • site 建立项目站点

    每个生命周期包含一些阶段 phase,这些阶段是有顺序的,并且后面的阶段依赖前面的阶段。用户和 Maven 最直接的交互方式就是条用这些生命周期的阶段。较之于阶段的前后依赖关系,三套生命周期之间是相互独立的。详细可以参考官方文档中的内容。

    插件

    Maven 生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件目标 plugin goal 相互绑定,以完成某个具体的构建任务。插件目标 plugin goal 是指用户通过命令行输入的指令,可以调用插件中的某个功能。例如 compiler:compile 是调用插件 maven-compiler-plugin 的 compile 目标。

    例如这个命令 mvn dependency:tree

    上面命令的完整写法是 mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:tree 这样插件的 groupId artifactId version goal 都被清晰的描述了。之所以有简单的写法,是因为 Maven 引入了前缀的概念,dependency 是 maven-dependency-plugin 的前缀,也就是插件的简易别名。有了插件前缀,Maven 就能找到对应的 artifactId。

    插件设置前缀的规则如下:

    • maven-${prefix}-plugin 官方插件
    • ${prefix}-maven-plugin 第三方插件

    为了让用户不做任何配置就能构建项目,Maven 为一些主要的生命周期阶段绑定了很多插件目标。 完成了插件和生命周期的绑定之后,用户还可以配置插件目标的参数,用户可以通过命令行或 POM 配置等方式来配置这些参数。在命令行中,用户可以使用 -D 参数,并伴随着一个参数键 = 参数值的形式,来配置插件目标的参数。

    聚合和继承

    一个常见的需求,我们会想要一次构建两个项目,而不是到两个模块目录下分别执行 mvn 命令。Maven 聚合这一特性就是就是为该需求服务的。对聚合模块来说,其打包方式 packaging 必须为 pom。为了方便用户构建项目,通常将聚合模块放在项目目录的最顶层,其他模块则作为聚合模块的子目录存在。

    POM 有一种父子结构,在父 POM 中声明一些配置供子 POM 使用,以实现一处声明,处处使用的目的,这就是 Maven 中的继承关系。

    Maven 提供的 dependencyManagement 元素下声明的依赖不会引入实际的依赖,但是只要子模块配置了 groupId artifactId 就能获得对应的依赖信息,从而引入正确的依赖。当依赖在父 POM 中声明版本后,子模块使用依赖时无须声明版本。

    在现有的实际项目中,往往会发现一个 POM 既是聚合 POM,又是父 POM。

    聚合和继承的区别:聚合是为了方便快速构建项目,继承是为了消除重复配置 

    参考:

    1 Maven实战 一书

    2 生命周期和阶段 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference

    3 插件前缀 http://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html

  • 相关阅读:
    阅读笔记06
    阅读笔记05
    学习进度03
    四则运算03
    阅读笔记04
    求最大子数组值(有环版)
    合作项目02
    新的小组信息以及项目名称与介绍
    第六周进度条
    软件工程个人作业4(课堂练习&&课堂作业)
  • 原文地址:https://www.cnblogs.com/colin220/p/12845480.html
Copyright © 2011-2022 走看看