• Maven进阶-继承与聚合


    一、继承

    引言

    继承关系中,分为父模块与子模块,父模块也被称为 parent 模块,子模块会继承父模块的依赖,父模块中也可以设置依赖管理器,供子模块选择是否需要某些依赖

    继承关系可以对不同模块的依赖版本做统一管理,因为子模块中的依赖基本都继承于父模块,父模块中指定哪个版本,子模块就继承哪个版本,可以有效避免不同模块可能采用不同版本的依赖时产生的冲突

    1. 继承关系的实现

    (1)parent 模块设置

    parent 模块即父模块,由于父模块只是为了给子模块提供依赖,所以父模块中只需要一个 pom.xml 文件即可。父模块的打包方式必须设置为 pom(默认打包方式是 jar)

        <groupId>com.mzzgroupId>
        <artifactId>parent-mavenartifactId>
        <version>1.0-SNAPSHOTversion>
        
        <packaging>pompackaging>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    只要设置了 packaging 属性为 pom,这个模块就可以作为 parent 模块被继承了

    (2)子模块设置

    子模块中只要设置了 parent 标签,就可以建立继承关系。

    所以继承主要体现在子模块,parent 模块是感受不到继承关系的,也无法从 parent 模块中看出哪些模块继承了自己。

    另外继承关系建议以后,如果子模块与父模块处于同一 groupId 下,那么子模块可以不写 groupId

        
        <artifactId>project-daoartifactId>
        <version>1.0-SNAPSHOTversion>
        
    	<parent>
    		
    		<groupId>com.mzzgroupId>
    		<artifactId>parent-mavenartifactId>
    		<version>1.0-SNAPSHOTversion>
    		
    		<relativePath>../parent-maven/pom.xmlrelativePath>
    	parent>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    对 relativePath 属性做一些补充:

    • relativePath 可以省略,前提是 parent 模块已经 install 至仓库,否则子模块无法定位到 parent,不能通过编译
    • 相对路径最后可以不写 pom.xml,只定位到父模块的文件夹也可以

    2. 依赖配置

    (1)必须继承的依赖

    parent 模块中声明的依赖便是子模块必须继承的依赖,子模块中不必声明便从父模块中继承了这些依赖

    <dependencies>
    	<dependency>
    		<groupId>org.springframeworkgroupId>
    		<artifactId>spring-webmvcartifactId>
    		<version>5.2.20.RELEASEversion>
    	dependency>
    	
    	
    	
    	<dependency>
    		<groupId>javax.servletgroupId>
    		<artifactId>javax.servlet-apiartifactId>
    		<version>4.0.1version>
    		<scope>providedscope>		
    	dependency>
    <dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述如上图,可见子模块中未声明依赖就继承了 parent 中的所有依赖

    (2)有选择地继承依赖

    parent 模块中设置依赖管理 dependencyManagement 后,在其中声明的依赖就是供子模块选择的依赖。子模块需要哪些依赖,必须在子模块中声明依赖,但不需要注明 version,因为版本由 parent 来指定。

    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.12version>
                <scope>testscope>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-testartifactId>
                <version>5.2.10.RELEASEversion>
                <scope>testscope>
            dependency>
        dependencies>
    dependencyManagement>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    
    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    如果子模块声明的依赖有 version 属性,那么这个依赖并不继承自 parent

    另外,parent 模块声明在 dependencyManagement 中的依赖并不被 parent 模块所依赖

    (3)插件继承

    插件的继承规则和设置方法与前面的依赖极为相似,同样也有插件管理 pluginManagement,与 dependencyManagement 类似,这里给出一个 parent 中设置的样例模板

    <build>
        <plugins>
    		
        plugins>
        <pluginManagement>
            <plugins>
    			
            plugins>
        pluginManagement>
    build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、聚合

    引言

    聚合就是指将多个模块组织成一个整体,同时进行项目的构建工作。

    使用聚合可以避免分模块开发时的一些问题,比如某个模块更新了一些内容,但其它已经构建好的模块不会进行更新,将所有模块聚合之后,只对聚合模块进行构建就会对所有模块都进行构建,能够及时的发现问题

    1. 实现聚合

    聚合模块也被称为 root 模块,同样是一个只需要 pom.xml 文件的项目,只要设置了 modules 标签,再将聚合的模块添加进去,即可实现聚合

    <modules>
    	
    	<module>../project-pojomodule>
    	<module>../project-daomodule>
    	<module>../project-servicemodule>
    modules>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如上例,将 pojo,dao 和 service 三个模块进行了聚合,只要对聚合模块进行构建,这三个模块也会被一起构建

    聚合只体现在聚合模块,被聚合的模块也无法感知自身被谁所聚合

    三、继承与聚合的合并

    继承是的 parent 模块和聚合时的 root 模块都只有 pom.xml,因为他们都是设计型模块,不包含实际的模块内容。事实上,继承与聚合经常被合并在一起使用,父模块(parent)也作为聚合模块(root)使用,只需要在父模块中加入 modules 属性,将子模块聚合即可

    这时要说一说继承时说到的 relativePath 属性,前面说 relativePath 属性可以省略,前提是父模块已经构建并 install 至仓库,否则子模块无法构建,但此时父模块同时也聚合了子模块,要构建父模块就又要一起构建子模块,但构建子模块又需要父模块 install 至仓库……陷入了套娃问题

    此时构建父模块 maven 会报错: Non-resolvable parent POM for XXX.XXX.XXX Could not find artifact com.mzz:parent-maven:pom:1.0-SNAPSHOT and ‘parent.relativePath’ points at wrong local POM,原因是无法定位 parent 模块

    解决方法也很简单,要么老老实实在子模块中 parent 标签中加入 relativePath 属性,使 maven
    可以根据相对路径找到父模块,要么,先将父模块中的 modules 注释掉,暂时不做聚合,将父模块 install 之后再取消注释,然后就能一起构建啦

  • 相关阅读:
    Java主流分布式解决方案多场景设计与实战
    编译原理复习——符号表
    CPS攻击案例(一)——基于脉冲宽度调制PWM的无人机攻击
    数理天地杂志数理天地杂志社数理天地编辑部2022年第15期目录
    软件设计师冲刺:临考快速记忆
    提升群辉AudioStation音乐体验,实现公网音乐播放
    制作一个简单HTML旅游网站(HTML+CSS+JS)无锡旅游网页设计与实现8个页面
    从零开始学JAVA(04):数组
    AES加密有什么用,AES加密算法安全性如何
    Privacy Policy for 高中英语
  • 原文地址:https://blog.csdn.net/Cey_Tao/article/details/126567296