Maven 基础

博文目录


Maven 官方入门指南
Maven 官方插件配置指南
Maven 官方pom.xml 指南
Maven 官方所有可用插件

Maven

Maven 是一个项目管理工具,它在非常高的层次上规范了一套项目管理的标准流程,包括但不限于项目的创建、构建、测试、打包、分发、记录和部署等阶段,同时上述的每一个步骤都可以在一个定义良好的范围内拥有无限的变化。而开发人员在了解过 Maven 的工作原理后,即可快速上手任何遵循 Maven 规范的项目,省时省力

基础概念

生命周期 - Build Lifecycle

Maven 的核心概念是围绕着 build lifecycle 的,这意味着项目的构建和分发等过程都是被明确定义的。Maven 有三个内置的生命周期

  • clean:负责处理项目清理
  • default:负责将源码构建成最终包并复制到远程存储库(如公司内网的 Maven 仓库)
  • site:负责处理创建项目的网站

每个生命周期都由多个阶段 Phases 组成

阶段 - Build Phase

每一个生命周期都由不同的阶段所定义,其中的阶段表示生命周期的一个步骤

这些阶段是有固定执行顺序的,每次执行都是从该生命周期的第一个阶段开始,直到到达指定的阶段才会停止

每个生命周期有都有多个阶段,但一般我们只需要关注其最重要的几个阶段即可,3个生命周期的完整的阶段可参考 这里

  • clean lifecycle

    • clean:删除由以前的生成生成生成的所有文件
  • default lifecycle

    • compile:编译项目的源代码
    • test:使用合适的单元测试框架测试编译的源代码。这些测试不应该要求打包或部署代码
    • package:将编译后的代码打包为可分发的格式,例如 JAR
    • install:将软件包安装到本地存储库中,以便在本地其他项目中用作依赖项
    • deploy:将最终包复制到远程存储库,是 default 生命周期的最终目标

目标 - Plugin goals

目标是由 插件 Plugin 提供的

每一个阶段都由多个目标组成,一个目标代表一个特定的任务(比阶段更精细)

一个目标可能被绑定到零个或多个阶段,未绑定到阶段的目标可以通过直接调用,从而在生命周期外执行

目标的执行顺序取决于目标和阶段被调用的顺序,如下命令中,clean 和 package 是阶段,而 dependency:copy-dependencies 是一个插件的目标

mvn clean dependency:copy-dependencies package

如果要执行此操作,则将首先执行clean阶段(这意味着它将运行c lean 生命周期的所有先前阶段,加上clean阶段本身),然后执行 dependency:copy-dependences 目标,最后执行 package 阶段(以及 default 生命周期的其他所有前置构建阶段)

此外,如果一个目标绑定到一个或多个构建阶段,那么该目标将在所有这些阶段中被调用

此外,构建阶段也可以绑定零个或多个目标。如果构建阶段没有绑定目标,则该构建阶段将不会执行。但如果它有一个或多个目标,它就会执行所有这些目标

默认目标绑定

完整的默认绑定关系看 这里

Clean 生命周期
Phaseplugin:goal
cleanclean:clean
Default 生命周期

Default 生命周期的默认绑定,与 POM 的 packaging 元素有关系,packaging 的值最常见的有 pom,jar,war 等,如果没有指定该元素,则默认为 jar

每一种 packaging 都默认包含了多个绑定到 default 生命周期中的多个阶段的目标,如果是 jar / war

阶段绑定到该阶段的插件目标 plugin:goal
process-resourcesresources:resources
compilecompiler:compile
process-test-resouecesresources:testResources
test-compilecompiler:testCompile
testsurefire:test
packagejar:jar 或 war:war
installinstall:install
deploydeploy:deploy

如果 packaging 为 jar 的项目执行 mvn package,则默认会执行上述 install 之前的全部阶段的目标

如果是 pom

Phaseplugin:goal
package
installinstall:install
deploydeploy:deploy
Site 生命周期
Phaseplugin:goal
sitesite:site
site-deploysite:deploy

插件 - Plugin

插件是为 Maven 提供目标的组件,一个插件可以有一个或多个目标,其中每个目标都代表该插件的一种能力,如编译插件 Compiler Plugin 有两个目标,分别是 compile 和 testCompile,分别用来编译主代码的源码和测试代码的源码

插件需要配置目标与生命周期阶段的绑定。单独添加插件是不够的,您还必须指定运行的目标

如果一个阶段配置了多个目标,则优先运行绑定到 packaging 的默认目标,然后才是 POM 中配置的目标(按配置顺序执行),可以用 <executions> 元素做更多顺序的配置

配置举例

Modello 插件默认情况下绑定其目标 modello:java 到 generate-sources 阶段,要使用该插件并让它从模型中生成源代码并将其纳入到构建流程中,可以在的部分将以下内容添加到 POM 中。(这里我有点疑惑,我觉得默认目标和默认阶段应该都不需要额外写出来)

