POM 依赖
Maven 解析依赖信息时,会到本地仓库中查找被依赖的 jar 包。
- groupid:公司火组织域名倒序 + 项目名
- artifactid:模块名
- version:版本
- scope:依赖的范围主要分为以下三种
- complie:编译阶段(默认)
- 对主程序是否有效:√
- 对测试程序是否有效:√
- 是否参与打包:√
- test:测试阶段
- 对主程序是否有效:×
- 对测试程序是否有效:√
是否参与打包:×
测试通过了才打包,所以不需要打包测试程序。
- 典型例子:junit
- provided:提供运行阶段(仅仅用来提供给运行)
- 对主程序是否有效:√
- 对测试程序是否有效:√
- 是否参与打包:×
- 是否参与部署:×
- 典型例子:servlet-api.jar
- complie:编译阶段(默认)
- exclusions:排除某个已有依赖。
依赖管理
Maven 一个核心的特性就是依赖管理。当我们处理多模块的项目(包含成百上千个模块或者子项目),模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。
可传递性依赖发现
一种相当常见的情况,比如说 A 依赖于其他库 B。如果,另外一个项目 C 想要使用 A ,那么 C 项目也需要使用库 B。
Maven 可以避免去搜索所有所需库的需求。Maven 通过读取项目文件(pom.xml),找出它们项目之间的依赖关系。
我们需要做的只是在每个项目的 pom 中定义好直接的依赖关系。其他的事情 Maven 会帮我们搞定。
类比:比如高等数学的建立依赖于初等数学,而我们解题需要用到高等数学的知识,那么我们只需要导入高等数学即可,其他的初等数学的知识 Maven 会帮我们导入。
解题需要依赖高等数学,高等数学需要依赖初等数学,这就是一个传递依赖,我们只需要将项目的直接依赖写入,其他的所需的传递依赖,Maven 会顺着直接依赖往下不断地导入依赖。
通过可传递性的依赖,所有被包含的库的图形会快速的增长。当有重复库时,可能出现的情形将会持续上升。Maven 提供一些功能来控制可传递的依赖的程度。
功能 | 功能描述 | 备注 |
---|---|---|
依赖调节 | 决定当多个手动创建的版本同时出现时,哪个依赖版本将会被使用。 | 如果两个依赖版本在依赖树里的深度是一样的时候,第一个被声明的依赖将会被使用。 |
依赖管理 | 直接的指定手动创建的某个版本被使用。 | 例如当一个工程 C 在自己的依赖管理模块包含工程 B,即 B 依赖于 A, 那么 A 即可指定在 B 被引用时所使用的版本。 |
依赖范围 | 包含在构建过程每个阶段的依赖。 | |
依赖排除 | 任何可传递的依赖都可以通过 "exclusion" 元素被排除在外。 | 举例说明,A 依赖 B, B 依赖 C,因此 A 可以标记 C 为 "被排除的"。 |
依赖可选 | 任何可传递的依赖可以被标记为可选的,通过使用 "optional" 元素。 | 例如:A 依赖 B, B 依赖 C。因此,B 可以标记 C 为可选的, 这样 A 就可以不再使用 C。 |
依赖范围(scope)
传递依赖发现可以通过使用如下的依赖范围来得到限制:
范围 | 描述 | 备注 |
---|---|---|
编译阶段(complie) | 该范围表明相关依赖是只在项目的类路径下有效。默认取值。 | 编译时需要用到的依赖 |
供应阶段(provided) | 该范围表明相关依赖是由运行时的 JDK 或者 网络服务器提供的。 | JRE 运行环境需要提供的依赖 |
运行阶段 | 该范围表明相关依赖在编译阶段不是必须的,但是在执行阶段是必须的。 | |
测试阶段(test) | 该范围表明相关依赖只在测试编译阶段和执行阶段。 | 测试时需要用到的依赖 |
系统阶段 | 该范围表明你需要提供一个系统路径。 | |
导入阶段 | 该范围只在依赖是一个 POM 里定义的依赖时使用。同时,当前项目的 POM 文件的 部分定义的依赖关系可以取代某特定的 POM。 |
org.apache.maven
maven-artifact
3.8.1
jar
test
spring-core
org.springframework
true
依赖的原则
(自己编写的工程,依赖相当于 import)
- 作用:解决模块工程之间的 jar 包冲突问题。
- 原则:
- 路径最短者优先
路径相同时,先声明者优先
先声明指的是 dependency 标签的声明顺序。
继承
- 现状:需要统一管理依赖
Hello 依赖的 junit:4.0
HelloFriend 依赖的 junit:4.0
MakeFriends 依赖的 junit:4.9
由于 test 范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致。 - 需求:统一管理各个模块工程中对 junit 依赖的版本
- 解决思路:将 junit 依赖统一提取到“父”工程中,在子工程中声明 junit 依赖时不指定版本,以父工程中统一设定的为准。同时也便于修改。
- 操作步骤:
创建一个 Maven 工程作为父工程。
注意:打包的方式 pom,只是一个整合的 maven 文件,不需要写程序
- 在子工程中声明对父工程的引用
- 将子工程的坐标中与父工程坐标中重复的内容删除
- 在父工程中统一 junit 的依赖
在子工程中删除 junit 依赖的版本号部分
聚合
聚合可以在父工程中写。
在 Maven 中的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可。
- 作用:一键安装各个模块工程
- 配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块。
- 使用方式:在聚合工程的 pom.xml 上点右键→run as→maven install
../Hello
../HelloFriend
../MakeFriends
作用
- 项目中定义的依赖信息都可以在父工程进行定义,子模块不需要定义依赖信息,直接继承过来即可
- 将各个子模块聚合在一起
- 将父工程保存到maven本地仓库(注意:别忘了这一步)
Maven 库站
我们可以到 http://mvnrepository.com/ 搜索需要的 jar 包的依赖信息。
推荐配置方式
使用 properties 标签内使用自定义标签统一声明版本号,以便于版本的更新。
类比:宏定义常量。
xml
4.0.0.RELEASE 在需要统一版本的威兹,使用\({自定义标签名}引用声明的版本号 ```xml
\) {spring.version}
```
其实 properties 标签配合自定义标签声明数据的配置并不是只能用于声明依赖的版本号。