Maven的生命周期和插件

1、生命周期

​ 这里的生命周期就是项目的生命周期,如果没有maven我们要对项目进行测试需要的流程就是清理、编译、测试、部署;这一系列每天重复的工作,被maven进行了抽象形成了maven的生命周期,包括清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成。它能够胜任几乎任何种类的项目构建。

​ 由于maven生命周期是抽象的,所以它不会有任何实际的操作(因为它不知道会面对什么项目),故而采取了一种非常类似于模板方法的设计模式,它只是定义了这些模板方法(也就是生命周期),且规定了顺序,但实际的实现却交给插件去做,也就是将插件绑定在不同的构建步骤上,在进行到这个步骤时,执行这个插件。例如针对编译的插件有maven-compiler-plugin 针对测试的有maven-surefire-plugin

2、三套生命周期

maven的生命周期不是一个整体,有三套相互独立的生命周期 clean、default、site。其中clean生命周期的目的是清理项目,default是构建项目,site是建立项目站点。每个生命周期都有自己的一些阶段(phase)。

  • clean生命周期

    • pre-clean 执行一些清理前需要完成的工作
    • clean 清理行一次构建生成的文件
    • post-clean 执行一些清理后需要完成的工作
  • default生命周期

    真正执行构建时所执行的所有步骤。

    • validate
    • initialize
    • generate-sources 处理项目主资源文件,也就是src/main/resources下的东西,如进行变量替换
    • process-sources
    • generate-resources
    • process-resources
    • compile 编译项目主源码,也就是src/main/java下的java文件到classpath目录
    • process-classes
    • generate-test-sources
    • process-test-sources 处理项目测试资源文件,如 src/test/resources
    • generate-test-resources
    • process-test-resources
    • test-compile 编译测试代码,如src/test/java
    • process-test-class
    • test 使用单元测试框架,进行单元测试
    • prepare-package
    • package 使用编译好的代码,打包
    • pre-integration-test
    • post-integration-test
    • verify
    • install 安装到本地仓库
    • deploy 部署到远程仓库
  • site生命周期

    site生命周期的目的时建立和发布项目站点

    • pre-site 执行一些在胜场项目站点之前需要完成的工作
    • site 生成项目站点文档
    • post-site 执行一些在生成项目站点之后需要完成的工作
    • site-deploy 将生成的项目站点发布到服务器

3、命令行和生命周期

虽然三个生命周期的阶段是相互独立的,但是同一个生命周期内的各个阶段是由前置依赖关系的。

  • maven clean

    调用clean生命周期内的clean阶段,由于依赖关系所以实际执行了pre-clean和clean这两个阶段

  • mvn test

    调用default生命周期内的test阶段,所以之前的初始化、处理resources、编译代码等都会执行一遍。注意由于和clean生命周期独立,所以不会执行clean工作。

  • maven clean install

    执行clean生命周期的前两个阶段然后再执行default生命周期的validate到install的所有阶段

4、插件目标和插件绑定

像是一开始说的,maven的生命周期只是一个声明,并没实际的具体实现,像是模板方法一样,而插件准确点来说插件目标则是对应的子类模板方法实现。那么什么是插件目标?

插件目标(goal),一个插件可能会包含很多功能,如果每个功能都单独拎出来做成一个插件是不可取的,因为会重复很多不必要的代码。所以一个插件提供的不同功能,就叫做插件目标(真拗口);

插件绑定,插件目标想要起作用就需要绑定到生命周期内的指定阶段(phase)上,这样在进行到指定的生命周期阶段时就会执行插件目标的功能。例如default生命周期内的compile阶段上默认绑定了maven-compliler-plugin插件的compile目标。

内置绑定,由于maven是开箱即用的,所以一开始不会让我们为一个个的生命周期阶段配置指定的插件目标,它默认绑定了一些,如clean生命周期下的clean阶段默认绑定了maven-clean0plugin的clean目标等。

由于不同的打包类型会影响生命周期阶段和插件目标的绑定关系,下面罗列了jar包时的default生命周期的绑定;

5、自定义绑定

想都不用想肯定支持自定义绑定啊,就是把一个插件内的插件目标绑定到指定生命周期的指定阶段上。下面演示一个生成源码的自定义绑定;

<project>
  <build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>3.0.1</version>
        <configuration>
        	<attach>true</attach>
        </configuration>
				<!--一个executions下的一个execution可以配置一个任务,即绑定插件-->
        <executions>
          <execution>
						<!--绑定到default生命周期下的compile阶段-->
						<!--也可以不用指定阶段,删除下面这行配置也能正常工作,因为插件目标设置了默认绑定阶段-->
            <phase>compile</phase>
						<!--在这个阶段上可以配置多个目标-->
            <goals>
							<!--绑定一个jar目标,当执行到compile阶段时会生成一个xxx-source.jar源码包-->
							<!--或者直接执行mvn compile 也能在target目录下看到这个源码包-->
              <goal>jar</goal>
            </goals>
           </execution>
         </executions>
			</plugin>
		</plugins>
  </build>
</project>

Q.E.D.