Maven多模块管理

1.多模块场景描述

现在有一个可发布的web应用【application】,该应用由各个业务模块【bussinessModel】组成。

【bussinessModel】:业务模块

  1. 是项目真正要实现的业务,如订单管理、会员管理等。
  2. 依赖于公共模块commonModal和第三方模块。

【commonModal】:公共模块

  1. 提供公共的基础服务,如工具类、常量类等。
  2. 同样依赖于第三方模块。

【第三方模块】:各类框架如Spring、MyBatis等。整个项目都是依赖这些第三方模块开发的。

Maven多模块管理_第三方模块

那么如何通过Maven管理该项目呢?

2.Maven多模块管理思路分析

项目管理要求:

  1. 需要让项目中各个模块所使用依赖的版本保持一致,如果各个模块的版本都不一样,那么整个项目就可能出问题。
  2. 需要让项目中各个模块使用的插件版本保持一致。

要实现上述要求,需要创建一个统领所有模块的父模块。在父模块中添加整个项目所需的所有依赖和插件,统一规定版本。

Maven多模块管理_多模块_02

3.Maven多模块管理方式

多模块管理实现方式:

  1. 第一种:父模块和子模块并列
  2. 第二种:父模块包含子模块
  3. 第三种:多个父模块并列,每个父模块包含各自子模块

3.1第一种:父模块与子模块并列

3.1.1新建空项目工程

新建一个空的项目工程:maven-modules-project

Maven多模块管理_多模块_03

3.1.2新建父模块

在当前空项目工程中,新建一个maven模块,作为父模块。

Maven多模块管理_版本号_04

当然,欲练神功,必先自宫,要使一个模块成为父模块,有以下两点要求:

  1. packaging标签里的文本内容必须为pom。
  2. 删除src目录,父模块中不需要写代码。

packaging标签指定的是打包方式,默认为jar。如果当前pom文件中没有packaging标签,那么默认就是打jar包。

标准父模块:

Maven多模块管理_maven_05

3.1.3新建maven java子模块

pom:项目对象模型(Project Object Module),该文件是可以被子模块继承的,maven多模块管理就是让子模块的pom文件继承父模块的pom文件。

新建子maven模块:

Maven多模块管理_版本号_06

查看子模块的pom文件:

Maven多模块管理_第三方模块_07

查看父模块中新加的内容:

Maven多模块管理_多模块_08

3.1.4新建maven web子模块

创建maven web子模块与创建maven java子模块的方式一样,只不过需要使用archetype-webapp模板

Maven多模块管理_java_09

然后指定继承父模块的pom文件,并且位于父模块的同级目录下。

Maven多模块管理_maven_10

修改web子模块的pom文件:

与java子模块基本相同,只不过web模块需要指定packaging标签里的文本内容为war

Maven多模块管理_第三方模块_11

3.2第二种:父模块包含子模块

3.2.1新建空项目工程

新建一个空的项目工程:maven-modules-project2

Maven多模块管理_java_12

3.2.2新建父模块

在当前空项目工程中,新建一个maven模块,作为父模块。

Maven多模块管理_java_13

同样删除src目录,并设置packaging标签文本内容为pom

Maven多模块管理_第三方模块_14

3.2.3新建子模块

与第一种方式不同的是,这里要让子模块位于父模块的根目录下,让父模块包含子模块。

Maven多模块管理_多模块_15

查看创建的子模块:

发现父模块包含子模块,同时子模块的pom中没有了指向父pom文件的relativePath标签。

Maven多模块管理_多模块_16

这是因为这种方式创建的子模块与父模块的pom文件位于同级目录,可以直接访问到,不需要手动指定。

Maven多模块管理_maven_17

3.3第三种:多个父模块并列,每个父模块包含各自子模块

3.2.1新建空项目工程

新建一个空的项目工程:maven-modules-project3

3.2.2新建父模块

在当前空项目工程中,新建三个maven模块,都修改为父模块。

Maven多模块管理_多模块_18

3.2.3新建子模块

使用包含方式创建三个父模块各自的子模块:

Maven多模块管理_第三方模块_19

4.父模块与子模块

以前面第一种管理方式的项目为例

4.1模块的转换

4.1.1子模块可以成为父模块

只要子模块满足父模块的两个要求,就可以成为父模块,创建自己的子模块。

将子模块002-maven-java修改成父模块:

Maven多模块管理_第三方模块_20

创建002-maven-java的子模块:

Maven多模块管理_java_21

查看子模块004-002-maven-java的pom:

Maven多模块管理_maven_22

查看父模块002-maven-java的pom文件变化:

Maven多模块管理_多模块_23

查看002-maven-java的父模块001-maven-parent的pom文件变化:

Maven多模块管理_java_24

001模块的pom文件只会指定其子模块002,不会指定002的子模块004。

但是004本质上还是001的后代,还是可以继承001的东西。

Maven多模块管理_多模块_25

子子孙孙无穷尽也,maven的父子模块继承,理论上可以一层层套下去。但是没有必要,在开发中大多只需要父和子两层关系就够了,延续再深也没有意义。

4.1.2手动修改孤儿模块为子模块

在我们创建子模块时可能会操作失误,子模块没有继承父模块就创建了出来,成了孤儿模块。

Maven多模块管理_java_26

孤儿模块的pom:

Maven多模块管理_多模块_27

我们可以手动修改孤儿模块的pom,使其继承父模块。

Maven多模块管理_版本号_28

再在父模块的pom中添加此模块即可

Maven多模块管理_maven_29

4.2父模块对依赖的管理

4.2.1子模块继承父模块的所有依赖

我们在父模块里添加两个依赖,刷新Maven,所有子模块都继承了这两个依赖,且版本一致,同时子模块本身不需要添加任何依赖。

这就实现了让项目中所有模块的依赖版本一致。

Maven多模块管理_第三方模块_30

4.2.2设置父模块有条件地管理依赖

上一步中,子模块会无条件继承父模块的所有依赖,导致的问题是:子模块本不需要继承的依赖也会被继承,这就大大增加了项目模块最终打包的大小,也可能为上线埋下了隐患。

为此,我们不能无条件地让子模块继承所有依赖。如何实现呢?我们可以在父模块的pom中使用dependencyManagement标签。

该标签的作用是加强依赖管理,由该标签包含的依赖不会让子模块无条件地继承。

使用dependencyManagement标签后:

Maven多模块管理_版本号_31

声明式依赖:当子模块需要某个依赖时,声明该依赖即可继承(子模块声明依赖不需要指定版本,默认以父模块中依赖的版本为准),而父工程实际只是管理依赖的版本号。

Maven多模块管理_maven_32

4.2.3父模块单独管理依赖版本号的方式

父模块只是管理依赖的版本号,但是在dependencies标签里一个个管理又很麻烦,那么不如我们直接把所有的版本号拿出来进行管理。

如何实现呢?可以使用properties标签。

在properties标签中,可以自定义标签名来管理依赖的版本号,通常自定义的标签名为:【项目名+version】

在dependencies标签里指定依赖版本号时,使用${自定义标签}代替版本号。

Maven多模块管理_多模块_33

4.3子模块继承父模块的插件

我们来查看当前项目所有子模块的jdk编译版本号:均为1.5

Maven多模块管理_maven_34

我们在父模块里设置jkd的编译插件,指定为1.8版本

Maven多模块管理_第三方模块_35

重新查看:

Maven多模块管理_第三方模块_36