Maven入门-依赖管理(Jar包管理)(二)
1 依赖管理(Jar包管理)
1.添加依赖
2.创建索引
3.添加jar包
pom.xml中多了一个依赖
查看依赖关系
4 依赖范围
1 Compile struts2-core
编译(compile)时需要, 测试时需要,运行时需要,打包时需要。也是默认的值。
2 Provided jsp-api.jar servlet-api.jar
编译(compile)时需要,测试(test)时也需要 ,运行时不需要,打包时不需要。相当于compile,但是在打包阶段做了exclude的动作。
3 Runtime 数据库驱动包
编译时不需要,测试时需要,运行时需要,打包时需要。被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。
4 Test junit.jar
编译时不需要,测试时需要,运行时不需要,打包也不需要。依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。
补充:关于system和import依赖作用
1.System
system 元素与 provided 元素类似,但是被依赖项不会从 maven 仓库中查找,而是从本地系统中获取,systemPath 元素用于制定本地系统中 jar 文件的路径
2.import
它只使用在<dependencyManagement>中,类似于继承父类中的pom,表示从其它的pom中导入dependency的配置。
Maven的继承和Java的继承一样,是无法实现多重继承的,import scope依赖能解决这个问题。你可以把dependencyManagement放到单独的专门用来管理依赖的pom中,然后在需要使用依赖的模块中通过import scope依赖。
如果在单独的子工程使用dependencyManagement, 那么其下面的依赖也可以不用声明版本。而且在maven版本仲裁的时候如果依赖的包有传递依赖,传递包的版本也会先取dependencyManagement 声明的版本。
例如:
(1)一个专门的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>cn.qz.cloud</groupId> <artifactId>cloud-pom</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>3.4</version> </dependency> </dependencies> </dependencyManagement> </project>
(2) 另一个模块引用该模块,类似于继承父类的dependencyManagement元素,dependencyManagement元素中的依赖不会继承下去,只是声明后无需指定版本号。
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-api-commons</artifactId> <dependencyManagement> <dependencies> <dependency> <groupId>cn.qz.cloud</groupId> <artifactId>cloud-pom</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>cn.qz.cloud</groupId> <artifactId>cloud-pom</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> </dependency> </dependencies> </project>
注意:import 不会直接继承过来里面所有的元素,和之前继承父类一样,相当于受了父类的importdependencyManagement指定的版本约束。在下面的 dependencies 只需要引入依赖即可,版本会采用上面继承的。
补充:关于依赖传递
依赖传递,也就是A项目引入B项目时。关于B项目pom中的依赖关系的传递性质。 注意这里的依赖是dependency jar包的依赖,插件plugin 不会传递。
compile/runtime:会进行依赖传递。假入C在B中的scope是这两者,会传递到A,且scope会继承。
provided/test: 不进行依赖传递。假入C在B中的scope是这两者,到A的时候不会引入C的依赖。
补充: 关于pom 依赖、插件的继承
1. 依赖和插件可以被继承, 而且依赖的scope 会被继承到子项目中
(1) 例如父工程依赖和插件如下:
<!--依赖可以被继承--> <dependencies> <!-- common --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>${commons.collections4.version}</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons.io.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons.lang3.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> <!--插件可以被继承--> <plugin> <groupId>cn.qz.cloud</groupId> <artifactId>my-mvn-plugin</artifactId> <version>2.0-SNAPSHOT</version> <executions> <execution> <!--编写阶段, 默认是compile阶段--> <phase> compile </phase> <goals> <goal>mvtest</goal> </goals> <!--传递参数--> <configuration> <multiParams> <multiParam>111222</multiParam> <multiParam>333444</multiParam> </multiParams> </configuration> </execution> </executions> </plugin> </plugins> </build>
(2) 子工程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"> <parent> <artifactId>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-skywalking-producer</artifactId> <dependencies> <!--skywalking 日志相关--> <dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-logback-1.x</artifactId> <version>8.5.0</version> </dependency> <!--eureka-client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--引入自己抽取的工具包--> <dependency> <groupId>cn.qz.cloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> </project>
查看子工程插件以及依赖如下 (可以看到依赖被继承到子工程, 而且其作用域也被继承到子类;插件也被继承到子类)
5. 下载依赖包
1.进入项目目录(有pom.xml的目录),cmd执行如下命令
mvn dependency:copy-dependencies -DoutputDirectory=dependency_lib
会自动创建dependency_lib目录并且导入相关依赖jar包
2.如果想查找依赖中是否存在某包
mvn dependency:tree |grep spark-core_2.1
补充: Maven 中<optional>true</optional>和<scope>provided</scope>之间的区别
依赖管理是maven的重要作用。无论我们需要什么依赖,将它添加到pom.xml 中,会将所有的类和资源自动添加到项目的classpath。
在添加依赖项时,我们可以使用optional标志,或者scope设为"provided"、"test"。这两种情况下,依赖关系都将在声明它们的模块中,不会传递到其他项目,也就是不会形成依赖。
另外,optional 声明的依赖也可以被继承,而且其optional 特性也会被继承到子类中。也就是option声明的依赖包会被继承到子类,且如果子类如果被引入其他项目,该依赖包不会被依赖传递。
补充: maven 仲裁
maven 仲裁机制: 其实说的是mave 对包依赖的解决办法
1. 优先按照依赖管理<dependencyManagement>元素中指定的版本声明进行仲裁,此时下面的两个原则都无效了
2. 若无版本声明,则按照“短路径优先”的原则(Maven2.0)进行仲裁,即选择依赖树中路径最短的版本
3. 若路径长度一致,则按照“第一声明优先”的原则进行仲裁,即选择POM中最先声明的版本
可以用 mvn dependency:list 查看依赖结果(仲裁结果), 等价于 mvn dependency:resolve