目录
第一部分 Maven的依赖的学习内容介绍
第一点 依赖的范围
1 依赖范围 Scope
2 一张表告诉你Scope的范围介绍
3 总结:
4 观察
5 测试
①验证 compile 范围对 main 目录有效
②验证test范围对main目录无效
③验证test和provided范围不参与服务器部署
④验证provided范围对测试程序有效
第二点 依赖的传递性
1 看下面的图来观察
2 概念
3 测试的方式 一
4 测试方式二
5 测试方式 三
第三点 依赖的排除性
1 当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。
3 分析 在一个工程中有以下操作 在A工程开始执行流程是要经历过 红色 绿色 蓝色 三个模块中 在这三个模块是相互依赖的关系执行流程如下
A工程——>x-3.0——>service-api-2.0——>B工程
在执行的流程中你发现有些文件有所冲突 想将一些文件舍弃去 不要 该如何操作呢?
4 所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。
5 配置
6 测试
7 运行 mvn dependency:tree 命令查看效果:
发现在 spring-core 下面就没有 commons-logging 了。
第四部分 聚合
1 理解这张图
2 Maven 中的聚合
总工程
3 聚合的配置
4 依赖循环问题
第一部分 Maven的依赖的学习内容介绍
第一点 依赖的范围
1 依赖范围 Scope
标签的位置:dependencies/dependency/scope
标签的可选值:compile/test/provided/system/runtime/import
2 一张表告诉你Scope的范围介绍
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
compile | 有效 | 有效 | 有效 | 有效 |
test | 无效 | 有效 | 有效 | 无效 |
provided | 有效 | 有效 | 有效 | 无效 |
3 总结:
copile:通常使用的第三方框架的 jar 包这样在项目实际运行时真正要用到的 jar 包都是以 compile 范围进行依赖的。比如 SSM 框架所需jar包。**
test:测试过程中使用的 jar 包,以 test 范围依赖进来。比如 junit。
provided:在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。比如 servlet-api、jsp-api。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”
4 观察
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<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>
<!-- Maven的坐标 -->
<groupId>com.web.maven</groupId>
<artifactId>pros-web01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- -->
<!-- 打包的方式是War包 -->
<packaging>war</packaging>
<name>pros-web01-maven Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<!-- 源码的字符集 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 配置对Java工程maventest的依赖 -->
<!-- 具体的配置方式:在dependency标签内使用坐标实现依赖 -->
<dependency>
<groupId>com.efg.maven</groupId>
<artifactId>maventest</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>pros-web01-maven</finalName>
<pluginManagement>
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
5 测试
①验证 compile 范围对 main 目录有效
main目录下的类:HelloServlet 使用compile范围导入的依赖:pro01-java-maven
验证:使用compile范围导入的依赖对main目录下的类来说是有效的
有效:HelloServlet 能够使用 pro01-java-maven 工程中的 Calculator 类
验证方式:在 HelloServlet 类中导入 Calculator 类,然后编译就说明有效。
②验证test范围对main目录无效
测试方式:在主体程序中导入org.junit.Test这个注解,然后执行编译。
具体操作:在pro01-maven-java\src\main\java\com\csdn\maven目录下修改Calculator.java
执行Maven编译命令: mvn compile
[ERROR] /D:/maven-workspace/space201026/pro01-maven-java/src/main/java/com/atguigu/maven/Calculator.java:[3,17] 程序包org.junit不存在
③验证test和provided范围不参与服务器部署
其实就是验证:通过compile范围依赖的jar包会放入war包,通过test范围依赖的jar包不会放入war包。
④验证provided范围对测试程序有效
测试方式是在pro02-maven-web的测试程序中加入servlet-api.jar包中的类。
第二点 依赖的传递性
1 看下面的图来观察
2 概念
在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。
B 依赖 C 时使用 compile 范围:可以传递 B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。 使用 compile 范围依赖 spring-core
3 测试的方式 一
在pro-java-maven工程依赖 spring-core(之前我们创建的一个Maven的Java项目)
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.0.0.RELEASE</version>
</dependency>
使用 mvn dependency:tree 命令查看效果: 使用 mvn dependency:list 命令查看效果:
TIP[INFO] com.csdn.maven:pro01-maven-java:jar:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] \- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] \- commons-logging:commons-logging:jar:1.1.1:compile
4 测试方式二
还可以在 Web 工程中,使用 mvn dependency:tree 命令查看效果(需要重新将 :maventest 安装到仓库而且之前的文章中我们已经设置过Maven的web工程依赖Java工程)
IP[INFO] com.csdn.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] \- com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
[INFO] \- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] \- commons-logging:commons-logging:jar:1.1.1:compile
5 测试方式 三
验证 test 和 provided 范围不能传递
从上面的例子已经能够看到 pro01-java-maven依赖了 junit,但是在 pro02-maven-web 工程中查看依赖树的时候并没有看到 junit。
要验证 provided 范围不能传递,可以在 pro01-maven-java 工程中加入 servlet-api 的依赖。
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope>
</dependency>
TIP[INFO] com.web.maven:pro02-maven-web:war:1.0-SNAPSHOT[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] \- com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
[INFO] \- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] \- commons-logging:commons-logging:jar:1.1.1:compile
第三点 依赖的排除性
1 当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。
2 观察下面的图找答案
3 分析 在一个工程中有以下操作 在A工程开始执行流程是要经历过 红色 绿色 蓝色 三个模块中 在这三个模块是相互依赖的关系执行流程如下
A工程——>x-3.0——>service-api-2.0——>B工程
在执行的流程中你发现有些文件有所冲突 想将一些文件舍弃去 不要 该如何操作呢?
4 所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。
5 配置
<dependency><groupId>com.csdn.maven</groupId><artifactId>pro01-maven-java</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope><!-- 使用excludes标签配置依赖的排除 --><exclusions><!-- 在exclude标签中配置一个具体的排除 --><exclusion><!-- 指定要排除的依赖的坐标(不需要写version) --><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions>
</dependency>
6 测试
测试的方式:在 pro02-maven-web 工程中配置对 commons-logging 的排除
<dependency><groupId>com.csdn.maven</groupId><artifactId>pro01-maven-java</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope><!-- 使用excludes标签配置依赖的排除 --><exclusions><!-- 在exclude标签中配置一个具体的排除 --><exclusion><!-- 指定要排除的依赖的坐标(不需要写version) --><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions>
</dependency>
7 运行 mvn dependency:tree 命令查看效果:
TIP[INFO] com.csdn.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] \- com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
[INFO] \- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
发现在 spring-core 下面就没有 commons-logging 了。
第四部分 聚合
1 理解这张图
2 Maven 中的聚合
使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目。
项目:整体 模块:部分
TIP
概念的对应关系:
从继承关系角度来看:
父工程 子工程 从聚合关系角度来看:
总工程
模块工程 好处 一键执行 Maven 命令:很多构建命令都可以在“总工程”中一键执行。
以 mvn install 命令为例:Maven 要求有父工程时先安装父工程;有依赖的工程时,先安装被依赖的工程。我们自己考虑这些规则会很麻烦。但是工程聚合之后,在总工程执行 mvn install 可以一键完成安装,而且会自动按照正确的顺序执行。
配置聚合之后,各个模块工程会在总工程中展示一个列表,让项目中的各个模块一目了然。
3 聚合的配置
在总工程中配置 modules 即可:
<modules> <module>pro04-maven-module</module><module>pro05-maven-module</module><module>pro06-maven-module</module></modules>
4 依赖循环问题
如果 A 工程依赖 B 工程,B 工程依赖 C 工程,C 工程又反过来依赖 A 工程,那么在执行构建操作时会报下面的错误:
DANGER
[ERROR] [ERROR] The projects in the reactor contain a cyclic reference: 这个错误的含义是:循环引用。