-
Maven pom 继承聚合
2018-10-31 16:52:53Maven pom 继承聚合 1.1.0 简介 对于一个pom.xml来说有几个元素是必须定义的,一个是project根元素,然后就是它里面的modelVersion、groupId、artifactId和version。由上面的超级pom.xml的内容我们...Maven pom 继承聚合
1.1.0 简介
对于一个pom.xml来说有几个元素是必须定义的,一个是project根元素,然后就是它里面的modelVersion、groupId、artifactId和version。由上面的超级pom.xml的内容我们可以看到pom.xml中没有groupId、artifactId和version的定义,所以我们在建立自己的pom.xml的时候就需要定义这三个元素。和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是: dependencies,developers, contributors, plugin列表(包括plugin下面的reports), resources
1.1.1继承
1.1.1.1 被继承项目与继承项目是父子目录关系
现在假设我们有一个项目projectA,它的pom.xml定义如下:
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> </project>
然后我们有另一个项目projectB,而且projectB是跟projectA的pom.xml文件处于同一个目录下,这时候如果projectB需要继承自projectA的话我们可以这样定义projectB的pom.xml文件。
<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/maven-v4_0_0.xsd"> <parent> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectB</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> </project>
由projectB的pom.xml文件的定义我们可以知道,当需要继承指定的一个Maven项目时,我们需要在自己的pom.xml中定义一个parent元素,在这个元素中指明需要继承项目的groupId、artifactId和version。
1.1.1.2 被继承项目与继承项目的目录结构不是父子关系
当被继承项目与继承项目的目录结构不是父子关系的时候,我们再利用上面的配置是不能实现Maven项目的继承关系的,这个时候我们就需要在子项目的pom.xml文件定义中的parent元素下再加上一个relativePath元素的定义,用以描述父项目的pom.xml文件相对于子项目的pom.xml文件的位置。
假设我们现在还是有上面两个项目,projectA和projectB,projectB还是继承自projectA,但是现在projectB不在projectA的子目录中,而是与projectA处于同一目录中。这个时候projectA和projectB的目录结构如下:
------projectA
------pom.xml
------projectB
------pom.xml
这个时候我们可以看出projectA的pom.xml相对于projectB的pom.xml的位置是“../projectA/pom.xml”,所以这个时候projectB的pom.xml的定义应该如下所示:
<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/maven-v4_0_0.xsd"> <parent> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../projectA/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectB</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> </project>
1.2.2聚合
对于聚合这个概念搞java的人应该都不会陌生。先来说说我对聚合和被聚合的理解,比如说如果projectA聚合到projectB,那么我们就可以说projectA是projectB的子模块, projectB是被聚合项目,也可以类似于继承那样称为父项目。对于聚合而言,这个主体应该是被聚合的项目。所以,我们需要在被聚合的项目中定义它的子模块,而不是像继承那样在子项目中定义父项目。具体做法是:
1) 修改被聚合项目的pom.xml中的packaging元素的值为pom
2) 在被聚合项目的pom.xml中的modules元素下指定它的子模块项目
对于聚合而言,当我们在被聚合的项目上使用Maven命令时,实际上这些命令都会在它的子模块项目上使用。这就是Maven中聚合的一个非常重要的作用。假设这样一种情况,你同时需要打包或者编译projectA、projectB、projectC和projectD,按照正常的逻辑我们一个一个项目去使用mvn compile或mvn package进行编译和打包,对于使用Maven而言,你还是这样使用的话是非常麻烦的。因为Maven给我们提供了聚合的功能。我们只需要再定义一个超级项目,然后在超级项目的pom.xml中定义这个几个项目都是聚合到这个超级项目的。之后我们只需要对这个超级项目进行mvn compile,它就会把那些子模块项目都进行编译。
1.2.2.1 被聚合项目和子模块项目在目录结构上是父子关系
还拿上面定义的projectA和projectB来举例子,现在假设我们需要把projectB聚合到projectA中。projectA和projectB的目录结构如下所示:
------projectA
------projectB
-----pom.xml
------pom.xml
这个时候projectA的pom.xml应该这样定义:
<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.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>projectB</module> </modules> </project>
由上面的定义我们可以看到被聚合的项目的packaging类型应该为pom,而且一个项目可以有多个子模块项目。对于聚合这种情况,我们使用子模块项目的artifactId来作为module的值,表示子模块项目相对于被聚合项目的地址,在上面的示例中就表示子模块projectB是处在被聚合项目的子目录下,即与被聚合项目的pom.xml处于同一目录。这里使用的module值是子模块projectB对应的目录名projectB,而不是子模块对应的artifactId。这个时候当我们对projectA进行mvn package命令时,实际上Maven也会对projectB进行打包。
1.2.2.2被聚合项目与子模块项目在目录结构上不是父子关系
那么当被聚合项目与子模块项目在目录结构上不是父子关系的时候,我们应该怎么来进行聚合呢?还是像继承那样使用relativePath元素吗?答案是非也,具体做法是在module元素中指定以相对路径的方式指定子模块。我们来看下面一个例子。
继续使用上面的projectA和projectB,还是需要把projectB聚合到projectA,但是projectA和projectB的目录结构不再是父子关系,而是如下所示的这种关系:
------projectA
------pom.xml
------projectB
------pom.xml
这个时候projectA的pom.xml文件就应该这样定义:
<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.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>../projectB</module> </modules> </project>
注意看module的值是“../projectB”,我们知道“..”是代表当前目录的上层目录,所以它表示子模块projectB是被聚合项目projectA的pom.xml文件所在目录(即projectA)的上层目录下面的子目录,即与projectA处于同一目录层次。注意,这里的projectB对应的是projectB这个项目的目录名称,而不是它的artifactId。
6.2.2.3聚合与继承同时进行
假设有这样一种情况,有两个项目,projectA和projectB,现在我们需要projectB继承projectA,同时需要把projectB聚合到projectA。然后projectA和projectB的目录结构如下:
------projectA
------pom.xml
------projectB
------pom.xml
那么这个时候按照上面说的那样,projectA的pom.xml中需要定义它的packaging为pom,需要定义它的modules,所以projectA的pom.xml应该这样定义:
<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.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>../projectB</module> </modules> </project>
而projectB是继承自projectA的,所以我们需要在projectB的pom.xml文件中新增一个parent元素,用以定义它继承的项目信息。所以projectB的pom.xml文件的内容应该这样定义:
<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.tiantian.mavenTest</groupId> <artifactId>projectA</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../projectA/pom.xml</relativePath> </parent> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectB</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> </project>
章节小结:其实说白了,聚合和继承是非常简单的,聚合的目的是实现一键build的功能,即A进行build的时候,下面聚合了的b,c,d都会进行build构建,而继承则是父pom对插件或者依赖jar进行了表述,使得子孙可以继承这样的规范和依赖,不过在继承中,也有需要注意甚至是才坑的地方,下面我们给出实例。特别要注意在继承关系中,并不是所有的依赖和插件都会继承,一定要区别开dependency标签是默认都继承,而dependencyManagement标签下的依赖或者pluginsManagement下的插件不是默认继承,而是需要声明,没有覆盖的内容就采用父pom中的内容,但是一定要声明。
Maven之——依赖与插件管理
并不是父POM中配置的所有依赖在不同的子类中都能用到、或者用到了但是不是统一版本、为解决这个、在父POM标签中定义依赖信息、在子POM中加入依赖的引入。具体细节如下:在父POM中配置项目中使用到的依赖、但是不再是dependency标签中配置、因为此标签可以自动被继承、使用dependencyManagement标签、此标签中定义的dependency不会被子POM自动引入、必须在子类中使用dependency声明。可能有些时候会觉得直接在子POM中引用依赖不就行了?一个是统一管理、另一个是简化配置后面有提到。依赖管理两部实现:
a)在父POM中配置需要引入的依赖管理——scattered-items中的pom.xml:
<properties> <junit.version>4.1</junit.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement>
上面使用了properties标签来定义全局变量、跟Java中定义变量意义项目、提取重复值。
b)在子POM中配置依赖——items-thkinjava中的pom.xml:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies>
子POM中关于junit的依赖的引入只需配置groupId和artifactId就可以了、版本和scope都不用指定。
注意:关键的地方是在父POM中的dependencyManagement标签中配置的依赖是不会主动引入到子项目中的、也就是说虽然在父POM中的dependencyManagement定义了junit的依赖、假如子类中没有关于junit的<dependency>、那么子类就没有junit依赖的引入、并且假如子项目不想使用4.1版本的junit、还可以指定自己想要使用的junit版本、这样就完全覆盖了父POM中关于junit的定义、也就是说父POM中的junit定义与他无关。这样的灵活性已经够满足我们日常需求了。
建议依赖都放在父POM中的dependencyManagement、一个是减少配置、二个是方便管理、比如版本冲突就是很常见的问题。通过dependencyManagement+变量的方式统一管理、更安全高效。
依赖范围有一种是import、是只有在dependencyManagement元素下才有效果的、使用该范围的依赖通常指向一个POM、作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。例如想在另外一个模块中使用上面配置的dependencyManagement配置、除了复制继承之外还可以使用import范围依赖将这已配置导入:
<dependencyManagement> <dependencies> <dependency> <groupId>org.andy.items</groupId> <artifactId>scattered-items</artifactId> <type>pom</type> <version>1.0-SNAPSHOT</version> <scope>import</scope> </dependency> <dependency> <groupId>othergi</groupId> <artifactId>otherai</artifactId> <version>${other.version}</version> </dependency> </dependencies> </dependencyManagement>
3、插件管理
插件管理与依赖管理原理一样、不同的是定义的元素标签不一样、插件管理标签是build标签的子标签pluginManagement、在父POM中定义、子POM引用。如前面有个生成源码包的插件、使用插件管理的配置过程如下:
a)父POM——scattered-items中的pom.xml:
<build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>${sources.plugin.verion}</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </pluginManagement> </build>
b)子POM——items-thkinjava中的pom.xml:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> </plugin> </plugins> </build>
注意的东西与依赖管理类似、只是换成了插件管理。
4、约定优于配置
标准的重要性已经不用过多强调、ConventionOver Configuration是maven最核心的设计理念之一。
任何一个maven项目都隐式的继承了超级POM、有点类似与Java所有的类都继承Object类、因此、大量超级POM的配置都会被所有maven项目继承、这些配置也就成为了maven所提倡的约定。
超级POM位置:$M2_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。
-
maven 依赖 继承 聚合的配置
2014-03-10 23:27:41pom的配置文件中 1.依赖 junit junit ${junit.version} 2.继承 com.xx.xx xx-parent 1.0-SNAPSHOT 3.聚合 testpom的配置文件中
1.依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>2.继承
<parent>
<groupId>com.xx.xx</groupId>
<artifactId>xx-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>3.聚合
<modules>
<module>test</module>
</modules> -
Maven的继承和聚合
2020-12-30 14:52:53Maven的继承和聚合 1. 继承 应用场景 项目分为多个模块,重复的依赖比较多,需要提出来公有的依赖来统一管理。 使用方法 子模块中引入父模块: <parent> <groupId>com.xsyz</groupId> <...Maven的继承和聚合
1. 继承
-
应用场景
项目分为多个模块,重复的依赖比较多,需要提出来公有的依赖来统一管理。
-
使用方法
子模块中引入父模块:
<parent> <groupId>com.xsyz</groupId> <artifactId>springboot-review</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> <!-- 父模块相对路径,如果不写会自动查找 --> </parent>
-
两种方式
-
父项目统一管理版本号,子项目需要显式说明自己的依赖(父项目加上dependencyManagement)
父模块:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.4.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </dependencyManagement>
子模块:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies>
子模块依赖:
-
全部继承父项目的依赖(父项目不加dependencyManagement)
父模块:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.4.1</version> <scope>test</scope> </dependency> </dependencies>
子模块:
<dependencies> </dependencies>
子模块依赖:
-
2. 聚合
-
应用场景
可以帮助我们把项目的多个模块聚合在一起,使用一条命令进行构建,即一条命令实现构建多个项目
-
使用方法
- 构建聚合模块:聚合模块的坐标GAV后面需要声明打包形式为pom
<groupId>com.xsyz</groupId> <artifactId>springboot-review</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging>
-
声明需要聚合的子模块:
<modules> <module>review-aop</module> <module>review-jwt</module> </modules>
-
在聚合模块下打包,打包的时候就会先打包聚合模块,然后自动打包子模块
聚合和继承经常一起使用
-
-
MAVEN的继承和聚合
2020-07-13 19:44:13maven的聚合是建立再继承之上的。 有继承关系可以没有聚合。 比如现在有parent、child1、child2三个部分, child1、child2是parent的子模块, 这时候,child1依赖child2,那么当去执行maven build时候,需要先执行...maven的聚合是建立再继承之上的。
有继承关系可以没有聚合。
比如现在有parent、child1、child2三个部分,
child1、child2是parent的子模块,这时候,child1依赖child2,那么当去执行maven build时候,需要先执行child2,再执行child1才能生效。
但是如果使用下图的方式,利用parent将两个模块聚合在一起,那么直接在parent的pom文件进行maven build,就可以智能的进行,先加载parent、再加载child1、再加载child2这样的方式
于是这样实现了聚合的好处
-
Maven 的继承和聚合
2013-12-20 01:14:07Maven的继承与聚合 当把Maven应用到实际项目中的时候,也需要将项目分成不同的模块,例如email和persist等模块,Maven的聚合特性能够把项目的各个模块聚合在一起构建,而Maven的继承 特性则能帮助抽取各模块相同的... -
maven继承与聚合
2019-06-29 19:03:421.maven的继承与聚合是两个不同的概念,其实互相是没有什么关系的。 2.聚合模块知道它聚合了哪些模块,但是被聚合的模块不知道聚合模块的存在;父模块不知道子模块的存在,但是子模块都必须知道自己的父模块是谁。 ... -
Maven项目继承和聚合
2020-01-05 20:12:56Maven中项目的继承和聚合目的都是用来方便工程模块的管理的,而Maven管理项目是方式是通过pom文件来实现的,所以Maven的继承和聚合关系本质又是不同模块间pom文件的关系。 Maven聚合:就是聚合工程pom中添加需要管理... -
Maven的继承和 聚合
2020-01-30 09:31:20不过还好,maven提供了继承机制,项目可以通过parent元素使用继承,可以避免这种重复。当一个项目声明一个parent的时候,它从父项目的POM中继承信息。它也可以覆盖父POM中的值,或者添加一些新的值。 一、创建... -
Maven学习笔记-maven的继承和聚合
2020-06-17 18:27:341.maven项目的继承 1. 为什么要进行maven项目继承? 在java中如果有多个class有多个相同的属性或者方法时,我们就会将这些属性或方法抽取出来,创建一个“baseEntity”,然后让各个类去继承“baseEntity”,这样方便... -
maven继承与聚合的理解
2017-09-05 11:32:111.首先说下maven的继承:主要是现在项目都比较大,模块比较多,很多模块又有很多相同的依赖,如果每个模块都去依赖的话就会很多余,如是就出现了继承,创建一个父项目统一管理相依赖,其余模块只需要继承父模块就行了 ... -
maven的继承和聚合
2019-03-26 20:29:471、继承 ... 使用继承机制就可以将这样的依赖统一提取到父工程模块中进行统一管理。 操作步骤: (1)、创建父工程 。创建一个Maven项目。注意:打包方式为 pom。 (2)、在父工程parent上,右键创... -
Maven的继承与聚合
2016-11-21 13:00:40maven继承管理 让版本的管理只在一个地方改变 modules用于聚合,把执行的项目都放到同一的地方用module包括,可以省去一个个项目去mvn install,这样可以所有项目一次聚合 mvn install 传递性依赖原则: A-->B A... -
Maven 继承与聚合
2018-04-14 14:36:46继承这个概念对于java程序员并不陌生,那在maven中的继承作用也和java中的一样么?maven为什么需要继承呢? 我们在上一章 Maven 依赖 中提到了依赖的范围概念,了解到junit 依赖是test范围的依赖,是不可以传递的... -
maven的继承和聚合-分布式框架基础
2019-09-04 18:58:12项目构建:一个项目拥有众多maven模块,这里面就蛇蛇了maven的继承和聚合 使用maven的继承和聚合可以对一个集成式的项目进行拆分,拆分成若干个模块,多个模块继承父工程。 创建一个项目我叫xiupeilian-parent,把src... -
Maven中的聚合与继承
2021-02-24 20:10:18Maven中的聚合与继承 1、聚合 Maven可以帮助我们把项目的多个模块聚合在一起,即使用一条命令实现多个项目的构建。 红框中的parent模块(父模块)即为聚合模块,聚合模块的打包方式必须为pom,否则无法完成构建。 ...