<plugin>
   <groupId>org.codehaus.modello</groupId>
   <artifactId>modello-maven-plugin</artifactId>
   <version>1.8.1</version>
   <executions>
     <execution>
       <configuration>
         <models>
           <model>src/main/mdo/maven.mdo</model>
         </models>
         <version>4.0.0</version>
       </configuration>
       <goals>
         <goal>java</goal>
       </goals>
     </execution>
   </executions>
 </plugin>

有些目标能用在不止一个阶段,假设你有一个目标 display:time 用于在命令行中输出时间,你想将其绑定到 process-test-resources 阶段,那么可以做如下配置,支持同时配置多个 <execution>

<plugin>
   <groupId>com.mycompany.example</groupId>
   <artifactId>display-maven-plugin</artifactId>
   <version>1.0</version>
   <executions>
     <execution>
       <phase>process-test-resources</phase>
       <goals>
         <goal>time</goal>
       </goals>
     </execution>
   </executions>
 </plugin>

如果插件没有写版本号,则默认是使用最新的可用版本

POM(Project Object Model)

完整文档看 这里

项目对象模型或POM是Maven中的基本工作单元。它是一个XML文件,包含有关项目的信息以及Maven用于构建项目的配置详细信息。它包含大多数项目的默认值,如 构建目录是 target,源码目录是 src/main/java,测试源码目录是 src/test/java,等等。

当执行任务或目标时,Maven会在当前目录中查找POM。它读取POM,获得所需的配置信息,然后执行目标。

POM中可以指定的一些配置包括项目依赖项、可以执行的插件或目标、构建配置文件等。还可以指定其他信息,如项目版本、描述、开发人员、邮件列表等。

Super POM

Super POM 是 Maven 的默认 POM。除非明确设置,否则所有 POM 都会扩展超级 POM,Super POM 中指定的配置将由您为项目创建的 POM 继承。

Maven 3.6.3 的 Super POM 内容看 这里,定义了很多默认路径和默认仓库的信息,依赖的默认下载路径 https://repo.maven.apache.org/maven2

项目继承 - Project Inheritance

以下的元素会因为继承而合并

  • dependencies
  • developers and contributors
  • plugin lists (including reports)
  • plugin executions with matching ids
  • plugin configuration
  • resources

子 POM 可以继承父 POM 的 GroupID 和 Version

项目聚合 - Project Aggregation

其实就是多模块 Maven 项目

项目聚合类似于项目继承。但是,它不是从模块中指定父POM,而是从父POM中指定模块。通过这样做,父项目现在知道了它的模块,如果对父项目调用Maven命令,那么该Maven命令也将对父项目的模块执行。要进行项目聚合,必须执行以下操作:

  • 将父pom包装更改为值“pom”。
  • 在父POM中指定其模块(子POM)的目录。

每当Maven命令处理父 POM 时,同样的Maven命令也会针对子 POM 运行。有些命令(特别是目标)对项目聚合的处理方式不同。

依赖机制 - Dependency Mechanism

完整参考查看 这里

依赖关系管理是Maven的核心功能。管理单个项目的依赖关系很容易。管理由数百个模块组成的多模块项目和应用程序的依赖关系是可能的。Maven在定义、创建和维护具有定义良好的类路径和库版本的可复制构建方面有很大帮助。

依赖传递 - Transitive Dependencies

有一个包 C 依赖 了 D 和 E 包,你依赖了 C,则自动依赖了 D 和 E,这就是依赖传递

依赖仲裁 - Dependency mediation

  • 就近原则:依赖冲突时,所使用的依赖版本将是依赖关系树中与您的项目最接近的版本(依赖深度最浅),假如你的项目是 A,A>B>C>D:2.0,A>E>D:1.0,此时 D:1.0 离 A 更近,所以根据就近原则,1.0 版本的 D 被选择为生效的版本,如果想使用 2.0 版本的 D,则可以在 A 中直接添加该版本的依赖,或者在 E 中排除对 D 的依赖
  • 如果两个冲突依赖的深度相同,则先声明的生效

依赖作用域 - Dependency Scope

依赖作用域用于限制依赖的传递性,并确定依赖何时包含在类路径(compile、test、runtime)中,有 6 种依赖作用域

  • compile:默认作用域。该作用域的依赖项在项目的所有类路径中都可用。这些依赖关系会传播到依赖项目
  • provided:该作用域的依赖项会被添加到 compile 和 test 类路径中,但不会添加到 runtime 的类路径中。这种作用域的依赖项不会传递。如 JavaEE Web 应用,需要添加 provided 范围的 Servlet 依赖,因为 Web 容器提供了这些类
  • runtime:表示编译时不需要这个依赖,但执行时需要。该作用域的依赖项会被添加到 runtime 和 test 类路径中,但不会添加到 compile 的类路径中
  • test:表示应用在正常运行时并不会需要这个依赖,它只生效于测试的编译和执行阶段。此作用域不可传递
  • system:表示此依赖从指定的目录查找,而不是本地仓库
  • import:此作用域只在 pom<dependencyManagement> 中生效,

插件 - Plugin

完整文档看 这里

如果没有配置版本号,默认是使用最新的可用版本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值