随着项目的不断发展,需求的不断细化与添加,代码越来越多,结构也越来越复杂,这时候就会遇到各种问题
不同方面的代码之间相互耦合,这时候一系统出现问题很难定位到问题的出现原因,即使定位到问题也很难修正问题,可能在修正问题的时候引入更多的问题。
多方面的代码集中在一个整体结构中,新入的开发者很难对整体项目有直观的感受,增加了新手介入开发的成本,需要有一个熟悉整个项目的开发者维护整个项目的结构(通常在项目较大且开发时间较长时这是很难做到的)。
开发者对自己或者他人负责的代码边界很模糊,这是复杂项目中最容易遇到的,导致的结果就是开发者很容易修改了他人负责的代码且代码负责人还不知道,责任追踪很麻烦。
将一个复杂项目拆分成多个模块是解决上述问题的一个重要方法。 拆分的好处
推荐安照功能拆分,后期方便转换成微服务架构
例如,在电商系统中如下module
搭建多模块项目,需要使用 maven 的继承和聚合,其中聚合负责将多个模块集中在一起进行管理,继承则负责各子模块中的公共配置
我使用的是idea
删掉src
pom文件内容
在项目下创建子模块
套路与创建普通项目一致
注意变化
module 的 pom 文件发生了变化
新增了两段配置
<packaging>pom</packaging> <modules> <module>module-util</module> </modules> 复制代码
pom 是最简单的打包类型。不像jar和war,它生成的构件只有它本身。将 packaging 申明为 pom 则意味着没有代码需要测试或者编译,也没有资源需要处理。
由于我们使用了聚合,所以打包方式必须为pom,否则无法构建。
<modules> <module>module-util</module> </modules> 复制代码
module的值是子模块相对于当前 POM 的 路径 。
再看子模块中的 pom
也是分成两个部分
<parent> <groupId>com.wqlm</groupId> <artifactId>module</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>module-util</artifactId> 复制代码
<parent> <groupId>com.wqlm</groupId> <artifactId>module</artifactId> <version>1.0-SNAPSHOT</version> <!--<relativePath/>--> </parent> 复制代码
声明了该模块继承自 com.wqlm:module:1.0-SNAPSHOT ,其实这里面还省略了 <relativePath></relativePath>
由于 relativePath 默认是 ../pom.xml
而我们的子项目确实在父项目的下一级目录中,所以是可以不用填写的
Maven首先在当前构建项目的环境中查找父pom,然后项目所在的文件系统查找,然后是本地存储库,最后是远程repo。
artifactId是子模块的组件id,由于继承了父pom,所以 groupId 、 version 也可以不写,不写的话就默认继承自父pom
如上所示,在创建多个模块之后,可以在父pom中添加公共配置,然后所有的子模块都会继承这些配置。除此之外,还可以通用对子模块进行 编译、打包、安装... 操作
如果子模块间有依赖关系,需要在 dependency
中引入要依赖的子模块,如图
上图中子模块 module-common:1.0-SNAPSHOT 依赖了 module-util:1.0-SNAPSHOT 。有一个问题不知道大家想过没,子模块间相关依赖,而且还有关系版本号,相互依赖一多起来,版本号很容易冲突。
解决这个问题的办法也很简单,就是使用** maven dependencyManagement**。 在父pom中加入 dependencyManagement
然后子模块中引用时,就可以不带版本号了
只要所以子模块都通过这种方式来引用其他子模块,那么在子模块的版本就都是父项目中定义都版本
关于 maven dependencyManagement 详情请参考 maven 依赖版本管理——depencyManagement