所以对于项目的拆分,大致会有如下几个步骤:
(1) 创建Maven模块
(2) 书写模块代码
分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。拆分方式可以按照功能拆也可以按照模块拆。
(3)通过maven指令安装模块到本地仓库(install 指令)。
团队内部开发需要发布模块功能到团队内部可共享的仓库中(私服)。
当在其他项目中想要使用独立出来的这些模块,只需要在其pom.xml使用< dependency >标签来进行jar包的引入即可。
< dependency >其实就是依赖,关于依赖管理里面都涉及以下这些内容:
依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。
格式为:
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
dependencies>
依赖是具有传递性的:
说明: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_04_dao
的pom.xml,在引入maven_03_pojo
的时候,添加optional
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
<version>1.0-SNAPSHOTversion>
<optional>trueoptional>
dependency>
此时,依赖03的工程就会报错。
<dependency>
<groupId>com.itheimagroupId>
<artifactId>maven_04_daoartifactId>
<version>1.0-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>com.itheimagroupId>
<artifactId>maven_03_pojoartifactId>
exclusion>
exclusions>
dependency>
这样操作后,依赖03的工程就会报错。
当然exclusions
标签带s
说明我们是可以依次排除多个依赖到的jar包。
A依赖B,B依赖C
,C
通过依赖传递会被A
使用到,现在要想办法让A
不去依赖C
,A
不知道有C
的存在,
,A
知道有C
的存在,主动将其排除掉。关于聚合具体的实现步骤为:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.itheimagroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-RELEASEversion>
<packaging>pompackaging>
project>
说明:项目的打包方式,我们接触到的有三种,分别是
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.itheimagroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-RELEASEversion>
<packaging>pompackaging>
<modules>
<module>../maven_02_ssmmodule>
<module>../maven_03_pojomodule>
<module>../maven_04_daomodule>
modules>
project>
测试发现,当maven_01_parent
的compile
被点击后,所有被其管理的项目都会被执行编译操作。这就是聚合工程的作用。
说明:聚合工程管理的项目在进行运行的时候,会按照项目与项目之间的依赖关系来自动决定执行的顺序和配置的顺序无关。
最后总结一句话就是,聚合工程主要是用来管理项目。
分别在maven_02_ssm
,maven_03_pojo
,maven_04_dao
的pom.xml中添加其父项目为maven_01_parent
<parent>
<groupId>com.itheimagroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-RELEASEversion>
<relativePath>../maven_01_parent/pom.xmlrelativePath>
parent>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.itheimagroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-RELEASEversion>
<packaging>pompackaging>
<modules>
<module>../maven_02_ssmmodule>
<module>../maven_03_pojomodule>
<module>../maven_04_daomodule>
modules>
<dependencies>
...........
dependencies>
project>
刷新子项目,子项目中所需要的jar包依然存在。
当项目的
标签被移除掉,会发现多出来的jar包依赖也会随之消失。
这样我们就可以解决刚才提到的第一个问题,将子项目中的公共jar包抽取到父工程中进行统一添加依赖,这样做的可以简化配置,并且当父工程中所依赖的jar包版本发生变化,所有子项目中对应的jar包版本也会跟着更新。
如果把所有用到的jar包都管理在父项目的pom.xml,看上去更简单些,但是这样就会导致有很多项目引入了过多自己不需要的jar包。如上面看到的这张图:
如果把所有的依赖都放在了父工程中进行统一维护,就会导致ssm_order项目中多引入了spring-test
的jar包,如果这样的jar包过多的话,对于ssm_order来说也是一种"负担"。
那针对于这种部分项目有的jar包,我们该如何管理优化呢?
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
dependencyManagement>
刷新完会发现,在maven_02_ssm项目中的junit依赖并没有出现,所以我们得到一个结论:
标签不真正引入jar包,而是配置可供子项目选择的jar包依赖
子项目要想使用它所提供的这些jar包,需要自己添加依赖,并且不需要指定
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
注意:这里就不需要添加版本了,这样做的好处就是当父工程dependencyManagement标签中的版本发生变化后,子项目中的依赖版本也会跟着发生变化
总结来说,继承可以帮助做两件事
最后总结一句话就是,父工程主要是用来快速配置依赖jar包和管理项目中所使用的资源。
小结
继承的实现步骤:
创建Maven模块,设置打包类型为pom
<packaging>pompackaging>
在父工程的pom文件中配置依赖关系(子工程将沿用父工程中的依赖关系),一般只抽取子项目中公有的jar包
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
...
dependencies>
在父工程中配置子工程中可选的依赖关系
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.16version>
dependency>
dependencies>
...
dependencyManagement>
在子工程中配置当前工程所继承的父工程
<parent>
<groupId>com.itheimagroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-RELEASEversion>
<relativePath>../maven_01_parent/pom.xmlrelativePath>
parent>
在子工程中配置使用父工程中可选依赖的坐标
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
dependency>
dependencies>
注意事项:
1.子工程中使用父工程中的可选依赖时,仅需要提供群组id和项目id,无需提供版本,版本由父工程统一提供,避免版本冲突
2.子工程中还可以定义父工程中没有定义的依赖关系,只不过不能被父工程进行版本统一管理。
两种之间的作用:
聚合和继承的相同点:
聚合和继承的不同点:
相信到这里,大家已经能区分开什么是聚合和继承,但是有一个稍微麻烦的地方就是聚合和继承的工程构建,需要在聚合项目中手动添加modules
标签,需要在所有的子项目中添加parent
标签,万一写错了咋办?
其实对于聚合和继承工程的创建,IDEA已经能帮助我们快速构建,具体的实现步骤为:
创建一个空的Maven项目,可以将项目中的src
目录删除掉,这个项目作为聚合工程和父工程。
创建成功后,maven_parent即是聚合工程又是父工程,maven_web中也有parent标签,继承的就是maven_parent,对于难以配置的内容都自动生成。
按照上面这种方式,大家就可以根据自己的需要来构建分模块项目。
后记
美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!!