Maven_命令行环境使用Maven(四)
一、让 Web 工程依赖 Java 工程
1、观念
明确一个意识:从来只有 Web 工程依赖 Java 工程,没有反过来 Java 工程依赖 Web 工程。本质上来说,Web 工程依赖的 Java 工程其实就是 Web 工程里导入的 jar 包。最终 Java 工程会变成 jar 包,放在 Web 工程的 WEB-INF/lib 目录下。
2、操作
在 pro02-maven-web 工程的 pom.xml 中,找到 dependencies 标签,在 dependencies 标签中做如下配置:
1 | <!-- 在当前Web工程中配置对上一个Java工程的依赖,即配置对Java工程pro01-maven-java的依赖 --> |
3、在 Web 工程中,编写测试代码
① 创建补充目录
pro02-maven-wb\src\test\java\com\atguigu\maven
② 确认 Web 工程依赖了 junit
1 | <dependency> |
③ 创建测试类
把 Java 工程 pro01-atguigu-maven 的 CalculatorTest.java 类复制到 pro02-maven-wb\src\test\java\com\atguigu\maven目录下
4、执行 Maven 命令
① 测试命令
mvn test
说明:测试操作中会提前自动执行编译操作,测试成功就说明编译也是成功的。
② 打包命令
mvn package
通过查看 war 包内的结构,我们看到被 Web 工程依赖的 Java 工程确实是会变成 Web 工程的 WEB-INF/lib 目录下的 jar 包。
③ 查看当前 Web 工程所依赖的 jar 包的列表
1 | mvn dependency:list |
[INFO] The following files have been resolved:
[INFO] junit:junit:jar:4.11:test
[INFO] javax.servlet:javax.servlet-api:jar:4.0.1:provided
[INFO] org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
说明:javax.servlet:javax.servlet-api:jar:4.0.1:provided 格式显示的是一个 jar 包的坐标信息。格式是:
groupId : artifactId : 打包方式 : version : 依赖的范围
这样的格式虽然和我们 XML 配置文件中坐标的格式不同,但是本质上还是坐标信息,大家需要能够认识这样的格式,将来从 Maven 命令的日志或错误信息中看到这样格式的信息,就能够识别出来这是坐标。进而根据坐标到 Maven 仓库找到对应的 jar 包,用这样的方式解决我们遇到的报错的情况。
④ 以树形结构查看当前 Web 工程的依赖信息
1 | mvn dependency:tree |
[INFO] com.atguigu.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] | - org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:4.0.1:provided
[INFO] - com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
我们在 pom.xml 中并没有依赖 hamcrest-core,但是它却被加入了我们依赖的列表。原因是:junit 依赖了 hamcrest-core,然后基于依赖的传递性,hamcrest-core 被传递到我们的工程了。
二、测试依赖的范围
1、依赖范围
标签的位置:dependencies/dependency/scope
标签的可选值:compile/test/provided
①compile 和 test 对比
main 目录(空间) | test 目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
compile | 有效 | 有效 | 有效 | 有效 |
test | 无效 | 有效 | 有效 | 无效 |
②compile 和 provided 对比
main 目录(空间) | test 目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
compile | 有效 | 有效 | 有效 | 有效 |
provided | 有效 | 有效 | 有效 | 无效 |
③ 结论
compile:通常使用的第三方框架的 jar 包这样在项目实际运行时真正要用到的 jar 包都是以 compile 范围进行依赖的。比如 SSM 框架所需 jar 包。
test:测试过程中使用的 jar 包,以 test 范围依赖进来。比如 junit。
provided:在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。比如 servlet-api、jsp-api。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”
2、测试
① 验证 test 范围对 main 目录无效
测试方式:在主体程序中导入 org.junit.Test 这个注解,然后执行编译。
具体操作:在 pro01-maven-java\src\main\java\com\atguigu\maven 目录下修改 Calculator.java
1 | package com.atguigu.maven; |
执行 Maven 编译命令:
1 | Compilation failure |
② 验证 test 和 provided 范围不参与服务器部署
其实就是验证:通过 compile 范围依赖的 jar 包会放入 war 包,通过 test 范围依赖的 jar 包不会放入 war 包。
③ 验证 provided 范围对测试程序有效
测试方式是在 pro02-maven-web 的测试程序中加入servlet-api.jar包中的类。
修改:pro02-maven-web\src\test\java\com\atguigu\maven\CalculatorTest.java
1 | package com.atguigu.maven; |
然后运行 Maven 的编译命令:mvn compile
然后看到编译成功。
三、测试依赖的传递性
1、依赖的传递性
① 概念
A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面是不是可以直接使用 C。
② 传递的原则
在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A 取决于 B 依赖 C 时使用的依赖范围。
- B 依赖 C 时使用 compile 范围:可以传递
- B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。
2、使用 compile 范围依赖 spring-core
① 测试方式 1
让 pro01-maven-java 工程依赖 spring-core
具体操作:编辑 pro01-maven-java 工程根目录下 pom.xml
1 | <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> |
使用命令
1 | mvn dependency:tree |
查看效果:
[INFO] com.atguigu.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
② 测试方式 2
还可以在 Web 工程 pro02-maven-web 中使用命令
1 | mvn dependency:tree |
查看效果(需要重新将 pro01-maven-java 安装到仓库 mvn install ):
[INFO] com.atguigu.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] | - org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:4.0.1: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
3、验证 test 和 provided 范围不能传递
从上面的例子已经能够看到,pro01-maven-java 依赖了 junit,但是在 pro02-maven-web 工程中查看依赖树的时候并没有看到 junit。
要验证 provided 范围不能传递,可以在 pro01-maven-java 工程中加入 servlet-api 的依赖。
1 | <dependency> |
效果还是和之前一样:
[INFO] com.atguigu.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] | - org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:4.0.1: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 包之间的冲突。
所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。
2、配置方式
1 | <dependency> |
3、测试
测试的方式:在 pro02-maven-web 工程中配置对 commons-logging 的排除
运行命令
1 | mvn dependency:tree |
查看效果:
[INFO] com.atguigu.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] | - org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:4.0.1: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 了。