maven浅谈之生命周期和插件目标

一、简介

maven本质就是插件的集合,我们执行的命令都是多个插件目标协作完成的。例如我们执行mvn compile其实就是在执行maven-compiler-plugin在compile目标。

二、插件目标

插件目标,maven有很多插件,每个插件都有很多功能,可以理解为是这个插件的功能,底层都是用代码实现的。下面说几个重要的插件目标。(以后插件目标都简写成插件:目标

  • maven-compiler-plugin有两个重要的插件目标compile和test-compile,分别作用于编译和测试代码的编译。(compile:compile和compile:test-compile)
  • surefire:test(maven-surefire-plugin:test)执行测试用例
  • assembly:single(maven-assembly-plugin:single)个性的打包插件
  • jar:jar(maven-jar-plugin:jar)打成一个可执行的jar包
  • shade:shade(maven-shade-plugin:shade) 打成一个包含依赖的可执行jar包
  • dependency:tree 获取依赖树
  • clean:clean (maven-clean-plugin)清理工程

其实我们执行的mvn命令就是在执行插件目标,比如mvn compile等同于mvn compile:compile;mvn test等同于mvn surefire:test。

三、生命周期

mvn的每个命令都是生命周期的一个阶段,例如我们常常执行的命令mvn clean package,就是在执行clean生命周期阶段和默认生命周期从validatepackage依次执行。

3.1 clean生命周期

clean生命周期是独立的生命周期,它内部包含了三个阶段

  • pre-clean:清理以前的任务
  • clean:清理
  • post-clean:清理之后的任务
  <plugin>
      <artifactId>maven-clean-plugin</artifactId>
      <version>3.1.0</version>
      <executions>
          <execution>
              <id>auto-clean</id>
              <phase>initialize</phase>
              <goals>
                  <goal>clean</goal>
              </goals>
              <configuration>
                  <filesets>
                      <fileset>
                          <directory>target-other</directory>
                          <includes>
                              <include>*.class</include>
                          </includes>
                      </fileset>
                  </filesets>
              </configuration>
          </execution>
      </executions>
  </plugin>

上例就是告诉maven-clean-plugin插件在initialize生命周期阶段执行clean目标,删除target-other目录下所有的class文件。

3.2 默认生命周期

mvn有一套默认的生命周期,他有各个生命周期阶段。比如compile、test、package、install等,下面说下各个默认的生命周期阶段。

  1. validate 验证项目是否正确
  2. generate-sources 生成所有需要包含在编译过程中的源代码
  3. process-sources 处理源代码,比如过滤一些值
  4. generate-resources 生成所有需要包含在打包过程中的资源文件
  5. process-resources 复制并处理资源文件至目标目录 (src/main/resources/ -> target/classes/)
  6. compile 编译项目的源代码
  7. process-classes 后处理编译生成的文件
  8. generate-test-sources 生成所有包含在测试编译过程中的测试源码
  9. process-test-sources 处理测试源码
  10. generate-test-resources 生成测试需要的资源文件
  11. process-test-resources 复制并处理测试资源文件至测试目标目录
  12. test-compile 编译测试源码至测试目标目录
  13. test 使用合适的单元测试框架运行测试。
  14. prepare-package 在真正的打包之前,执行一些准备打包必要的操作。
  15. package 将编译好的代码打包成可分发的格式,如JAR,WAR,或者EAR
  16. pre-integration-test 执行一些在集成测试运行之前需要的动作
  17. integration-test 处理包并发布至集成测试可以运行的环境
  18. post-integration-test 执行一些在集成测试运行之后需要的动作
  19. verify 执行所有检查,验证包是有效的,符合质量规范
  20. install 安装包至本地仓库,以备本地的其它项目作为依赖使用
  21. deploy 复制最终的包至远程仓库,共享给其它开发人员和项目

注意:通过上述描述我们可以发现什么问题?
1.clean阶段不在默认的生命周期中,所以我们要使用clean都要是显示声明使用,例如mvn clean package
2.更高级的生命周期阶段是包含低级的生命周期阶段的,而且在执行过程中如果中间的一个阶段失败,j就会导致整个构建失败
2.1.所以我们有时候直接运行mvn install就直接有生成包了,因为install高于package,在执行install之间会执行package
2.2.所以当我们的不跳过测试用例,而测试用例有失败的时候,整个构建失败 mvn package -DskipTests
3.test阶段高于compile阶段,所以执行test的时候,一定要编译,但是编译不会执行测试用例 (生成test-classes目录(存放测试用例的编译类))
4.这就是为什么我们在pom中没有配置任何插件,直接mvn package也是可以打包的原因,因为他们都会有默认的插件目标

3.3 打包类型和生命周期阶段的关系

我们知道我们常用的打包类型有jarwarpom。但是我们只是在pom文件中设置了打包类型,但是它到底是怎么生成包的呢?
因为每个打包类型都默认设置了对应的生命周期阶段,下面列出他们的默认生命周期阶段和对应的插件目标。

上面也说了,
1、我们执行的命令其实在底层都是执行插件目标。
2、各个插件目标可以绑定到特定的生命周期阶段。

3.3.1 jar默认的生命周期阶段

下面是打包类型为jar默认的生命周期阶段:(序号.生命周期阶段,插件目标)
1.process-resources,resources:resources
2.compile ,compiler:compile
3.process-test-resources,resources:testResource
4.test-compile,compiler:testCompile
5.test,surefire:test
6.package,jar:jar
7.install,install:install
8.deploy,deploy:deploy

3.3.2 pom默认的生命周期阶段

下面是打包类型为pom默认的生命周期阶段:(序号 生命周期阶段,插件目标)
1.package,site:attach-descriptor
2.install,install:install
3.deploy,deploy:deploy

3.3.3 war默认的生命周期阶段

下面是打包类型为war默认的生命周期阶段:(序号 生命周期阶段,插件目标)
1.process-resources,resources:resources
2.compile,compiler:compile
3.process-test-resources,resources:testResources
4.test-compile,compiler:testCompile
5.test,surefire:test
6.package,war:war
7.install,install:install
8.deploy,deploy:deploy

3.4 生命周期阶段和默认的插件目标

我们知道mvn就是执行各个插件目标的集合,例如我们执行生命周期各个阶段其实就是执行绑定在各个生命周期阶段的插件目标,所以插件目标是mvn的基础。上一小结其实已经列出生命周期阶段和对应的插件目标,这里具体说下。

3.4.1 rocess-resources阶段和resources:resources

process-resources生命周期阶段阶段其对应的插件目标是:resources:resources,功能是把资源文件复制到输出目录( src/main/resources/ -> target/classes/) (同样process-test-resources同理)
主要的作用:1.把资源文件复制到特定的输出目录

<resource>
    <directory>src/main/xml</directory>
</resource>
<resource>
    <directory>src/main/images</directory>
</resource>

2.属性替代,定义公共属性,可以在其他文件引入属性的值(例如password等),需指定两个事:构建配置的filters元素中的属性文件列表,以及一个标记告诉Maven特定的资源目录需要过滤。
下面的例子:定义default.properties为过滤文件(可以理解为其他文件要经过该文档过滤),src/main/resources中的文件可以使用default.properties定义的属性值
例如default.properties如下

password=123456

src/main/resources下有文件prod.properties

pw=${password}

最终打出的prod.properties

pw=123456
<build>
    <filters>
        <filter>src/main/filters/default.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
3.4.2 compile阶段和插件目标是compile:compile

compile阶段对应的插件目标是compile:compile,功能是编译所有的源码并复制到构建输出目录中。 (同样test-compile同理)
我们要定义compile编译的java版本等,可以下面操作

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
    </configuration>
</plugin>

注意上面的定义是对整个compiler插件设置,不是仅仅对compile:compile设置。因为compiler插件设置的范围肯定大于compile:compile设置的,比如compiler插件还包括compile:test-compiletest-compile生命周期阶段)。
上面设置的好处是,整个插件都应用相同的配置,避免测试的时候还有单独设置compile:test-compile的source和target
如果想单独设置compile:compile呢(其实几乎不会存在这种情况)可以像下面配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </execution>
    </executions>
</plugin>
3.4.3 test阶段和插件目标是surefire:test

test阶段对应的插件目标是surefire:test,功能是:寻找测试源码目录下所有以*Test结尾的类进行单元测试。通常单元测试失败会导致整个构建失败,可以指定如果遇到失败是否继续构建
maven-surefire-plugin是管理测试生命周期的插件:比如我们常用的-Dmaven.test.skip=true 就是告诉该插件跳过所有的测试用例
也可以把该插件配置到pom文件中,这样就可以不用写上面的参数了

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <skip>true</skip>  跳过测试用例
        <testFailureIgnore>true</testFailureIgnore>   测试用例失败继续执行
    </configuration>
</plugin>

4.install阶段对应的插件目标是install:install功能是把生成的目标导入本地仓库中
5.deploy阶段对应的插件目标是deploy:deploy功能是把生成的目标导入远程仓库中,通常需要验证信息等(一般放入setting.xml中)。
6.package阶段是很特殊的,因为不同的打包类型配置的默认的插件目标是不同的,例如jar包对应的插件目标是jar:jarwar包对应的插件目标是war:war,同时也有很多的插件目标都绑定到package,例如maven-shade-plugin:shademaven-assembly-plugin:single

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值