zoukankan      html  css  js  c++  java
  • maven07-----maven中的聚合与继承

    Maven的聚合特性能够把项目的各个模块聚合在一起构建,而Maven的继承特性则能帮助抽取各模块相同的依赖和插件等配置。

    一. 聚合

    Maven聚合(或者称为多模块),是为了能够使用一条命令就构建多个模块,例如已经有两个模块,分别为account-email,account-persist,我们需要创建一个额外的模块(假设名字为account-aggregator,然后通过该模块,来构建整个项目的所有模块,accout-aggregator本身作为一个Maven项目,它必须有自己的POM,不过作为一个聚合项目,其POM又有特殊的地方,看下面的配置:

    <project
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
            http://maven.apache.org/maven-v4_0_0.xsd>
            <modelVersion>4.0.0</modelVersion>
            <groupId>com.juvenxu.mvnbook.account</groupId>
            <artifact>account-aggregator</artifact>
            <version>1.0.0-SNAPSHOT</version>
            <packaging>pom</packaging>    //note:要使用聚合的话必须为pom
            <name>Account Aggregator</name>
            <modules>
                <module>account-email</module>
                <module>account-persist</module>
            </modules>
    </project>

    上面有一个特殊的地方就是packaging,其值为pom,如果没有声明的话,默认为jar,对于聚合模块来说,其打包方式必须为pom,否则无法构建。

    modules里的每一个module都可以用来指定一个被聚合模块,这里每个module的值都是一个当前pom的相对位置,本例中account-email、account-persist位于account-aggregator目录下,当三个项目同级的时候,上面的两个module应该分别为../account-email和../account-persist

    举例:

    (1)创建一个父项目a

    (2)创建一个子项目b

    点击父项目的pom文件,为他添加model

     

    一路next,最终finish

     刷新一下项目a,就可以看见下面有个子项目b

    note: 项目a中的除pom.xml文件其它都可以事先删除掉。

    同理,再建立一个子项目c

    (3)到父模板下面执行mvn clean install

     Reactor Summary:
    [INFO]
    [INFO] a 0.0.1-SNAPSHOT ................................... SUCCESS [  0.303 s]
    [INFO] b .................................................. SUCCESS [  1.893 s]
    [INFO] c 0.0.1-SNAPSHOT ................................... SUCCESS [  0.757 s]
    [INFO] ------------------------------------------------------------------------

    说明:Maven会首先解析聚合模块的pom分析要构建的模块、并计算出一个反应堆构建顺序(Reactor Build Order),然后根据这个顺序依次构建各个模块。上面的红色名字部分正是pom种的name字段的值,因此,配置一个有意义的名字比较好。

    二. 继承

    2.1 使用说明

     maven中的继承类似于java项目中的继承。

    maven中的继承的实现步骤:

    • 建立父工程:父工程的打包方式为pom
    • 在父工程的pom.xml中编写依赖:
    <dependencyManagement>   //如果是父工程,需要写dependencyManagement,否则普通工程直接不用写这个
      <dependencies>
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
              <scope>test</scope>
          </dependency>
      </dependencies>
      </dependencyManagement>
    • 子类:在子类中添加parent的配置
    <parent>
          <groupId>com.test</groupId>
          <artifactId>base</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <relativePath>../base/pom.xml</relativePath>  //代表的从子类pom.xml到父类pom.xml的相对路径
      </parent>
    note: 找相对路径的办法:先找到当前的pom.xml,可以通过alt+enter快捷键定位到计算机中的存储位置(有一个黄色的link可以点击直接跳转到计算机的存储位置)。
    然后子pom需要先跳出来,跳到本项目同级别的父项目的位置,假设是base,然后再进入到base里面寻找Pom,因此相对路径就是../base/pom.xml
    • 子类:需要声明,使用哪些父类的依赖

    知道了大致的继承创建过程后,下面举一个例子来进一步理解。

    2.2 举例

    1. 创建父项目base

    第一个勾选了允许在创建maven项目的时候就能够修改打包方式。并且,创建以后的东西还可以省去处理pom.xml文件之外的文件。

    2. 在父类的pom.xml中添加依赖

    <dependencyManagement>  
      <dependencies>
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
              <scope>test</scope>
          </dependency>
      </dependencies>
      </dependencyManagement>

    3. 创建子工程,且配置Pom.xml

    因为两者的groupId和version一样,因此,无需在子模块中继续声明了。

     <parent>
          <groupId>com.test</groupId>
          <artifactId>base</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <relativePath>../base/pom.xml</relativePath> 
      </parent>
      
      <artifactId>sub</artifactId>
      <packaging>jar</packaging>
    
      <name>sub</name>
      <url>http://maven.apache.org</url>
    note:先保证子类没有junit 4.12版本

    4. 刷新子类,发现Junit4.12并没有在maven depenciy下拉菜单中,是因为没有继承么?实际上这是正确的。倘若父类有很多子类没有的东西,那岂不是父类所有的jar包都需要展示在子类的依赖包的下拉菜单中了。那么如何证明继承成功呢?有两个办法:

    (1)查看子类的effective pom.xml,其中就包含了从子类继承来的所有jar包。发现是有junit4.12的,只是pom.xml中没有而已。

    (2)直接在子类的pom中显示的声明需要依赖junit 4.12的版本,只需要给出groupID和architeID就可以了,会自动从父类中继承4.12版本的。刷新后,就会在maven depency下来菜单中出现了。

    2.3 可继承的pom元素

    • groupId:项目组ID,项目坐标的核心元素
    • version:项目版本,项目坐标的核心元素
    • description:项目的描述信息
    • organnization:项目的组织信息
    • inceptionYear:项目的创始年份
    • url:项目的URL地址
    • developers:项目的开发者信息
    • contributors:项目的贡献者信息
    • distributionManagement:项目的部署配置
    • issueManagement:项目的缺陷跟踪系统信息
    • ciManagement:项目的集成信息
    • scm:项目的版本控制系统信息
    • mailingLists:项目的邮件列表信息
    • properties:自定义的Maven属性
    • dependencies:项目的依赖配置
    • dependencyManagement:项目的依赖管理配置
    • repositories:项目的仓库配置
    • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
    • reporting:包括项目的报告输出目录配置,报告插件配置等。

    三. 聚合与继承的关系

    多模块中的聚合与继承其实是两个概念,其目的是完全不同的,前者主要是为了方便快速构建项目,后者主要是为了消除重复配置。

    对于聚合模块来说,它知道有哪些被聚合的模块,但那些被聚合的子模块不知道这个聚合模块的存在。

    对于继承关系的父POM来说,它不知道哪些子模块继承于它,但那些子模块都必须知道自己的父POM是什么。

    在现有的实际项目中,往往会发现一个POM即是聚合POM,又是父POM,这么做主要是为了方便。一般来说,融合使用聚合与继承也没什么问题。

    四. 约定优于配置

    Maven默认的源码目录是:src/main/java但是用户也可以自己指定源码目录,如下:

    <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.juvenxu.mvnbook<groupId>
        <artifactId>my-project</artifactId>
        <version>1.0</version>
        <build>
            <sourceDirectory>src/java</sourceDirectory>
        </build>
    </project>

    但是一般还是不要自定义了,不好管理。

    五. 反应堆

    反应堆的构建顺序

    在一个多模块的Maven项目中,反应堆(Reactor)是指所有模块组成的一个构建结构。对于单模块的项目,反应堆就是该模块本身,对于多模块来说,反应堆就包含了各模块之间继承与依赖的关系,从而能够自动计算出合理的模块构建顺序。

    例如:

    <modules>
        <module>account-email</module>
        <module>account-persist</module>
        <module>account-parent</module>
    </modules>

    以上,构建顺序不一定是顺序去读取POM的顺序,当一个模块依赖于另外一个模块,Maven会先去构建被依赖模块,并且Maven中不允许出现循环依赖的情况,就是,当出现模块A依赖于B,而B又依赖于A的情况时,Maven就会报错。

    裁剪反应堆

    一般来说,用户会选择构建整个项目或者选择构建单个的模块,但有些时候,用户会想要仅仅构建完整反应堆中的某些个模块。换句话说,用户需要实时地剪裁反应堆。

    Maven提供很多命令行选项支持裁剪反应堆,输入mvn -h可以看到这些选项:

    • -am, --also-make:同时构建所列模块的依赖模块
    • -amd -also-make-dependents:同时构建依赖于所列模块的模块
    • -p,--project
    • -rf -resume-from

    默认情况从account-aggregator执行mvn clean install会得到如下完整的反应堆:

    [INFO]-----------------------------------------------------
    [INFO]Reactor Build Order:
    [INFO]
    [INFO]Account Aggregator
    [INFO]Account Parent
    [INFO]Account Email
    [INFO]Account Persist
    [INFO]
    [INFO]-----------------------------------------------------

    可以使用-pl选项指定构建某几个模块,如运行如下命令:

    $ mvn clean install -p account-email,account-persist

    得到的反应堆为:

    [INFO]-----------------------------------------------------
    [INFO]Reactor Build Order:
    [INFO]
    [INFO]Account Email
    [INFO]Account Persist
    [INFO]
    [INFO]-----------------------------------------------------

    六. 补充

    多模块的创建涉及到了聚合和继承。也可以通过新建一个maven(simple)工程作为父工程,删除src等东西,只留下Pom.xml,然后点击父项目,右键new-->maven module方式来创建子Module,这样继承和聚合关系就自动生成了。记得刷新一下。

    参考文献

    《Maven实战》

  • 相关阅读:
    【以前的空间】poj 2288 Islands and Bridges
    【以前的空间】网络流合集
    【以前的空间】 单调队列系列
    【以前的空间】几道平衡树
    【以前的空间】vijos 1720 阿狸的打字机
    对拍程序
    【Ubuntu】编写一个c语言代码
    用Matlab对数据进行线性拟合算法
    Oracle视图传递参数
    oracle decode的用法
  • 原文地址:https://www.cnblogs.com/Hermioner/p/10266832.html
Copyright © 2011-2022 走看看