目录
依赖
依赖到底是什么
依赖就可以理解为jar包/war包
多模块项目的父pom
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>web</module>
<module>service</module>
<module>db</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>pers.wmx</groupId>
<artifactId>daily-coding</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>daily-coding</name>
<description>daily-coding</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<mybatis_spring_version>1.3.1</mybatis_spring_version>
<lombok.version>1.16.20</lombok.version>
<fastjson_version>1.2.57</fastjson_version>
</properties>
<dependencyManagement>
<!-- 项目全局的依赖版本管理,所有依赖的版本号必须定义在这里 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 所有子模块的版本保持一致 -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis_spring_version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson_version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
整个项目的依赖和其版本号都在父pom中管理起来,儿子需要什么就拿什么,不用管版本号
dependencyManagement
顾名思义,就是依赖的管理者
dependency
就是具体的依赖,这些依赖的groupId
和artifactId
、version
依赖的基本坐标,都可以在maven中央仓库查寻。
一般习惯于在properties
定义版本号,在dependency
直接引用,就好像声明变量似的
依赖范围
依赖又有范围scope
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系
a) compile 编译(默认)
编译依赖范围
对编译classpath、测试classpath、运行classpath都有效
测试依赖范围
测试classpath有效
导入依赖范围
不会对三种classpath产生实际影响
依赖范围由强到弱的顺序是:compile>provided>runtime>test
默认引入 的jar包 ——- compile 【默认范围 可以不写】(编译、测试、运行 都有效 )
servlet-api 、jsp-api ——- provided (编译、测试 有效, 运行时无效 防止和tomcat下jar冲突,容器已经提供)
jdbc驱动jar包 —- runtime (测试、运行 有效 )
junit —– test (测试有效)
maven仓库
在这里基本都能找到你需要的依赖,神器
依赖传递
但是也有一定的条件:
maven会解析各个直接依赖的pom,将那些必要的间接依赖以传递性依赖的形式引入到当前项目
依赖范围还会影响传递性依赖
更详细的见下表
第一直接依赖 \ 第二直接依赖 |
compile |
test |
provided |
runtime |
---|---|---|---|---|
compile |
compile |
—— |
—— |
runtime |
test |
test |
—— |
—— |
test |
provided |
provided |
—— |
provided |
provided |
runtime |
runtime |
—— |
—— |
runtime |
最左一列表示第一直接依赖的范围,最上一行表示第二直接的范围
交叉的节点得到的就是间接依赖的范围
依赖仲裁
首先严禁在同一个pom中声明两个不同版本的依赖
然后我们看下下面两个基本的依赖原则:
- 最短路径原则
A–>B–>C–>X(1.0)、A–>D–>X(2.0),X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用
- 加载先后原则
A–>B–>Y(1.0),A–>C–>Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2
第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。顺序最靠前的那个依赖优胜。
如:
这样按照一些规则加载依赖,就不会产生冲突和问题
可选依赖
如果A依赖B,B可选依赖C(optional),则C对A是不可见的
A的pom
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.9</version>
</dependency>
</dependencies>
</project>
B的pom
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
joda-time
对B是不可见的,可再显示引入依赖
排除依赖
maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的的两个依赖
<project>
...
<dependencies>
<dependency>
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>sample.ProjectC</groupId>
<artifactId>Project-C</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
项目A在引入对项目B的依赖时,排除了对项目C的依赖。
但并不影响项目A在其他地方引入对项目C的依赖。
例如,项目A又引入了对项目D的依赖,而项目D依赖项目C,这个时候,项目A就又产生了对项目C的依赖。
或者项目A直接显示声明对C的其他版本依赖
排除依赖我觉得主要原因
一来是解决依赖冲突
二来是排除掉不稳定的版本,自己引入需要的版本
依赖排查命令
mvn dependency:list
mvn dependency:tree
mvn dependency:analyze
参考
https://www.cnblogs.com/LaiCuiTing/p/9542525.html
https://www.52xbc.cn/java/301.html
《Maven实战》 (这本书正在看,真心不错!)
转载请注明:汪明鑫的个人博客 » maven 依赖概述
说点什么
您将是第一位评论人!