您现在的位置是:首页 >学无止境 >Maven(六):Maven的使用——继承与聚合网站首页学无止境
Maven(六):Maven的使用——继承与聚合
Maven(六):Maven的使用——继承与聚合
前言
本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!
一、实验九:继承
1、概念
Maven
工程之间,A
工程继承B
工程
B
工程:父工程
A
工程:子工程
本质上是A
工程的pom.xml
中的配置继承了B
工程中pom.xml
的配置。
2、作用
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。
它的背景是:
对一个比较大型的项目进行了模块拆分。 一个
project
下面,创建了很多个module
。 每一个module
都需要配置自己的依赖信息。
它背后的需求是:
⭕ 在每一个
module
中各自维护各自的依赖信息很容易发生出入,不易统一管理。
⭕ 使用同一个框架内的不同jar
包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一。⭕ 使用框架时所需要的
jar
包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的
jar
包;又能够将以往的经验沉淀下来,节约时间和精力。
3、举例
在一个工程中依赖多个
Spring
的jar
包
TIP
[INFO] +- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] | - commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- org.springframework:spring-beans:jar:4.0.0.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.0.0.RELEASE:compile
[INFO] +- org.springframework:spring-expression:jar:4.0.0.RELEASE:compile
[INFO] +- org.springframework:spring-aop:jar:4.0.0.RELEASE:compile
[INFO] | - aopalliance:aopalliance:jar:1.0:compile
使用
Spring
时要求所有Spring
自己的jar
包版本必须一致。为了能够对这些jar
包的版本进行统一管理,我们使用继承这个机制,将所有版本信息统一在父工程中进行管理。
4、操作
4.1 创建父工程
创建的过程和前面创建
pro01-maven-java
一样。
工程名称:pro03-maven-parent
工程创建好之后,要修改它的打包方式:
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>
只有打包方式为
pom
的Maven
工程能够管理其他Maven
工程。打包方式为pom
的Maven
工程中不写业务代码,它是专门管理其他Maven
工程的工程
4.2 创建模块工程
模块工程类似于
IDEA
中的module
,所以需要进入pro03-maven-parent
工程的根目录,然后运行mvn archetype:generate
命令来创建模块工程。
假设,我们创建三个模块工程:
4.3 查看被添加新内容的父工程 pom.xml
下面 modules
和 module
标签是聚合功能的配置
<modules>
<module>pro04-maven-module</module>
<module>pro05-maven-module</module>
<module>pro06-maven-module</module>
</modules>
4.4 解读子工程的pom.xml
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro04-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->
4.5 在父工程中配置依赖的统一管理
<!-- 使用dependencyManagement标签配置对依赖的管理 -->
<!-- 被管理的依赖并没有真正被引入到工程 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
4.6 子工程中引用那些被父工程管理的依赖
关键点:省略版本号
<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉。 -->
<!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 -->
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
<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-expression</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
</dependencies>
4.7 在父工程中升级依赖信息的版本
……
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
……
然后在子工程中运行
mvn dependency:list
,效果如下:
TIP
[INFO] org.springframework:spring-aop:jar:4.1.4.RELEASE:compile
[INFO] org.springframework:spring-core:jar:4.1.4.RELEASE:compile
[INFO] org.springframework:spring-context:jar:4.1.4.RELEASE:compile
[INFO] org.springframework:spring-beans:jar:4.1.4.RELEASE:compile
[INFO] org.springframework:spring-expression:jar:4.1.4.RELEASE:compile
4.8 在父工程中声明自定义属性
<!-- 通过自定义属性,统一指定Spring的版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 自定义标签,维护Spring版本数据 -->
<atguigu.spring.version>4.3.6.RELEASE</atguigu.spring.version>
</properties>
在需要的地方使用${}的形式来引用自定义的属性名:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${atguigu.spring.version}</version>
</dependency>
真正实现“一处修改,处处生效”。
5、实际意义
编写一套符合要求、开发各种功能都能正常工作的依赖组合并不容易。如果公司里已经有人总结了成熟的组合方案,那么再开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。
如上图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。
二、实验十:聚合
1、聚合本身的含义
部分组成整体
动画片《战神金刚》中的经典台词:“我来组成头部!我来组成手臂!”就是聚合关系最生动的体现。
2、Maven 中的聚合
使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目。
⭕ 项目:整体
⭕ 模块:部分
概念的对应关系:
⭕ 从继承关系角度来看:
父工程 子工程
⭕ 从聚合关系角度来看:
总工程 模块工程
3、好处
⭕ 一键执行
Maven
命令:很多构建命令都可以在“总工程”中一键执行。以
mvn install
命令为例:Maven
要求有父工程时先安装父工程;有依赖的工程时,先安装被依赖的工程。我们自己考虑这些规则会很麻烦。但是工程聚合之后,在总工程执行mvn install
可以一键完成安装,而且会自动按照正确的顺序执行。
⭕ 配置聚合之后,各个模块工程会在总工程中展示一个列表,让项目中的各个模块一目了然。
4、聚合的配置
在总工程中配置
modules
即可:
<modules>
<module>pro04-maven-module</module>
<module>pro05-maven-module</module>
<module>pro06-maven-module</module>
</modules>
5、依赖循环问题
如果
A
工程依赖B
工程,B
工程依赖C
工程,C
工程又反过来依赖A
工程,那么在执行构建操作时会报下面的错误:
[ERROR] [ERROR] The projects in the reactor contain a cyclic reference:
这个错误的含义是:循环引用。