目录
一、引入
maven是一款构建和管理java项目的工具。
在实际的开发场景中,我们一般会将一个项目拆分为多个模块,让每个模块实现自己特定的功能。这样一来,极大方便了项目的管理、维护、拓展,也方便了模块之间的相互调用、共享资源。这种思想是高级maven的基础。
但是我们在分模块设计的时候还会遇到一些比较繁琐的操作:
- 有一些依赖在每一个项目内都被调用,使用起来非常繁琐(继承解决)
- 有些依赖并不一定被每个项目调用,但是也有多个项目调用的情况,那么这个时候依赖的版本如果要修改就会很麻烦,需要到每一个项目的pom文件中去注意修改,而且会有以来版本不一致的风险(继承解决)
- 在项目进行打包的时候,需要逐级根据依赖关系进行一一打包,也非常繁琐(聚合解决)
那么如果来解决这些问题呢?那就是项目的继承和聚合。
二、Maven的继承
1.1 依赖被重复调用的解决
1.1.1 存在问题:
打个比方,如果我们在三个模块中都引入了一个Lombok依赖,那么在以后的开发中,如果做一个大型的项目,这些重复被调用的依赖会非常多,而且项目的数量也会非常多,这种方法是不是非常的繁琐?
1.1.2 解决方法:
- 再创建一个父工程 tlias-parent
- 然后让上述的三个模块 tlias-pojo、tlias-utils、tlias-web-management 都来继承这个父工程
- 将各个模块中都共有的依赖,都提取到父工程 tlias-parent中进行配置,只要子工程继承了父工程,依赖它也会继承下来
这样就无需在各个子工程中进行配置了。
但是在对设想进行实践之前,还要插入一个小细节 --->>>
细节:在Maven的继承中,一个子项目,对应一个父工程。(一个儿子不能有多个父亲)
但是在项目当中,启动项目是一个springboot项目,而springboot项目都会有一个统一的父工程,就是spring-boot-starter-parent
假设tlias-web-management是一个启动项目:
- 它既要继承一个自定义的父工程,简化繁琐的依赖引入
- 又想不影响其继承springboot框架的父工程spring-boot-starter-parent
它既要又要该怎么办?
我们不妨联想一下Java中的继承,虽然不能多继承,但是不是可以进行多层继承呀?
-------解决:
我们让启动项目和别的项目一样继承自定义的父工程,再让父工程去继承springboot框架的父工程spring-boot-starter-parent
咱们整个“爷工程”,这个问题就迎刃而解了。
1.1.2.1 实现Maven继承
1.首先我们在原有项目的基础上新建一个模块,命名为tlias-parent,作为这些模块的父工程。
2.将Maven的打包方式设置为pom。
Maven打包方式:
jar(默认):普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)
war:普通web程序打包,需要部署在外部的tomcat服务器中运行
pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理
3.继承SpringBoot父工程。
4.将目标子工程继承这个父工程tlias-parent。
注意:
- 继承的时候需要配置依赖路径,根据自身的路径进行编写。
- 配置好继承关系后,组织名会自动继承下来,<groupId>com.itheima</groupId>可以删除掉。
其他目标子工程操作如上:
5.在父工程中配置各个子工程共有的依赖,如Lombok。
我们删除掉子项目pom文件中的Lombok依赖,刷新一下maven。
打开右边的maven窗口就可以看见,子项目都继承了父工程,注入了Lombok的依赖:
那么这样一来,第一个问题就解决完成啦~
1.2 依赖版本管理和修改繁琐的解决
1.2.1 存在问题:
有些依赖并不一定被每个项目调用,但是也有多个项目调用的情况,那么这个时候依赖的版本如果要修改就会很麻烦,需要到每一个项目的pom文件中去注意修改,而且会有以来版本不一致的风险!
1.2.2 解决方法:
- 我们在父工程中把常用的依赖放在 <dependencyManagement> 中进行统一管理
- 在子项目调用该依赖的时候,不用指定依赖版本,由父工程统一配置
- 在需要修改依赖版本的时候,不需要到子工程的pom文件中逐一修改,直接在父工程的配置属性<properties>中修改即可
1.2.2.1 实现Maven继承的版本管理
1.把常用的依赖放在<dependencyManagement> 中进行统一管理。并在<properties>中配置版本信息,让<dependencyManagement> 中的依赖引用
注意:<dependencyManagement>里面的依赖不会注入到父工程,只是负责版本的管理!
2.将子项目的相关依赖版本删去即可。
这样,以后在对这些依赖的版本进行管理和修改的时候就方便多了!
三、Maven的聚合
1.1 项目生命周期执行繁琐的解决
1.1.1 存在问题:
如果想将项目打包到本地或者供他人使用,我们需要进行maven项目生命周期中的打包操作。
我们的项目被拆分为多个模块,而模块之间的关系,可能错综复杂。
比如:
tlias-web-management 模块的父工程是 tlias-parent
该模块又依赖了tlias-pojo、 tlias-utils模块
那此时,我们要想将 tlias-web-management 模块打包,是比较繁琐的
因为在进行项目打包时:
- maven会从本地仓库中来查找tlias-parent父工程,以及它所依赖的模块 tlias-pojo、tlias-utils
- 而本地仓库目前是没有这几个依赖的
- 所以,我们再打包tlias-web-management 模块前,需要将 tlias-parent、tlias-pojo、 tlias-utils分别执行install生命周期安装到maven的本地仓库
- 然后再针对于 tlias-web-management 模块执行package进行打包操作
这样的操作逻辑,如果遇到关系更复杂的项目依赖关系,分分钟让人头昏眼花~
因此我们需要引入Maven的聚合来解决这个问题,让maven各个生命周期的操作更简单便捷,以快速构建项目。
1.1.2 解决方法:
- 创建一个聚合工程(这是一个不具有业务的空工程,只有一个pom文件,一般继承关系中的父工程和聚合工程是同一个工程,所以不用再额外创建)
- 在聚合工程中通过<module>设置当前聚合工程所包含的子模块的名称
1.1.2.1 实现Maven聚合
1.在聚合工程中通过<module>设置当前聚合工程所包含的子模块的名称。
自定义的依赖关系都要写。
2.刷新maven,打开右侧maven工具,我们对父工程的生命周期进行执行测试。
当我们执行clear清理的时候,聚合的项目全部都对其执行文件进行了清理。
我们再点击package进行打包,可以看见打包操作也一步到位了,不用考虑依赖之间的关系,非常简单快捷,大大加快了项目的构建速度。
注意:在打包之前,先关闭test测试流程,因为测试流程可能会导致一些意料之外的报错(我的项目因为没有关闭测试流程,它跑去测试我的jwt令牌,但是令牌已经过期了,会产生报错导致无法打包)
四、总结
4.1 继承与聚合
作用:
- 聚合用于快速构建项目
- 继承用于简化依赖配置、统一管理依赖
相同点:
- 聚合与继承的pom.xml文件打包方式均为pom,通常将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
不同点:
- 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
4.2 小结
高级Maven内容是企业级开发的重要部分,能够极大提升项目的完成效率和整体优化。
通过引入 Maven 的继承和聚合机制,我们可以有效地解决多个模块开发中常见的繁琐操作。
- Maven 继承让我们可以将公共依赖和版本管理提取到父工程中,极大地简化了每个模块的依赖管理,也保证了依赖版本的一致性。
- 而 Maven 聚合则通过创建一个聚合工程,让我们能够一次性对所有模块进行构建和打包操作,避免了逐一执行的麻烦。
- 这两者的结合,使得我们在面对复杂的多模块项目时,能够更加轻松地管理和维护。通过将公共依赖抽离到父工程,开发者可以专注于模块自身的业务逻辑实现。而通过聚合工程,我们可以方便地进行全局的打包和部署,提高项目的构建效率。这种结构不仅适用于企业级的项目开发,也能帮助团队在不断迭代的过程中保持项目的高效和规范性。