zoukankan      html  css  js  c++  java
  • maven的生命周期和插件

    Maven作为一个构建工具由于遵循了约定优于配置的原则,只要编写比Ant所需少得多的脚本就能实现同样的构建。并且Maven还有很多Ant没有的高级特性,例如依赖管理等,这一切使得Maven不仅是构建工具,更是项目管理工具,并越发流行起来。

    由于Maven在使用时非常简单,比如下面是百度百科中对Maven常用命令的列表:

    mvn archetype:create 创建Maven项目
    mvn compile 编译源代码
    mvn deploy 发布项目
    mvn test-compile 编译测试源代码
    mvn test 运行应用程序中的单元测试
    mvn site 生成项目相关信息的网站
    mvn clean 清除项目目录中的生成结果
    mvn package 根据项目生成的jar
    mvn install 在本地Repository中安装jar
    mvn eclipse:eclipse 生成eclipse项目文件
    mvn jetty:run 启动jetty服务
    mvn tomcat:run 启动tomcat服务
     
    开发人员往往只需要执行几个命令就能达成日常需要完成的目标,这是一个优点,但正是由于看起来太过简单了,可能会导致开发人员对待Maven不求甚解,比如在上面这一列表中有的命令有:(冒号),有的则没有,这些不同到底意味着什么,也许有的开发人员并不关心,这也可以理解,毕竟开发人员更关注于开发代码。但是知道Maven的一些基本概念还是有利于我们熟练掌握Maven的,像Maven这样的好东西,不仅会用而且能用好才是理想状态。刚才提到的有冒号和没冒号命令的区别,简单来的说,有冒号的命令是直接执行指定的插件,没有冒号的命令是按照Maven生命周期来执行的。但是什么是生命周期,插件又是什么呢?别着急,这正是本文要介绍的内容。

    1.Maven的生命周期

    Maven的生命周期是对所有的构建过程进行抽象和统一。Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,生命周期只是定义了一系列的阶段,并确定这些阶段的执行顺序。而在执行这些阶段时,实际的工作还是由插件来完成的。这种思想与设计模式中的模板方法非常相似。

    Maven有三套相互独立的生命周期,分别是clean、default和site。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site生命周期的目的是建立项目站点。每个生命周期都定义了有顺序的阶段(phase),如下表:
    生命周期 clean default site
    阶段(phase),
    执行顺序由上至下
    pre-clean validate pre-site
    clean initialize site
    post-clean generate-sources post-site
      process-sources site-deploy
    generate-resources  
    process-resources
    compile
    process-classes
    generate-test-sources
    process-test-sources
    generate-test-resources
    process-test-resources
    test-compile
    process-test-classes
    test
    prepare-package
    package
    pre-integration-test
    integration-test
    post-integration-test
    verify
    install
    deploy

    用户在mvn命令后可以指定三个生命周期中的任何阶段,则Maven会按以下逻辑执行:首先会得到该阶段所属生命周期,从该生命周期中的第一个阶段开始按顺序执行,直至该阶段本身。例如执行mvn clean命令会依次执行clean生命周期中的pre-clean阶段及clean阶段。mvn命令后可以指定多个阶段,Maven会按照输入的顺序依次执行,每次执行都会按照之前描述的逻辑执行。

    之前提到实际的工作还是由插件来完成的,这意味着插件需要和阶段绑定起来。Maven已经事先将很多核心插件绑定到对应的阶段,这样用户几乎不用配置就有构建Maven项目。Maven的内置绑定如下:

    生命周期 阶段(phase) 插件目标
    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

    细心的同学可能会问插件目标是什么呢,为什么不直接绑定到插件上。这是因为一个插件往往有多个功能,而每一个功能就是一个插件目标。回到文章开头提到的问题,像mvn archetype:create这样的命令,archetype:create实际上就是一个插件目标,mvn archetype:create这条命令会直接执行指定的插件目标,并不会执行其它任何的插件目标,这和执行生命周期阶段不一样。

    除了内置绑定外,用户还可以自己选择将某个插件目标绑定到生命周期的某个阶段,从而让构建过程更为完善。

    例如,虽然maven已经将test阶段和maven-surefire-plugin:test插件目标绑定起来,但却没有将integration-test阶段和任何插件目标绑定。如果我们想在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包下的测试类。

    2.Maven的插件

    其实在刚才介绍生命周期中已经提到了可以在命令行的mvn命令后直接指定插件目标,之所以Maven支持这种方式是因为有些任务不适合绑定到生命周期上。在命令行调用插件的格式如下 :

    mvn groupId:artifactId:version:goal

    其中groupId、artifactId、version共同表示了插件的坐标;goal则表示插件目标的方法。

    但我们看到很多执行插件目标的格式与之并不相符,例如文章开头的mvn archetype:create,archetype并不是groupId、artifactId或version而是插件的前缀,这就有了第二种调用插件的格式:

    mvn 前缀:goal

    Maven是如何解析插件的前缀的呢?实际是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。

  • 相关阅读:
    深入nginx之《获取用户的真实IP》
    深入Nginx之《常用参数配置技巧》
    深入Nginx之《HTTP请求报文与HTTP响应报文》
    webapck html-loader 静态html模块化
    webpack四个基础概念
    从原生Android 跳转到hbuilder项目
    移动端适配方案 flexible.js
    vue使用px2rem
    koa2 post请求ctx.request.body空获取不到的解决办法
    url、href、src
  • 原文地址:https://www.cnblogs.com/huangbin/p/3219740.html
Copyright © 2011-2022 走看看