• Maven 学习总结 (二) 之 生命周期与插件


    五、生命周期与插件

      1、Maven有三套独立的生命周期:clean、default和site。 clean生命周期的目的是清理项目,default生命周期的目的是构建项目,site生命周期的目的是建立项目站点。

    clean生命周期:pre-clean、clean、post-clean

    default生命周期:validate、initialize、generate-sources、process-sources(处理项目主资源文件,对src/main/rescources目录内容进行变量替换等工作后,复制到项目输出的主classpath)、

            generate-resources、process-resources、compile(编译项目的主源码,编译src/main/java目录下的Java文件至项目输出的主classpath目录中。)process-classes、

            generate-test-sources、process-test-sources(处理项目测试资源文件,对src/test/resources目录的内容进行变量替换等工作后,复制到项目输出的测试classpath目录中。)

            generate-test-resources、 process-test-resources、test-compile(编译项目的测试代码,是编译src/test/java目录下的Java文件至项目的测试classpath目录中)、test、

            prepare-package、package(接受编译好的代码,打包成可发布的格式)、pre-integration-test、integration-test、post-integration-test、verify、install(将包安装到maven

            本地仓库,供其他人和项目使用)、deploy(将最终的包复制到远程仓库,供其他开发人员和项目使用)

    site生命周期:pre-site、site(生成项目站点文档)、post-site、site-deploy(将生成的站点发布到服务器上)。

      2、命令行与生命周期

      从命令行执行maven任务的最主要方式就是调用maven的生命周期阶段。

      mvn clean 调用clean生命周期的clean阶段。

      mvn test 调用default生命周期的test阶段。

      mvn clean install 调用clean生命周期的clean阶段和defaulte生命周期的install阶段。

      mvn clean deploy site-deploy 调用clean的阶段、default生命周期的deploy阶段,以及site生命周期的site-deploy阶段。

           maven中主要的生命周期阶段并不多,而常用的maven命令实际是基于这些阶段简单组合而成的。 

      3、插件目标

      maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的构件形式存在。

      maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体讲是生命周期的阶段与插件的目标相互绑定,以完成某个具体构建任务。

        

      为了能让用户几乎不用任何配置就能构建maven项目,maven在核心为一些主要的生命周期阶段绑定了很多插件目标,当用户通过命令调用生命周期阶段的时候,对应的插件

       目标就会执行相应的任务。

       clean生命周期的pre-clean、clean和post-clean三个阶段,只有clean与maven-clean-plugin:clean绑定。maven-clean-plugin仅有clean这一个目标,其作用是删除项目输出目录。

       site生命周期的pre-site、site、post-site和site-deploy四个阶段,其中,site和maven-site-plugin:site相互绑定,maven-site-plugin有很多目标,其中site目标用来生成项目站点,

            deploy目标用来将项目站点部署到远程服务器上。

                    

       default生命周期与插件目标的绑定关系就显得复杂些。这是因为对于任何项目来说,例如jar项目和war项目,他们的项目清理和站点生成是一样的,不过构建过程会有区别。

            例如jar项目需要打包成JAR包,而war项目需要打成WAR包。由于项目的打包类型会影响构建的具体过程,因此,default生命周期的阶段与插件目标的绑定关系由项目打

       包类型所决定,打包类型是通过POM中的packaging元素定义的。基于打包类型是jar的项目,其default生命周期内置插件绑定关系及具体任务如表:

        

      default生命周期还有很多其他阶段,默认他们没有绑定任何插件,因此也没有任何实际行为。

      4、自定义绑定

     

         除了内置绑定以外,用户还能够自己选择某个插件目标绑定到生命周期的某个阶段上,这种自定义绑定方式能让maven项目在构建过程中执行更多更富特色的任务。

      <build>

        <plugins>

          <plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-source-plugin</artifactId>

            <version>2.1.1</version>

            <executions>

              <execution>

                <id>attched-sources</id>

                <phase>verify</phase>

                <goals>

                  <goal>jar-no-fork</goal>

                </goals>

               </execution>

            </executions>

          </plugin>

        </plugins>

       </build>

      

            在POM的build元素下的plugins子元素中声明插件的使用,该例中用到的是maven-source-plugin,其中groupId为org.apahe.maven.plugins,这是maven官方插件的groupId。

         对于自定义绑定的插件,用户总是应该声明一个非快照版本,这样可以避免由于插件版本变化造成的构建不稳定性。除了基本插件坐标声明外,还有插件执行配置,

            executions下每个execution子元素可以用来配置执行一个任务。该例中配置一个id为attch-sources的任务,通过phase配置,将其绑定到verify生命周期阶段上,再通过goals

       配置指定要执行的插件目标。

         有时候,即使不通过phase元素配置声明周期阶段,插件目标也能够绑定到生命周期中去。原因是,很多插件的目标在编写时已经定义了默认绑定阶段。

       可以使用maven-help-plugin 查看插件详细信息,了解插件目标的默认绑定阶段。

          

      5、插件配置

       完成了插件和生命周期的绑定之后,用户还可以配置插件目标的参数,进一步调整插件目标所执行的任务,以满足项目的需求。

       命令行配置

        在日常maven使用中,我们经常从命令行输入并执行maven命令。这种情况下,能够方便地改变某些插件的行为十分方便。 用户可以在maven命令中使用-D参数,

             并伴随一个参数健=参数值的形式,来配置插件目标的参数。

            $ mvn install-Dmaven.test.skip=true,参数-D是java自带的,其功能是通过命令行设置一个java系统属性,maven简单第重用了该参数,在准备插件的时候检查系统属性,

        便实现了插件参数的配置。

       全局配置:

         并不是所有的插件参数都适合从命令行配置,有些参数的值从项目创建到项目发布都不会改变,或者说很少改变,对于这种情况,POM文件中一次性配置就显然比重复在

       命令行输入要方便。

      <build>

        <plugins>

          <plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-compiler-plugin</artifactId> 

            <version>2.1</version>

            <configuration>

              <source>1.5</source>

              <target>1.5</target>

            </configuration>

          </plugin>

        </plugins>

      </build>

       这样,不管绑定到compile阶段的maven-compiler-plugin:compile任务,还是绑定到test-compiler阶段的maven-compiler-plugin:testCompiler任务,就能够使用该配置,

       基于java1.5版本进行编译。

       POM中插件任务配置:

       除了为插件配置全局参数,用户还可以为某个插件任务配置特定参数,以maven-antrun-plugin,他有一个目标run,可以用来在maven中调用Ant任务。

       用户将maven-antrun-plugin:run绑定到多个生命周期阶段上,再加以不同的配置,就可以让maven在不同的生命阶段执行不同的任务。

       <build>

        <plugins>

          <plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-antrun-plugin</artifactId>

            <version>1.3</version>

            <executions>

              <execution>

                <id>ant-validate</id>

                <phase>validate</phase>

                <goals>

                  <goal>run</goal>

                </goals>

                <configuration>

                  <tasks>

                    <echo>I am bound to validate phase.</echo>

                  </tasks>

                </configuration>

              </execution>

              <execution>

                <id>ant-verify</id>

                <phase>verify</phase>

                <goals>

                  <goal>run</goal>

                </goals>

                <configuration>

                  <tasks>

                    <echo>I am bound to verify phase.</echo>

                  </tasks>

                </configuration>

              </execution>

            </executions>

          </plugin>

        </plugins>

      </build>

      上述代码片段中,首先maven-antrun-plugin:run与validate阶段绑定,从而构成一个id为ant-validate的任务。插件全局配置中的configuration元素位于plugin元素下面,

            而这里的configuration元素则位于execution元素下,表示这是特定任务的配置,而非插件整体的配置。这个ant-validate任务配置了一个echo ant任务,

      向命令行输出一段文字,表示该任务是绑定到validate阶段的。第二 个任务的id为ant-verify,它绑定到了verify阶段,同样她输出一段文字到命令行,

      告诉该任务绑定到了verify阶段。

      获取插件信息:

      插件信息:基本上所有主要的maven插件都来自apache和Codeaus。

      maven-help-plugin描述插件:除了访问在线的插件文档之外,还可以借助maven-help-plugin来获取插件信息。

      从命令行调用插件

      如果在命令行运行mvn-h来显示mvn命令帮助,就可以看到如下信息

      usage:mvn [optiona] [<goal(s)>] [phase(s)] 

      options:

      ...

      该信息高速我们mvn命令基本用法,options表示可用的选项,mvn命令有20多个选项,这里暂不详述。命令后面可以添加一个或者多个goal和phase,

      他们分别指插件目标和生命周期阶段。可以通过mvn命令激活生命周期阶段,从而执行那些绑定在生命周期阶段上的插件目标。但maven还支持直接从命令行调用插件目标。

      支持这种方式是因为有些任务不适合绑定生命周期上。

       

      6、插件解析机制

      

      为了方便用户使用和配置插件,Maven不需要用户提供完整的插件坐标信息,就可以解析到正确的插件,这样虽然简化了插件的使用和配置,可一旦插件的行为出现异常,

      用户就很难快速定位到问题的插件构件。例如mvn help : system这样一条命令,到底执行了什么插件,该插件的groupId、artifactId和version分别是什么?

      插件仓库:与依赖构件一样,插件构件同样基于坐标存储在maven仓库中。在需要的时候,maven会从本地仓库寻找插件,如果不存在,则从远程仓库查找。找到插件之后,

      再下载到本地仓库使用。mave会区别对待依赖的远程仓库与插件仓库。当maven需要的依赖在本地仓库不存在时,它会去所配置的远程仓库查找,可是当maven需要的插件

      在本地仓库不存在时,它就不会去这些远程仓库查找。插件的远程仓库使用pluginRepositories和pluginRepository配置。内置的插件远程仓库配置 如下。

      这个默认插件仓库的地址就是中央仓库.

      

      项目使用的插件无法在中央仓库找到,或者自己编写了插件,这个时候可以参考以上的配置,在POM或者settings.xml中加入其它的插件仓库配置。

      插件的默认groupId:在POM中配置插件的时候,如果该插件是maven的官方插件,可以省略groupId配置。

      解析插件版本:同样是为了简化插件配置和使用,在用户没有提供插件版本的情况下,maven会自动解析插件版本。maven在超级pom中为所有核心插件设定了版本,

      超级pom是所有maven项目的父pom。所有项目都继承这个超级pom的配置,因此即使用户不加任何配置,maven使用核心插件的时候,他们的版本都就已经确定了,

      这些插件包括maven-clean-plugin、maven-compiler-plugin、maven-surefire-plugin等。

      如果用户使用某个插件时没有设定版本,而这个插件不属于核心插件的范畴,maven就会去检查所有仓库中可用的版本,然后做出选择。

      以maven-compiler-plugin为例,在中央仓库的仓库元数据为http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml

      内容如下:

      

      maven遍历本地仓库和所有远程插件仓库,将该路径下的仓库元数据归并后,就能计算出latest和release的值。latest表示所有仓库中该构建的最新版本,而release表示最新的非快照版本。

      解析插件前缀:mvn命令行支持使用插件前缀来简化插件调用,现在解释maven如何根据插件前缀解析到插件的坐标。插件前缀与groupId:artifactId是一一对应的,

      这种匹配关系存在仓库元数据中,仓库元数据为groupId/maven-metadata.xml。maven解析插件仓库元数据的时候,会默认使用org.apache.maven.plugins和

      org.codehaus.mojo两个groupId.可以通过配置settings.xml让maven检查其他groupId是哪个的插件仓库元数据:

      

      基于该配置,maven就不仅仅会检查org/apache/maven/plugins/maven-metadata.xml和org/codehaus/mojo/maven-metadata.xml还会检查com/your/plugins/maven-metadata.xml

       

      上述内容是从中央仓库的org.apache.maven.plugins groupId下插件仓库元数据中截取的一些片段,从这段数据中就能看到maven-clean-plugin的前缀为clean,maven-compiler-plugin的

      前缀为compiler,maven-dependency-plugin的前缀为dependency.

      当maven解析到denpendency:tree这样的命令后,他首先基于默认的groupId归并所有插件仓库的元数据org/apache/maven/plugins/maven-metadata.xml.其次检查归并后的元数据,

      找到对应的artifactId为maven-dependency-plugin,然后结合当前元数据的groupId找到对应的artifactId为maven-dependency-plugin然后结合当前元数据的groupI org.apache.maven.plugins.

      解析到version,这是就得到了完整的插件坐标。

     

  • 相关阅读:
    synchronized内置锁
    《JavaScript闯关记》视频版硬广
    想提高团队技术,来试试这个套路!
    从国企到阿里的面试经历(二)
    从国企到阿里的面试经历(一)
    《JavaScript 闯关记》之垃圾回收和内存管理
    《JavaScript 闯关记》之原型及原型链
    《JavaScript 闯关记》之作用域和闭包
    如何排版 微信公众号「代码块」之 MarkEditor
    《JavaScript 闯关记》之事件
  • 原文地址:https://www.cnblogs.com/jixp/p/10447590.html
Copyright © 2020-2023  润新知