这里我还是将通过一个例子来了解一下Maven继承的初步使用配置。还是使用三个工程项目Project-Parent、Project-C和Project-D来进行说明,三个项目关系如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.spiritmark.ExtendDemo</groupId>
<artifactId>Project-Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <name>Project-Parent</name> </project>

看这个POM文件,会发现和聚合有几分相像,只是没有modules节点,同样需要注意的是packaging的取值,必须使用pom。

Project-C的POM文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.spiritmark.ExtendDemo</groupId>
<artifactId>Project-Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../Project-Parent/pom.xml</relativePath>
</parent> <artifactId>Project-C</artifactId> <name>Project-C</name> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
</dependencies>
</project>

Project-D的POM文件如下:

?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.spiritmark.ExtendDemo</groupId>
<artifactId>Project-Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../Project-Parent/pom.xml</relativePath>
</parent> <artifactId>Project-D</artifactId> <name>Project-D</name> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
</dependencies>
</project>

在Project-C和Project-D工程中都使用了parent元素声明父模块,parent下的坐标元素groupId、artifactId和version是必须的,它们指定了父模块的坐标;元素relativePath表示父模块POM的相对路径。在项目构建时,Maven会首先根据relativePath检查父POM。

同时,在Project-C和Project-D工程中,我们都没有在POM中指定groupId和version值,但是在构建时,依然可以成功构建。实际上,在Project-C和Project-D工程从父模块继承了这两个元素,这也就消除了一些不必要的配置。在这个例子中,子模块同父模块使用了同样的groupId和version值,如果遇到子模块需要使用和父模块不一样的groupId或者version的情况,我们则完全可以再子模块中显示声明。

可继承的POM元素

在上面,可以看到groupId和version是可以被继承的,那么还有哪些POM元素可以被继承呢?这里我将一些我们经常用作继承的元素做一下汇总,并进行简单的说明:

  • groupId:项目组ID
  • version:项目版本
  • distributionManagement:项目的部署配置
  • properties:自定义的Maven属性
  • dependencies:项目的依赖配置
  • dependencyManagement:项目的依赖管理配置
  • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等

依赖管理

上面说到dependencies是可以被继承的,那我们在Project-C和Project-D工程中很多公共的部分就可以提取出来,统一放到Project-Parent工程中去了,这样就可以移除公共配置,简化配置。

上面说的做法是可行的,但是会存在问题。我们考虑一下这样的一个场景。Project-C和Project-D工程中公共的部分都提取到Project-Parent工程中去了,如果此时新增了一个Project-E工程,而Project-E工程有80%的依赖在Project-Parent工程中可以找到,另外那20%的依赖是个性化的;也就是说,Project-Parent工程中有20%的依赖对于Project-E工程来说是没有用的。这个时候如果Project-E工程继承Project-Parent工程,则会引入无用的依赖,违背了Maven的使用原则。对于这种场景,Maven中也有很完美的解决方案。

Maven提供的dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用。现在将Project-Parent工程的POM文件修改如下:


<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.spiritmark.ExtendDemo</groupId>
<artifactId>Project-Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <name>Project-Parent</name> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springframework.version>5.1.6.RELEASE</springframework.version>
<junit.version>4.11</junit.version>
</properties> <dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

这里使用dependencyManagement,将springframework和junit依赖提取了出来,放到了Project-Parent工程中。这样声明的依赖既不会给Project-Parent引入依赖,也不会给它的子模块引入依赖,不过这段配置是会被继承的。现在,我们将Project-C工程的POM修改为以下内容:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.spiritmark.ExtendDemo</groupId>
<artifactId>Project-Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../Project-Parent/pom.xml</relativePath>
</parent> <artifactId>Project-C</artifactId> <name>Project-C</name> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
</dependencies>
</project>

Project-D项目和Project-C类似,这里不再累述。上面的POM中依赖配置比原来简单了不少,所有的springframework依赖只配置了groupId和artifactId,省去了version。这些依赖的配置都在Project-Parent工程中有了配置,子模块只需要简单的配置groupId和artifactId即可。如果在子模块不声明依赖的使用,即使该依赖已经在父POM的dependencyManagement中声明了,也不会产生任何实际的效果。

插件管理

Maven提供了dependencyManagement元素帮助管理依赖,类似地,Maven也提供了pluginManagement元素帮助管理插件。同dependencyManagement一样,在pluginManagement元素中配置的依赖不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中配置的插件匹配时,pluginManagement的配置才会影响实际的插件行为。

