1.多模块场景描述
现在有一个可发布的web应用【application】,该应用由各个业务模块【bussinessModel】组成。
【bussinessModel】:业务模块
- 是项目真正要实现的业务,如订单管理、会员管理等。
- 依赖于公共模块commonModal和第三方模块。
【commonModal】:公共模块
- 提供公共的基础服务,如工具类、常量类等。
- 同样依赖于第三方模块。
【第三方模块】:各类框架如Spring、MyBatis等。整个项目都是依赖这些第三方模块开发的。
那么如何通过Maven管理该项目呢?
2.Maven多模块管理思路分析
项目管理要求:
- 需要让项目中各个模块所使用依赖的版本保持一致,如果各个模块的版本都不一样,那么整个项目就可能出问题。
- 需要让项目中各个模块使用的插件版本保持一致。
要实现上述要求,需要创建一个统领所有模块的父模块。在父模块中添加整个项目所需的所有依赖和插件,统一规定版本。
3.Maven多模块管理方式
多模块管理实现方式:
- 第一种:父模块和子模块并列
- 第二种:父模块包含子模块
- 第三种:多个父模块并列,每个父模块包含各自子模块
3.1第一种:父模块与子模块并列
3.1.1新建空项目工程
新建一个空的项目工程:maven-modules-project
3.1.2新建父模块
在当前空项目工程中,新建一个maven模块,作为父模块。
当然,欲练神功,必先自宫,要使一个模块成为父模块,有以下两点要求:
- packaging标签里的文本内容必须为pom。
- 删除src目录,父模块中不需要写代码。
packaging标签指定的是打包方式,默认为jar。如果当前pom文件中没有packaging标签,那么默认就是打jar包。
标准父模块:
3.1.3新建maven java子模块
pom:项目对象模型(Project Object Module),该文件是可以被子模块继承的,maven多模块管理就是让子模块的pom文件继承父模块的pom文件。
新建子maven模块:
查看子模块的pom文件:
查看父模块中新加的内容:
3.1.4新建maven web子模块
创建maven web子模块与创建maven java子模块的方式一样,只不过需要使用archetype-webapp模板
然后指定继承父模块的pom文件,并且位于父模块的同级目录下。
修改web子模块的pom文件:
与java子模块基本相同,只不过web模块需要指定packaging标签里的文本内容为war
3.2第二种:父模块包含子模块
3.2.1新建空项目工程
新建一个空的项目工程:maven-modules-project2
3.2.2新建父模块
在当前空项目工程中,新建一个maven模块,作为父模块。
同样删除src目录,并设置packaging标签文本内容为pom
3.2.3新建子模块
与第一种方式不同的是,这里要让子模块位于父模块的根目录下,让父模块包含子模块。
查看创建的子模块:
发现父模块包含子模块,同时子模块的pom中没有了指向父pom文件的relativePath标签。
这是因为这种方式创建的子模块与父模块的pom文件位于同级目录,可以直接访问到,不需要手动指定。
3.3第三种:多个父模块并列,每个父模块包含各自子模块
3.2.1新建空项目工程
新建一个空的项目工程:maven-modules-project3
3.2.2新建父模块
在当前空项目工程中,新建三个maven模块,都修改为父模块。
3.2.3新建子模块
使用包含方式创建三个父模块各自的子模块:
4.父模块与子模块
以前面第一种管理方式的项目为例
4.1模块的转换
4.1.1子模块可以成为父模块
只要子模块满足父模块的两个要求,就可以成为父模块,创建自己的子模块。
将子模块002-maven-java修改成父模块:
创建002-maven-java的子模块:
查看子模块004-002-maven-java的pom:
查看父模块002-maven-java的pom文件变化:
查看002-maven-java的父模块001-maven-parent的pom文件变化:
001模块的pom文件只会指定其子模块002,不会指定002的子模块004。
但是004本质上还是001的后代,还是可以继承001的东西。
子子孙孙无穷尽也,maven的父子模块继承,理论上可以一层层套下去。但是没有必要,在开发中大多只需要父和子两层关系就够了,延续再深也没有意义。
4.1.2手动修改孤儿模块为子模块
在我们创建子模块时可能会操作失误,子模块没有继承父模块就创建了出来,成了孤儿模块。
孤儿模块的pom:
我们可以手动修改孤儿模块的pom,使其继承父模块。
再在父模块的pom中添加此模块即可
4.2父模块对依赖的管理
4.2.1子模块继承父模块的所有依赖
我们在父模块里添加两个依赖,刷新Maven,所有子模块都继承了这两个依赖,且版本一致,同时子模块本身不需要添加任何依赖。
这就实现了让项目中所有模块的依赖版本一致。
4.2.2设置父模块有条件地管理依赖
上一步中,子模块会无条件继承父模块的所有依赖,导致的问题是:子模块本不需要继承的依赖也会被继承,这就大大增加了项目模块最终打包的大小,也可能为上线埋下了隐患。
为此,我们不能无条件地让子模块继承所有依赖。如何实现呢?我们可以在父模块的pom中使用dependencyManagement标签。
该标签的作用是加强依赖管理,由该标签包含的依赖不会让子模块无条件地继承。
使用dependencyManagement标签后:
声明式依赖:当子模块需要某个依赖时,声明该依赖即可继承(子模块声明依赖不需要指定版本,默认以父模块中依赖的版本为准),而父工程实际只是管理依赖的版本号。
4.2.3父模块单独管理依赖版本号的方式
父模块只是管理依赖的版本号,但是在dependencies标签里一个个管理又很麻烦,那么不如我们直接把所有的版本号拿出来进行管理。
如何实现呢?可以使用properties标签。
在properties标签中,可以自定义标签名来管理依赖的版本号,通常自定义的标签名为:【项目名+version】
在dependencies标签里指定依赖版本号时,使用${自定义标签}
代替版本号。
4.3子模块继承父模块的插件
我们来查看当前项目所有子模块的jdk编译版本号:均为1.5
我们在父模块里设置jkd的编译插件,指定为1.8版本
重新查看: