现在有一个可发布的web应用【application】,该应用由各个业务模块【bussinessModel】组成。
【bussinessModel】:业务模块
【commonModal】:公共模块
【第三方模块】:各类框架如Spring、MyBatis等。整个项目都是依赖这些第三方模块开发的。
那么如何通过Maven管理该项目呢?
项目管理要求:
要实现上述要求,需要创建一个统领所有模块的父模块。在父模块中添加整个项目所需的所有依赖和插件,统一规定版本。
多模块管理实现方式:
新建一个空的项目工程:maven-modules-project
在当前空项目工程中,新建一个maven模块,作为父模块。
当然,欲练神功,必先自宫,要使一个模块成为父模块,有以下两点要求:
packaging标签指定的是打包方式,默认为jar。如果当前pom文件中没有packaging标签,那么默认就是打jar包。
标准父模块:
pom:项目对象模型(Project Object Module),该文件是可以被子模块继承的,maven多模块管理就是让子模块的pom文件继承父模块的pom文件。
新建子maven模块:
查看子模块的pom文件:
查看父模块中新加的内容:
创建maven web子模块与创建maven java子模块的方式一样,只不过需要使用archetype-webapp模板
然后指定继承父模块的pom文件,并且位于父模块的同级目录下。
修改web子模块的pom文件:
与java子模块基本相同,只不过web模块需要指定packaging标签里的文本内容为war
新建一个空的项目工程:maven-modules-project2
在当前空项目工程中,新建一个maven模块,作为父模块。
同样删除src目录,并设置packaging标签文本内容为pom
与第一种方式不同的是,这里要让子模块位于父模块的根目录下,让父模块包含子模块。
查看创建的子模块:
发现父模块包含子模块,同时子模块的pom中没有了指向父pom文件的relativePath标签。
这是因为这种方式创建的子模块与父模块的pom文件位于同级目录,可以直接访问到,不需要手动指定。
新建一个空的项目工程:maven-modules-project3
在当前空项目工程中,新建三个maven模块,都修改为父模块。
使用包含方式创建三个父模块各自的子模块:
以前面第一种管理方式的项目为例
只要子模块满足父模块的两个要求,就可以成为父模块,创建自己的子模块。
将子模块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的父子模块继承,理论上可以一层层套下去。但是没有必要,在开发中大多只需要父和子两层关系就够了,延续再深也没有意义。
在我们创建子模块时可能会操作失误,子模块没有继承父模块就创建了出来,成了孤儿模块。
孤儿模块的pom:
我们可以手动修改孤儿模块的pom,使其继承父模块。
再在父模块的pom中添加此模块即可
我们在父模块里添加两个依赖,刷新Maven,所有子模块都继承了这两个依赖,且版本一致,同时子模块本身不需要添加任何依赖。
这就实现了让项目中所有模块的依赖版本一致。
上一步中,子模块会无条件继承父模块的所有依赖,导致的问题是:子模块本不需要继承的依赖也会被继承,这就大大增加了项目模块最终打包的大小,也可能为上线埋下了隐患。
为此,我们不能无条件地让子模块继承所有依赖。如何实现呢?我们可以在父模块的pom中使用dependencyManagement标签。
该标签的作用是加强依赖管理,由该标签包含的依赖不会让子模块无条件地继承。
使用dependencyManagement标签后:
声明式依赖:当子模块需要某个依赖时,声明该依赖即可继承(子模块声明依赖不需要指定版本,默认以父模块中依赖的版本为准),而父工程实际只是管理依赖的版本号。
父模块只是管理依赖的版本号,但是在dependencies标签里一个个管理又很麻烦,那么不如我们直接把所有的版本号拿出来进行管理。
如何实现呢?可以使用properties标签。
在properties标签中,可以自定义标签名来管理依赖的版本号,通常自定义的标签名为:【项目名+version】
在dependencies标签里指定依赖版本号时,使用${自定义标签}
代替版本号。
我们来查看当前项目所有子模块的jdk编译版本号:均为1.5
我们在父模块里设置jkd的编译插件,指定为1.8版本
重新查看: