第六节:Maven生命周期和插件

生命周期详解:
     Maven的生命周期就是对 项目构建过程进行的抽象和统一,就是项目构建的流程。但是构建过程中每一步(例如编译源代码)的 实际行为都由插件来完成的。
     Maven的生命周期不是一个整体,它 拥有三套相互独立的生命周期(clean,default,site)而且 每套生命周期下面包含一些阶段这些阶段是有顺序的,并且 同一个生命周期内后面的阶段依赖前面阶段的完成,也就是说当我们调用生命周期内的某个阶段C时,该生命周期内阶段C之前的阶段也会自动执行, 用户对Maven的操作其实就是 调用这些生命周期下的的一个或者多个阶段。以clean生命周期为例,它包含三个阶段:pre-clean,clean,post-clean。当调用clean时,pre-clean,clean阶段会得以顺序执行。
  • clean生命周期:清理项目,下面是它包含的三个阶段
    • pre-clean:执行一些清理前必须完成的工作
    • clean:清理上一次构建生成的文件
    • post-clean:执行一些清理后需要完成的工作
  • default生命周期:构建项目,下面是它包含的几个重要的阶段
    • validate验证工程是否正确,所有需要的资源是否可用。
    • process-resources:复制和处理资源文件到target目录,准备打包。
    • compile:编译项目的源代码。
    • test-compile:编译测试源代码;
    • test:运行测试代码;
    • package:打包成jar或者war或者其他格式的分发包;
    • integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
    • verify运行所有检查,验证包是否有效且达到质量标准。
    • install:将打好的包安装到本地仓库,供其他项目使用;
    • deploy    :将打好的包安装到远程仓库,供其他项目使用;
  • site生命周期:建立项目站点,下面是包含的四个阶段
    • pre-site:生成项目站点之前需要完成的工作
    • site:生成项目的站点文档;
    • post-site:生成项目站点之后需要完成的工作
    • site-deploy:将项目站点发布到服务器
     较之于 生命周期阶段的前后依赖关系,三套 生命周期本身是相互独立的。也就是说: 用户可以仅调用某生命周期的某个阶段,而不会触发其他生命周期或者对其他生命周期有什么影响。例如:用户调用default生命周期的compile阶段,不会触发clean生命周期的任何阶段。
     从命令行执行Maven任务的最主要的方式就是调用Maven的生命周期阶段。下面以一个常见的Maven命令举例:
      $mvn clean install site-deploy: 该命令调用clean生命周期的clean阶段,default生命周期的deploy阶段,以及site生命周期的site-deploy阶段。实际执行的是clean生命周期的pre-clean和clean阶段,default生命周期的install以及其之前的所有阶段,site生命周期的全部阶段。

插件目标:
     前面我们已经知道,Maven核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的。假设我们有三个插件,需要完成的功能分别是:分析项目依赖,列出项目依赖树,列出项目所有已经解析的依赖。因为功能的相似,我们发现这三个插件之间有很多可以复用的代码,所以为每一个功能都写一个独立的插件是不可取的, 于是我们可以把这三个功能聚集在一个插件里,每个功能作为一个插件目标。例如:maven-dependency-plugin插件有十多个目标,每个目标对应了一个功能:dependency:analyze,dependency:tree,dependency:list。 这是一种通用的写法,冒号前面是插件插件前缀,冒号后面是该插件的目标。

插件绑定:
     具体来说,生命周期的阶段与插件互相绑定,以完成某个具体的构建任务。其中Maven默认对生命周期中的各个重要阶段都绑定了很多插件任务。我们调用生命周期阶段的时候,就默认调用了绑定的插件目标。
     下面列出拥有插件绑定关系的阶段,生命周期还有很多其他阶段,默认它们没有绑定任何插件,因此也没有任何实际行为。
  • clean生命周期:清理项目,下面是它包含的三个阶段
    • clean ->> maven-clean-plugin:clean
  • default生命周期:构建项目,下面是它包含的几个重要的阶段
    • process-resources ->> maven-resources-plugin:resources
    • compile ->> maven-compiler-plugin:compile
    • process-test-resources ->> maven-resources-plugin:testResources
    • test-compile ->> maven-compiler-plugin:testCompile
    • test ->> maven-surfire-plugin:test
    • package ->> maven-jar-plugin:jar
    • install ->> maven-install-plugin:install
    • deploy ->> maven-deploy-plugin:deploy
  • site生命周期:建立项目站点,下面是包含的四个阶段
    • site ->> maven-site-plugin:site
    • site-deploy ->> maven-site-plugin:deploy

自定义绑定:
     自定义绑定允许我们将某个插件目标绑定到生命周期的某个阶段上,下面以生成项目主代码的源码jar为例。使用到的插件和他的目标为:maven-source-plugin:jar-no-fork、将其绑定到default生命周期阶段verify上(可以任意指定三套生命周期的任意阶段)、在项目的POM配置中(也可以在父POM中配置、后面聚合与继承会有提到)。 
     上述配置有插件的坐标声明, excutions下面每个excution子元素配置的执行的一个任务通过phase指定与生命周期的那个阶段绑定、在通过goals指定执行绑定插件的哪些目标。当我们执行verify生命周期阶段时,会自动调用
maven-source-plugin: 2.1.1: jar-no-fork( attach-sources )
     当插件的目标绑定到不同的生命周期阶段的时候,插件目标的执行顺序是有生命周期阶段的顺序决定的,当多个插件目标绑定到同一生命周期阶段的时候,顺序是按照插件声明的顺序来决定目标的执行顺序。

命令行插件配置:
     因为通过命令行插件配置,可以 灵活得改变插件的行为,使其更符合需要。
     使用语法:
     maven命令 -D参数=参数值
     例如:maven-surfier-plugin提供了一个maven.test.skip参数,当它为true时,它就会跳过测试。我们运行如下命令:
     $ mvn install -Dmaven.test.skip = true
     maven-surfier-plugin插件是绑定在test阶段的插件,是在install阶段之前被执行的。

POM中插件全局配置:
     对于一些 参数值从项目创建到发布都 不会或者很少会改变的情况,在POM文件中一次性配置显然比每次在命令行输入方便。
     用户可以在 声明插件的时候插件进行一个全局的配置<configuration>,也就是说所有 基于该插件的目标,都会使用这些配置。例如:我们通常会需要配置 maven-compile-plugin告诉它编译Java 1.7版本的源代码,生成与JVM 1.7兼容的字节码文件,这样不管绑定到 compile阶段的maven-compile-plugin:compile任务,还是绑定的到 test-compile阶段的maven-compile-plugin:testCompile任务, 只要使用了该插件,就都能使用该全局配置,基于Java1.7版本进行编译。
           

POM中插件任务配置:
      除了为插件配置全局变量,我们还可以 为某个插件任务配置特定的参数。 以maven-antrun-plugin为例,它有一个目标run,可以用来在Maven中调用Ant任务。用户将maven-antrun-plugin:run 绑定到多个生命周期阶段上,再加以不同的配置,就可以让Maven在不同的生命阶段执行不同的任务,如:
    
在上述代码片段中,首先,maven-antrun-plugin:run 与 validate阶段绑定,从而构成一个id为ant-validate的任务。 插件全局配置中得configuration元素位于plugin元素下面,而这里的configuraction元素则位于execution元素下,表示这是特定任务的配置,而非插件整体的配置。
这个ant-validate任务配置了一个echo Ant任务,向命令行输出一段文字,表示该任务是绑定到validate阶段的。
第二个任务的id为ant-verify,它绑定到了verify阶段,同样它也输出了一段文字到命令行,告诉该任务绑定到了verify阶段。

插件解析机制:
     插件仓库:插件同样基于坐标存储于Maven仓库中,但是Maven区别对待依赖的远程仓库与插件的远程仓库,插件的远程仓库使用pluginRepositories和pluginRepository配置,其他的子元素和依赖远程仓库的配置一样。
     在POM中配置插件的时候,如果插件是Maven的官方插件(即如果其groupie为org.apache.maven.plugins),可以省略groupId的配置。 我们也可以配置自己默认的groupId,在Maven的settings.xml中添加如下内容。
     
     Maven在超级POM中为所有核心插件(maven-clean-plugin,maven-compiler-plugin,maven-surefire-plugin等)设定了版本,当用户使用某个插件没有设定版本而且又不是核心插件时,Maven会合并这个插件在本地仓库和远程仓库的元数据maven-metadata.xml,计算出最新的release版本并使用,但是这存在风险,所以应该显示声明插件版本。
     解析插件前缀:插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中,但与之前 解析版本所用到的groupId/artifactId/maven-metadata.xml不同,这里的 仓库元数据为groupId/maven-metadata.xml(该groupId下所有插件的),且Maven在解析插件仓库元数据的时候,会默认使用org.apache.maven.plugins和org.codehaus.mojo这两个groupId,也可以通过pluginGroup的配置让Maven检查其他groupId上的插件仓库元数据。
     最后用一个例子来总结一下插件的解析机制: mvn compiler:compiler 是怎么解析为一个完整路径的
      1. 先补上被省略的默认的 groupId(也可以由pluginGruop自己配置)—> mvn org.apache.maven.plugins:compile:compile                  
      2.去maven的默认的插件远程仓库下比对元数据, Maven默认的远程仓库是 http://repo.maven.apache.org/maven2/ ,所有插件元数路径则是: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml ,我们找到compiler插件的元数据,如图:
    
这里会根据prefix指定的前缀找到对应的artifactId.  — >  mvn org.apache.maven.plugins: maven-compiler-plugin :compile
     3. 我们再根据groupId和artifactId找到maven-compiler-plugin插件单个的元数据, 路径为 http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml ,如图:
maven将所有的远程插件仓库及本地仓库元数据归并后,就能找到release的版本,最后命令被拓展成了这样:
mvn org.apache.maven.plugins:maven-compiler-plugin:3.0.0:compiler


     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值