目标
- 理解并实现分模块开发
(1)按照功能拆分
我们现在的项目都是在一个模块中,比如前面的SSM整合开发。虽然这样做功能也都实现了,但是也存在了一些问题,我们拿银行的项目为例来聊聊这个事。
上面三个场景出现的时间是不相同的,如果非要把三个场景的模块代码放入到一个项目,那么当其中某一个模块代码出现问题,就会导致整个项目无法正常启动,从而导致银行的多个业务都无法正常班理。所以我们会按照功能将项目进行拆分。
(2)按照模块拆分
比如电商的项目中,有订单和商品两个模块,订单中需要包含商品的详细信息,所以需要商品的模型类,商品模块也会用到商品的模型类,这个时候如果两个模块中都写模型类,就会出现重复代码,后期的维护成本就比较高。我们就想能不能将它们公共的部分抽取成一个独立的模块,其他模块要想使用可以像添加第三方jar包依赖一样来使用我们自己抽取的模块,这样就解决了代码重复的问题,这种拆分方式就说我们所说的按照模块拆分。
经过两个案例的分析,我们就知道:
刚刚我们说了可以将domain层进行拆分,除了domain层,我们也可以将其他的层也拆成一个个对立的模块,如:
这样的话,项目中的每一层都可以单独维护,也可以很方便的被别人使用。关于分模块开发的意义,我们就说完了,说了这么多好处,那么该如何实现呢?
前面我们已经完成了SSM整合,接下来,咱们就基于SSM整合的项目来实现对项目的拆分。
将资料\maven_02_ssm
部署到IDEA中,将环境快速准备好,部署成功后,项目的格式如下:
创建一个名称为maven_03_pojo
的jar项目,为什么项目名是从02到03这样创建,原因后面我们会提到,这块的名称可以任意。
在maven_03_pojo
项目中创建com.itheima.domain
包,并将maven_02_ssm
中Book类拷贝到该包中
删除后,maven_02_ssm
项目中用到Book
的类中都会有红色提示,如下:
**说明:**出错的原因是maven_02_ssm
中已经将Book类删除,所以该项目找不到Book类,所以报错
要想解决上述问题,我们需要在maven_02_ssm
中添加maven_03_pojo
的依赖。
在maven_02_ssm
项目的pom.xml添加maven_03_pojo
的依赖
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
因为添加了依赖,所以在maven_02_ssm
中就已经能找到Book类,所以刚才的报红提示就会消失。
maven_02_ssm
项目编译maven_02_ssm
你会在控制台看到如下错误
错误信息为:不能解决maven_02_ssm
项目的依赖问题,找不到maven_03_pojo
这个jar包。
为什么找不到呢?
原因是Maven会从本地仓库找对应的jar包,但是本地仓库又不存在该jar包所以会报错。
在IDEA中是有maven_03_pojo
这个项目,所以我们只需要将maven_03_pojo
项目安装到本地仓库即可。
将需要被依赖的项目maven_03_pojo
,使用maven的install命令,把其安装到Maven的本地仓库中。
安装成功后,在对应的路径下就看到安装好的jar包
**说明:**具体安装在哪里,和你们自己电脑上Maven的本地仓库配置的位置有关。
当再次执行maven_02_ssm
的compile的命令后,就已经能够成功编译。
创建一个名称为maven_04_dao
的jar项目
在maven_04_dao
项目中创建com.itheima.dao
包,并将maven_02_ssm
中BookDao类拷贝到该包中
在maven_04_dao
中会有如下几个问题需要解决下:
项目maven_04_dao
的BookDao接口中Book类找不到报错
解决方案在maven_04_dao
项目的pom.xml中添加maven_03_pojo
项目
<dependencies>
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
dependencies>
项目maven_04_dao
的BookDao接口中,Mybatis的增删改查注解报错
解决方案在maven_04_dao
项目的pom.xml中添加mybatis
的相关依赖
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.6version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
dependencies>
删除Dao包以后,因为maven_02_ssm
中的BookServiceImpl类中有使用到Dao的内容,所以需要在maven_02_ssm
的pom.xml添加maven_04_dao
的依赖
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_04_daoartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
此时在maven_02_ssm
项目中就已经添加了maven_03_pojo
和maven_04_dao
包
再次对maven_02_ssm
项目进行编译,又会报错,如下:
和刚才的错误原因是一样的,maven在仓库中没有找到maven_04_dao
,所以此时我们只需要将maven_04_dao
安装到Maven的本地仓库即可。
将需要被依赖的项目maven_04_dao
,使用maven的install命令,把其安装到Maven的本地仓库中。
安装成功后,在对应的路径下就看到了安装好对应的jar包
当再次执行maven_02_ssm
的compile的指令后,就已经能够成功编译。
将抽取后的项目进行运行,测试之前的增删改查功能依然能够使用。
所以对于项目的拆分,大致会有如下几个步骤:
(1) 创建Maven模块
(2) 书写模块代码
分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。拆分方式可以按照功能拆也可以按照模块拆。
(3)通过maven指令安装模块到本地仓库(install 指令)
团队内部开发需要发布模块功能到团队内部可共享的仓库中(私服),私服我们后面会讲解。
我们现在已经能把项目拆分成一个个独立的模块,当在其他项目中想要使用独立出来的这些模块,只需要在其pom.xml使用标签来进行jar包的引入即可。
其实就是依赖,关于依赖管理里面都涉及哪些内容,我们就一个个来学习下:
我们先来说说什么是依赖:
依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。
格式为:
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
dependencies>
回到我们刚才的项目案例中,打开Maven的面板,你会发现:
在项目所依赖的这些jar包中,有一个比较大的区别就是有的依赖前面有箭头>
,有的依赖前面没有。
那么这个箭头所代表的含义是什么?
打开前面的箭头,你会发现这个jar包下面还包含有其他的jar包
你会发现有两个maven_03_pojo
的依赖被加载到Dependencies中,那么maven_04_dao
中的maven_03_pojo
能不能使用呢?
要想验证非常简单,只需要把maven_02_ssm
项目中pom.xml关于maven_03_pojo
的依赖注释或删除掉
在Dependencies中移除自己所添加maven_03_pojo
依赖后,打开BookServiceImpl的类,你会发现Book类依然存在,可以被正常使用
这个特性其实就是我们要讲解的依赖传递。
依赖是具有传递性的:
说明: A代表自己的项目;B,C,D,E,F,G代表的是项目所依赖的jar包;D1和D2 E1和E2代表是相同jar包的不同版本
(1) A依赖了B和C,B和C有分别依赖了其他jar包,所以在A项目中就可以使用上面所有jar包,这就是所说的依赖传递
(2) 依赖传递有直接依赖和间接依赖
(3)因为有依赖传递的存在,就会导致jar包在依赖的过程中出现冲突问题,具体什么是冲突?Maven是如何解决冲突的?
这里所说的依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突。
情况一: 在maven_02_ssm
的pom.xml中添加两个不同版本的Junit依赖:
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
dependencies>
通过对比,会发现一个结论
情况二: 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
情况三: 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
但是对应上面这些结果,大家不需要刻意去记它。因为不管Maven怎么选,最终的结果都会在Maven的Dependencies
面板中展示出来,展示的是哪个版本,也就是说它选择的就是哪个版本,如:
如果想更全面的查看Maven中各个坐标的依赖关系,可以点击Maven面板中的show Dependencies
在这个视图中就能很明显的展示出jar包之间的相互依赖关系。
依赖传递介绍完以后,我们来思考一个问题,
**说明:**在真实使用的过程中,maven_02_ssm中是需要用到maven_03_pojo的,我们这里只是用这个例子描述我们的需求。因为有时候,maven_04_dao出于某些因素的考虑,就是不想让别人使用自己所依赖的maven_03_pojo。
在maven_04_dao
的pom.xml,在引入maven_03_pojo
的时候,添加optional
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
<version>1.0-SNAPSHOTversion>
<optional>trueoptional>
dependency>
此时BookServiceImpl就已经报错了,说明由于maven_04_dao将maven_03_pojo设置成可选依赖,导致maven_02_ssm无法引用到maven_03_pojo中的内容,导致Book类找不到。
前面我们已经通过可选依赖实现了阻断maven_03_pojo的依赖传递,对于排除依赖,则指的是已经有依赖的事实,也就是说maven_02_ssm项目中已经通过依赖传递用到了maven_03_pojo,此时我们需要做的是将其进行排除,所以接下来需要修改maven_02_ssm的pom.xml
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_04_daoartifactId>
<version>1.0-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
exclusion>
exclusions>
dependency>
这样操作后,BookServiceImpl中的Book类一样也会报错。
当然exclusions
标签带s
说明我们是可以依次排除多个依赖到的jar包,比如maven_04_dao中有依赖junit和mybatis,我们也可以一并将其排除。
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_04_daoartifactId>
<version>1.0-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
exclusion>
<exclusion>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
exclusion>
<exclusion>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
exclusion>
exclusions>
dependency>
介绍我这两种方式后,简单来梳理下,就是
A依赖B,B依赖C
,C
通过依赖传递会被A
使用到,现在要想办法让A
不去依赖C
,A
不知道有C
的存在,
,A
知道有C
的存在,主动将其排除掉。学习笔记 from 黑马程序员
By – Suki 2023/4/6