Maven之继承的更多相关文章

  1. Maven的继承与聚合——多模块开发

    一:Maven多模块项目,适用于一些比较大的项目,通过合理的模块拆分,实现代码的复用,便于维护和管理.尤其是一些开源框架,也是采用多模块的方式,提供插件集成,用户可以根据需要配置指定的模块. 二:继承 ...

  2. Maven的继承和聚合

    Maven的继承和聚合子项目的pom文件里通过<parent>节点来继承父项目 <parent> <groupId>com.tykj</groupId> ...

  3. maven pom继承与聚合

    一.POM聚合模块: 在分布式架构,分模块化开发中,每个某块可能都是一个单独的maven项目,能够独立的进行项目构架,当模块比较多时,可以使用maven聚合聚合项目来简化maven构建,一次构建多个项 ...

  4. Maven可继承的POM 元素

    groupId :项目组 ID ,项目坐标的核心元素: version :项目版本,项目坐标的核心元素: description :项目的描述信息: organization :项目的组织信息: in ...

  5. Maven的继承以及import作用域

    Maven的pom文件中可继承的元素包括: groupId:项目ID,项目坐标核心元素 version:项目版本 description:描述信息 organization:组织信息 inceptio ...

  6. Maven项目继承与聚合

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6628534.html  一:继承 在Java编程中,如果多个类都使用到了相同的内容.方法时,我们可以用继承的方 ...

  7. maven(十)-继承

     继承 如果项目划分了多个模块,都需要依赖相似的jar包,只需要创建一个父模块,在它的pom.xml文件中配置依赖jar包.功能模块只需要继承父模块,就可以自动得到其依赖jar包,而不需要在每个模 ...

  8. SpringBoot2.0.2 不使用parent作为maven单继承方式操作 : org.springframework.boot : spring-boot-dependencies : 2.0.2.RELEASE

    1.pom配置方式 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  9. (十四)Maven聚合与继承

    1.Maven聚合 我们在平时的开发中,项目往往会被划分为好几个模块,比如common公共模块.system系统模块.log日志模块.reports统计模块.monitor监控模块等等.这时我们肯定会 ...

随机推荐

  1. css3系列之过渡transition

    transition 设置变换属性的过渡效果,举个例子,也就是说, 如果从width100px 变成 width200px,要以什么方式进行变换,速度,时间,类型等. transition trans ...

  2. robot 如何定义用户关键字、变量

    1.用户关键字,使用robot语法定义的关键字 2.系统关键字  自带的 3.资源文件,自己定义的关键字 4.变量 自己定义的关键字,需单独建一个资源文件 自己写的关键字,需写在***Keywords ...

  3. Java中的位掩码BitMask

    目录 JDK源码的使用 日常工作中的使用 JDK源码的使用 最近在JDK源码中闲逛,无意中看到了java.lang.reflect.Modifier这个类,这个类很简单,都是些常量定义和判断方法,于是 ...

  4. 推荐系统实践 0x07 基于邻域的算法(2)

    基于邻域的算法(2) 上一篇我们讲了基于用户的协同过滤算法,基本流程就是寻找与目标用户兴趣相似的用户,按照他们对物品喜好的对目标用户进行推荐,其中哪些相似用户的评分要带上目标用户与相似用户的相似度作为 ...

  5. open()和with open() as的区别

    2020-03-18  20:37:55 open()和with open() as的区别 1 file = open("test.txt","r") 2 fo ...

  6. (在模仿中精进数据可视化05)疫情期间市值增长top25公司

    本文完整代码及数据已上传至我的Github仓库https://github.com/CNFeffery/FefferyViz 1 简介 新冠疫情对很多实体经济带来冲击的同时,也给很多公司带来了新的增长 ...

  7. 【mq学习笔记-分布式篇】主从同步机制

    核心类: 消息消费到达主服务器后需要将消息同步到从服务器,如果主服务器Broker宕机后,消息消费者可以从从服务器拉取消息. HAService:RocketMQ主从同步核心实现类 HAService ...

  8. MySQL中的事务原理和锁机制

    本文主要总结 MySQL 事务几种隔离级别的实现和其中锁的使用情况. 在开始前先简单回顾事务几种隔离级别以及带来的问题. 四种隔离级别:读未提交.读已提交.可重复读.可串行化. 带来的问题:脏读.不可 ...

  9. 【2014广州市选day1】JZOJ2020年9月12日提高B组T4 字符串距离

    [2014广州市选day1]JZOJ2020年9月12日提高B组T4 字符串距离 题目 Description 给出两个由小写字母组成的字符串 X 和Y ,我们需要算出两个字符串的距离,定义如下: 1 ...

  10. 0001_20190327_使用frp搭建内网穿透

    1. 环境 a)         公网服务器为阿里云的ECS  Windows  2008 R2服务器, 有公网IP地址; 这个作为frp的服务器 b)         内网是开发服务器, Cento ...