对于复杂庞大的项目,maven的熟练使用可以大大提高工作效率
开发的模块可以独立出来,作为一个资源,当需要使用时可以通过依赖的形式来引用
将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享。这样的话,项目中的每一层都可以单独维护,也可以很方便的被别人使用
1.按照功能拆分
为了避免项目中某一个模块代码出现问题,导致整个项目无法正常启动,我们会按照功能将项目进行拆分
2.按照模块拆分
为了提高代码复用性
可以将公共的部分抽取成一个独立的模块,其他模块要想使用可以像添加第三方jar包依赖一样来使用我们自己抽取的模块,这样就解决了代码重复的问题(比如订单用户)
建立依赖关系
在maven01
项目的pom.xml添加maven03
的依赖
<dependency>
<groupId>ppgoodlike.yu7dailygroupId>
<artifactId>maven03artifactId>
<version>1.0-SNAPSHOTversion>
dependency>
在IDEA中是有maven03
这个项目,所以我们只需要将maven03
项目安装到本地仓库即可,将需要被依赖的项目maven03
,使用maven的install命令,把其安装到Maven的本地仓库中。否则会出现编译错误!
(1) A依赖了B和C,B和C有分别依赖了其他jar包,所以在A项目中就可以使用上面所有jar包,这就是所谓的依赖传递
(2) 依赖传递有直接依赖和间接依赖
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被资源的资源如果依赖其他资源,当前项目间接依赖其他资源
(3)因为有依赖传递的存在,就会导致jar包在依赖的过程中出现冲突问题,具体什么是冲突?Maven是如何解决冲突的?
这里所说的依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突。
情况一: 在maven01
的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>
特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。
情况二:
路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
情况三:
声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
为了解决依赖的版本冲突问题,通常可以隐藏对外的资源关系
方案一:可选依赖
在maven04
的pom.xml,在引入maven03
的时候,添加optional
<dependency>
<groupId>ppgoodlike.yu7dailygroupId>
<artifactId>maven03artifactId>
<version>1.0-SNAPSHOTversion>
<optional>trueoptional>
dependency>
方案二:排除依赖
前面我们已经通过可选依赖实现了阻断maven03的依赖传递,对于排除依赖,则指的是已经有依赖的事实,也就是说maven01项目中已经通过依赖传递用到了maven03,此时我们需要做的是将其进行排除,所以接下来需要修改maven01的pom.xml
<dependency>
<groupId>ppgoodlike.yu7dailygroupId>
<artifactId>maven04artifactId>
<version>1.0-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>ppgoodlike.yu7dailygroupId>
<artifactId>maven03artifactId>
exclusion>
exclusions>
dependency>
A依赖B,B依赖C
,C
通过依赖传递会被A
使用到,现在要想办法让A
不去依赖C
,A
不知道有C
的存在,
,A
知道有C
的存在,主动将其排除掉。1.所谓聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合
2.聚合工程:通常是一个不具有业务功能的"空"工程(有且仅有一个pom文件)
使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建
当工程中某个模块发生更新(变更)时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题。
聚合具体的实现步骤为:
<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>ppgoodlike.yu7dailygroupId>
<artifactId>maven01artifactId>
<version>1.0-RELEASEversion>
<packaging>pompackaging>
<modules>
<module>../maven01module>
<module>../maven03module>
<module>../maven04module>
modules>
project>
测试发现,当maven01
的compile
被点击后,所有被其管理的项目都会被执行编译操作。这就是聚合工程的作用。
聚合工程管理的项目在进行运行的时候,会按照项目与项目之间的依赖关系来自动决定执行的顺序和配置的顺序无关。
最后总结一句话就是,聚合工程主要是用来管理项目。
所谓继承:描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
将所有项目公共的jar包依赖提取到父工程的pom.xml中,子项目就可以不用重复编写,简化开发
将所有项目的jar包配置到父工程的dependencyManagement标签下,实现版本管理,方便维护
注:dependencyManagement标签不真正引入jar包,只是管理jar包的版本,子项目在引入的时候,只需要指定groupId和artifactId,不需要加version
注:当dependencyManagement标签中jar包版本发生变化,所有子项目中有用到该jar包的地方对应的版本会自动随之更新
最后总结一句话就是,父工程主要是用来快速配置依赖jar包和管理项目中所使用的资源。
实现步骤:
1.创建Maven模块,设置打包类型为pom
<packaging>pompackaging>
2.在父工程的pom文件中配置依赖关系(子工程将沿用父工程中的依赖关系),一般只抽取子项目中公有的jar包
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
...
dependencies>
3.在父工程中配置子工程中可选的依赖关系
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ppgoodlike.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.16version>
dependency>
dependencies>
...
dependencyManagement>
4.在子工程中配置当前工程所继承的父工程
<parent>
<groupId>ppgoodlike.yu7dailygroupId>
<artifactId>maven01artifactId>
<version>1.0-RELEASEversion>
<relativePath>../maven01/pom.xmlrelativePath>
parent>
5.在子工程中配置使用父工程中可选依赖的坐标
<dependencies>
<dependency>
<groupId>ppgoodlike.alibabagroupId>
<artifactId>druidartifactId>
dependency>
dependencies>
注意事项:
1.子工程中使用父工程中的可选依赖时,仅需要提供群组id和项目id,无需提供版本,版本由父工程统一提供,避免版本冲突
2.子工程中还可以定义父工程中没有定义的依赖关系,只不过不能被父工程进行版本统一管理。
两种之间的作用:
聚合和继承的相同点:
聚合和继承的不同点:
为了解决更新多个jar包的版本,而出现漏改导致程序出问题,可以声明一个变量,在其他地方使用该变量,当变量的值发生变化后,所有使用变量的地方,就会跟着修改,以spring、junit、mybatis-spring为例
<properties>
<spring.version>5.2.10.RELEASEspring.version>
<junit.version>4.12junit.version>
<mybatis-spring.version>1.3.0mybatis-spring.version>
properties>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
为了让maven管理范围更大,我们可以在父工程中定义属性通过配置文件引用的方式来完成配置
<properties>
<jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_dbjdbc.url>
properties>
在jdbc.properties,将jdbc.url的值直接获取Maven配置的属性
jdbc.driver=ppgoodlike.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=284650
Maven在默认情况下是从当前项目的src\main\resources
下读取文件进行打包。现在我们需要打包的资源文件是在maven01下,需要我们通过配置来指定下具体的资源目录
<build>
<resources>
<resource>
<directory>../maven01/src/main/resourcesdirectory>
<filtering>truefiltering>
resource>
resources>
build>
directory路径前要添加../
的原因是maven01相对于父工程的pom.xml路径是在其上一层的目录中,所以需要添加。