maven中依赖、继承、聚合、dependencyManagement、parent标签、modules标签的作用
简介
Maven是软件基金会组织维护的一款自动化构建工具,专注服务于Java平台的项目构建和依赖管理。Maven这个单词的本意是:专家,内行。读音是['meɪv(ə)n]或['mevn]。
依赖 依赖范围
maven中依赖常见的范围有 、、test 三种。
范围依赖:
范围依赖:
test范围依赖:
主要是针对web工程的。以前web开发,总是缺少-api.jar,所以我们常去的lib目录下拷过来使用。但是部署的时候会忽略,因为容器会提供,所以不会打包上去。故将 -api.jar 设置为范围。
依赖传递&排除
当A工程依赖B工程,那么我们在给B工程导入其他依赖的话,A工程也会自动导入相同的依赖,这样依赖只用在pom.xml文件中导入一次,就比较方便。这就是依赖的传递性。
当然依赖的传递也不是绝对的,有些依赖就传递不过来。非范围的依赖不能传递。 这样我们也可以看出,和test范围就是给当前工程自己用的。所以在各个工程模块中,如果有需要就得重复声明依赖。
-----------------------------------------------------------华丽的分割线-----------------------------------------------------------
现在假设有这么个场景,B工程导入的依赖有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。想要排除某个依赖,就在依赖的gav坐标中,使用 标签,里面可以定义多个 。
比如在当前的工程中,依赖了 , 又依赖了。但是我工程不想要依赖,就可以使用哦 标签进行排除。
排除前:
排除后:
依赖冲突的原则
之前说过,依赖存在传递性,当A依赖于B,而B又依赖于C,则A也会引入C的范围的依赖。
假设现在有这么一个场景,有三个工程,分别名为 ,,。
如上图所示,此时就发生依赖冲突了。是依赖 1.18.20还是 1.16.18呢?
一般来说选择版本较高的,因为版本较高的都会向下兼容。但是maven有自己的解决依赖版本问题的原则,就是就进优先,也就是路径最短者优先。那么怎么去看这个路径呢?
到再到 1.16.18的路径短于 到到再到 1.18.20。故最终会选择 1.16.18的依赖版本。
那么如果我就是想用 1.18.20 的版本的依赖呢?那就在该工程pom.xml中显示的声明即可。
-----------------------------------------------------------华丽的分割线-----------------------------------------------------------
现在换一个场景,假设还是三个工程 ,,。
依赖了 和,而在和都有依赖,那么 用谁的依赖呢?
此时从 到 1.16.18的路径和到 1.18.20的路径相等,该如何是好?
maven中规定,路径相同的时候,对依赖的取舍标准就叫做先声明者优先。 先声明指的是标签的声明顺序。
依赖的统一管理
在最早学的时候,导入依赖,我们都是根据的模块按需导入。如:
当我们使用框架时,使用框架的一组jar包,最好都是版本一致的,毕竟不同版本之间总会有些改动。那么如果我想将所有的jar包版本都升级到 5.3.6 怎么办呢?最笨的办法就是手动去挨个修改,这样有多少个jar包就要修改多少次,这样并不可取。
推荐的方法就是,在 标签内来自定义标签来统一版本号。这样我们只要修改了自定义标签内的值,那么其他地方凡是引用到了该自定义标签的值都会跟着修改。
标签配合自定义标签声明数据的配置并不是只能用于版本号管理,但是用的最多的是版本号管理。凡是需要统一声明后再引用的场合都可以使用。
继承 标签
假设现在有四个工程 ,,,。 、 、 都依赖,此时如果的版本发生变动,其他三个工程想要升级依赖版本,也要各自去修改,十分麻烦。
之前在单个工程中可以通过标签和自定义标签来统一依赖版本。那么多个工程之间如何统一呢? 就需要定义一个父工程来进行统一管理。
定义一个父工程 。在父工程中引入 的依赖。
<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>org.examplegroupId>
<artifactId>mavenpro_parentartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
<properties>
<mavenpro_d.version>3.0-SNAPSHOTmavenpro_d.version>
properties>
<dependencies>
<dependency>
<groupId>org.examplegroupId>
<artifactId>mavenpro_dartifactId>
<version>${mavenpro_d.version}version>
dependency>
dependencies>
project>
我们只需继承父工程,就能得到父工程中的范围的依赖。这样如果版本发生变动,我们只需要在父工程中修改即可,不需要变动子工程。
注意,父工程的打包类型一定要定义成 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>org.examplegroupId>
<artifactId>mavenpro_parentartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
<properties>
<mavenpro_d.version>3.0-SNAPSHOTmavenpro_d.version>
<spring.aop.version>5.3.6spring.aop.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.examplegroupId>
<artifactId>mavenpro_dartifactId>
<version>${mavenpro_d.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${spring.aop.version}version>
dependency>
dependencies>
dependencyManagement>
project>
此时我们再去看 ,即使使用了标签,但是依赖全无。因为,标签中的依赖,maven会帮我们自动下载,而标签中的依赖,maven不会帮我们下载,需要我们自己按需引入!。
于是我按需导入 aop 依赖
<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>org.examplegroupId>
<artifactId>mavenpro_cartifactId>
<version>1.0-SNAPSHOTversion>
<parent>
<artifactId>mavenpro_parentartifactId>
<groupId>org.examplegroupId>
<version>1.0-SNAPSHOTversion>
<relativePath>../mavenpro_parent/pom.xmlrelativePath>
parent>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
dependency>
dependencies>
project>
可以看到,在导入aop依赖的时候,我并没有写版本号,这也是 标签带来的好处,我们在父工程中定义的依赖,子类在引入依赖时,可以不定义版本号,那么就默认的使用父工程的版本号。这称为maven的版本仲裁机制。
聚合
一个工程中的类想要被其它工程使用,那么我们需要将该工程打包成jar包的方式,被其它工程引用,即可使用。在maven使用 maven 即可打包但装到我们的maven仓库中。
当工程渐渐变多,一个一个的maven 就变得繁琐起来,于是我们可以在父工程中通过 标签引入子工程,这样我们 maven 父工程,则 标签中的子工程也会被一键安装。
<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>org.examplegroupId>
<artifactId>mavenpro_parentartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
<modules>
<module>../mavenpro_amodule>
<module>../mavenpro_bmodule>
modules>
<properties>
<mavenpro_d.version>3.0-SNAPSHOTmavenpro_d.version>
<spring.aop.version>5.3.6spring.aop.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.examplegroupId>
<artifactId>mavenpro_dartifactId>
<version>${mavenpro_d.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${spring.aop.version}version>
dependency>
dependencies>
dependencyManagement>
project>