• Maven 的插件和生命周期的绑定


    一、Maven 的生命周期

    Maven 的生命周期是对所有的构建过程进行抽象和统一。Maven 的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,生命周期只是定义了一系列的阶段,并确定这些阶段的执行顺序。

    Maven 有三套相互独立的生命周期,分别是 clean、default和 site。生命周期( lifecycle )由多个阶段( phase )组成,每个阶段( phase )会挂接一到多个goal。Goal 是 maven 里定义任务的最小单元,如下表:

    生命周期( Lifecycle )

    阶段( Phase )

    目标( Goa l)

    clean

    clean

    maven-clean-plugin:clean

    default

    process-resources

    maven-resources-plugin:resources

    compile

    maven-compiler-plugin:compile

    generate-test-resources

    maven-resources-plugin:testResouces

    test-compile

    maven-compiler-plugin:testCompile

    test

    maven-surefire-plugin:test

    package

    打包类型是jar时:maven-jar-plugin:jar;

    打包类型是war时:maven-war-plugin:war

    install

    maven-install-plugin:install

    deploy

    maven-deploy-plugin:deploy

    site

    site

    maven-site-plugin:site

    site-deploy

    maven-site-plugin:deploy

    二、 Maven 插件和生命周期的绑定

    Maven 的插件位于 ${REPOSITORY_HOME}orgapachemavenplugins 。用户和 Maven 最直接的交互方式就是调用这些生命周期阶段,而在执行这些阶段时,实际的任务主要由插件来完成。
    1. 以 Phase 为目标的构建
      以 phase 为目标进行构建是最常见的,如我们平时经常执行的 mvn compile,mvn test,mvn package...等等, compile, test, package 都是 maven 生命周期( lifecycle )里的 phase,通过 mvn 命令,你可以指定一次构建执行到哪一个阶段,在执行过程中,所有经历到的执行阶段( phase )上绑定的 goal 都将得到执行。例如,对于一个jar包应用,当执行mvn package命令时,maven 从 validate 阶段一个阶段到一个阶段的执行,在执行到 compile 阶段时,compiler 插件的 compile goal 会被执行,因为这个 goal 是绑定在compile阶段( phase )上的。这一点可从其对应的 mojo 类上得知:

      再比如经常使用的打包插件 shade,它的 goal 是绑定到package阶段的,这样,使用 mvn package 进行打包时都会执行 shade 的。
    2. 以 Goal 为目标的构建
      虽然以 phase 为目标的构建最常见,但是有时候我们会发现,一些插件的 goal 并不适合绑定到任何阶段( phase )上,或者是这些 goal 往往是单独执行,不需要同某个阶段( phase )绑定在一起,比如 jetty(6.1.26)插件,它的 goal 都是将打包或未打包的工程部署到 jetty 里然后启动 jetty 容器的,多数情况下,人们都是独立运行这些goal的,比如:人们希望当键入 mvn jetty:run 后,工程就能完成编译后启动 jetty。而 jetty 插件也确实是这样做的,它的 run goal 的 mojo 是这样声明的:

      其中 @execute phase="test-compile" 指明 jetty:run 这一 goal 会促使 maven 先 build 到 test-compile 阶段,再执行这个 goal。同样,对于 jetty:run-war 这个goal 则要求先 build 到 package 阶段再执行该 goal。

      而另外一个例子是exec插件的exec:java.

      这个 goal 也声明了 execute 的 phase,但却是 validate,这样,如果代码没有编译,执行这个 goal 就会出错,所以多数情况下,人们总是使用下面的方式执行的:mvn clean compile exec:java
      Maven 支持这种方式是因为有些任务不适合绑定到生命周期上。
      在命令行调用插件的格式如下:
        mvn groupId:artifactId:version:goal
      其中 groupId、artifactId、version 共同表示了插件的坐标,goal 则表示插件目标的方法。
      但我们看到很多执行插件目标的格式与之并不相符,例如文章开头的 mvn jetty:run,jetty并不是 groupId、artifactId或version 而是插件的前缀,这就有了第二种调用插件的格式:
        mvn 前缀:goal

      Maven 通过查询插件仓库的元数据才得知插件前缀对应插件的 groupId、artifactId,而如果插件是Maven的核心插件则在超级POM中已经定义了插件的版本,如果不是核心插件,则默认取最新的release版本 。
      Maven的插件仓库默认是 http://repo1.maven.org/maven2/org/apache/maven/plugins/ 和 http://repository.codehaus.org/org/codehaus/mojo/,相应的查询插件仓库元数据时会默认使用 org.apache.maven.plugins 和 org.codehaus.mojo 两个 groupId。但也可以通过配置 settings.xml 让Maven检查其他 groupId 上的插件仓库元数据,如:

      <settings>    
          <pluginGroups>
              <pluginGroup>com.your.plugins</pluginGroup>
          </pluginGroups>
      </settings>

      这样配置后,Maven就不只检查 org/apache/maven/plugins/maven-metadata.xml 和 org/codehaus/mojo/maven-metadata.xml,还会检查com/your/plugins/maven-metadata.xml

    3. 相关配置实例
      如果我们想在 test 阶段只执行单元测试,而在 integration-test 阶段进行集成测试的话,可以如下配置:
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.10</version>
          <configuration>
              <skip>true</skip>
          </configuration>
          <executions>
              <execution>
                  <id>run-test</id>
                  <phase>test</phase>
                  <goals>
                      <goal>test</goal>
                  </goals>
                  <configuration>
                      <skip>false</skip>
                      <includes>
                          <include>**/unit/**/*.java</include>
                      </includes>
                  </configuration>
              </execution>
              <execution>
                  <id>run-integration-test</id>
                  <phase>integration-test</phase>
                  <goals>
                      <goal>test</goal>
                  </goals>
                  <configuration>
                      <skip>false</skip>
                      <includes>
                          <include>**/integration/**/*.java</include>
                      </includes>
                  </configuration>
              </execution>
          </executions>
      </plugin>

      其中红色背景的 <skip>true</skip> 是为了让 Maven 的默认绑定(test阶段<-> maven-surefire-plugin:test 插件目标) 无效 (其实绑定仍然有效,只是执行时忽略执行罢了),而后面的 executions 块内容则增加了两个绑定,分别将 maven-surefire-plugin:test 插件目标绑定到 test 阶段和 integration-test 阶段,只是配置不一样了,分别执行unit包和integration包下的测试类。

    三、参考文档

  • 相关阅读:
    java开发中的常见类和对象-建议阅读时间3分钟
    周末学习-泛型-就是传入什么类型就是什么类型-花了一个半小时
    实习第二天-String对象的不可变性-未解决
    实习第二天-java参数传递-精华在文章最后2句话
    实习第二天-对象-对象引用-引用变量-精-精-精-下雨天
    实习第一天:try和catch的使用
    实习第二天-今年第一场雨-方法的重载(马上想到println()函数和abs(函数))
    实习第一周第一天:接口 extends是继承类,implement是实现接口,原接口里面的方法填充,方法名也是不变,重写override是父类的方法名不变,把方法体给改了
    实习第一天:static 声明的 变量和 方法
    JavaWeb学习总结(二)-修改Tomcat服务器的端口(半年之后再总结)
  • 原文地址:https://www.cnblogs.com/tannerBG/p/4235410.html
Copyright © 2020-2023  润新知