1. 分模块设计与开发
在开发大型 Java 项目时,将项目拆分为多个模块进行开发,称为分模块设计。这种设计方法解决了项目不易维护、难以复用组件的问题。例如,电商项目可以将商品、购物车、订单、用户等功能分别放在不同的模块中。这样不仅可以提高项目的可维护性,还能通过复用组件方便其他项目使用这些模块中的通用工具类或实体类。
而且分模块设计之后,如果我们需要用到另外一个模块的功能,我们直接依赖模块就可以了。比如商品模块、搜索模块、购物车订单模块都需要依赖于通用组件当中封装的一些工具类,我只需要引入通用组件的坐标就可以了。
2. 继承与聚合
2.1 继承
Maven 的继承机制允许子模块从父模块继承配置,简化了重复依赖的声明。例如,多个模块都需要 lombok
依赖,可以将其提取到父模块 xxx-parent
中,子模块不再需要单独配置此依赖。
2.1.1 继承结构
创建父工程 xxx-parent
,配置通用依赖和插件,子模块继承父工程。
在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
(1)概念:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。
(2)作用:简化依赖配置、统一管理依赖版本
(3)实现:
子工程中配置parent:
<relativePath>父工程的pom.xml</relativePath>
../ 代表的上一级目录
例如:../pom.xml,指父工程pom.xml在自己的上一级
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<relativePath>....</relativePath>
</parent>
2.1.2 多重继承
由于 Maven 不支持多继承,可以通过“多重继承”解决冲突。即让 xxx-parent
继承 spring-boot-starter-parent
,然后子模块继承 xxx-parent
,确保两者配置均生效。
父工程xxx-parent的pom.xml文件配置如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.itheima</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
Maven打包方式:
jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)
war:普通web程序打包,需要部署在外部的tomcat服务器中运行
pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理
2.1.3 版本锁定
2.1.3.1 统一管理依赖版本
在项目开发中,同一依赖可能在多个模块中使用,为了保证版本一致性,可以使用 Maven 的 dependencyManagement
来统一管理依赖的版本号。子模块无需显式声明版本号,只需在父模块中统一管理和修改。
在maven中,可以在父工程的pom文件中通过 <dependencyManagement> 来统一管理依赖版本。
父工程:
<!--统一管理依赖版本-->
<dependencyManagement>
<dependencies>
<!--JWT令牌-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
</dependencyManagement>
子工程:
<dependencies>
<!--JWT令牌-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies>
注意:
(1)在父工程中所配置的 <dependencyManagement> 只能统一管理依赖版本,并不会将这个依赖直接引入进来。 这点和 <dependencies> 是不同的。
(2)子工程要使用这个依赖,还是需要引入的,只是此时就无需指定 <version> 版本号了, 父工程统一管理。变更依赖版本,只需在父工程中统一变更。
2.1.3.2 属性配置
我们也可以通过自定义属性及属性引用的形式,在父工程中将依赖的版本号进行集中管理维护。 具体语法为:
(1)自定义属性
<properties>
<lombok.version>1.18.24</lombok.version>
</properties>
(2)引用属性
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
接下来,我们就可以在父工程中,使用自定义属性,将所有的版本号,都集中管理维护起来。
版本集中管理之后,我们要想修改依赖的版本,就只需要在父工程中自定义属性的位置,修改对应的属性值即可。
2.2 聚合
如果开发一个大型项目,拆分的模块很多,模块之间的依赖关系错综复杂,那 此时要进行项目的打包、安装操作,是非常繁琐的。 maven的聚合就是来解决这个问题的,通过maven的聚合就可以轻松实现项目的一键构建(清理、编译、测试、打包、安装等)。
Maven 的聚合功能可以将多个模块整合到一个项目中,通过父模块统一构建项目。聚合工程配置子模块,通过 modules
标签将模块整合。打包时无需逐个模块操作,可以一次性构建整个项目。
聚合:将多个模块组织成一个整体,同时进行项目的构建。
聚合工程:一个不具有业务功能的“空”工程(有且仅有一个pom文件) 【PS:一般来说,继承关
系中的父工程与聚合关系中的聚合工程是同一个】
作用:快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)
在maven中,我们可以在聚合工程(父工程)中通过 <moudules> 设置当前聚合工程所包含的子模块的名称。我们可以在 xxx-parent中,添加如下配置,来指定当前聚合工程,需要聚合的模块:
<!--聚合其他模块-->
<modules>
<module>../tlias-pojo</module>
<module>../tlias-utils</module>
<module>../tlias-web-management</module>
</modules>
那此时,我们要进行编译、打包、安装操作,就无需在每一个模块上操作了。只需要在聚合工程上,统 一进行操作就可以了。
2.3 继承与聚合对比
2.3.1 作用
聚合用于快速构建项目
继承用于简化依赖配置、统一管理依赖版本
2.3.2 相同点
聚合与继承的pom.xml文件打包方式均为pom,通常将两种关系制作到同一个pom文件中
聚合与继承均属于设计型模块,并无实际的模块内容
2.3.3 不同点
聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些
继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
3. 父工程总结
3.1 继承spring-boot-starter-parent
让 xxx-parent
继承 spring-boot-starter-parent
,然后子模块继承 xxx-parent
,确保两者配置均生效。
3.2 配置公共依赖
在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。
3.3 统一管理依赖版本
在 dependencyManagement
中锁定所有子模块的依赖版本,确保模块间的依赖版本一致,避免版本冲突。
3.3.1 自定义版本号属性
通过自定义属性及属性引用的形式,在父工程中将依赖的版本号进行集中管理维护。
3.3.2 引用自定义属性
接下来,我们就可以在父工程中,使用自定义属性,将所有的版本号,都集中管理维护起来。
版本集中管理之后,我们要想修改依赖的版本,就只需要在父工程中自定义属性的位置,修改对应的属性值即可。
3.4 模块聚合
在maven中,我们可以在聚合工程(父工程)中通过 <moudules> 设置当前聚合工程所包含的子模块的名称。
使用 modules
标签将多个子模块聚合到父工程中,统一管理、构建和打包各个子模块,避免逐个模块独立构建。