一.maven依赖的范围和传递性
1.范围的含义
编译时,maven 会将与编译相关的依赖引入classpath中,测试时,maven会将与测试相关的的依赖引入到classpath中,运行时,maven会将与运行相关的依赖引入classpath中,而依赖范围就是用来控制依赖于这三种classpath的关系。
2.范围的分类
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
scope标签就是依赖范围的配置,默认是compile,可选配置有test、provided、runtime、system、import
1). compile,默认依赖范围
此依赖范围对 于编译、测试、运行三种classpath都有效,即main目录下的java代码可以访问这个范围的依赖,test目录下的java代码可以访问这个范围的依赖,部署到tomcat服务器上运行时会放在WEB-INF的lib目录下
2). test,针对测试
main目录下的java代码不可以访问这个范围的依赖,test目录下的java代码可以访问这个范围的依赖,部署到tomcat服务器上运行时不会放在WEB-INF的lib目录下
3). provided只对编译和测试有效,对运行无效
main目录下的java代码可以访问这个范围的依赖,test目录下的java代码可以访问这个范围的依赖,部署到tomcat服务器上运行时不会放在WEB-INF的lib目录下
典型范例:servlet-api在服务器运行时,servlet容器会提供相应的jar
4). runtime只对测试和运行有效,对编译无效
典型范例:JDBC的驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动。
5). system
与classpath的关系与 provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可移植,因此谨慎使用,systemPath元素可以引用环境变量:
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
6). import
不会对三种classpath产生影响,该依赖范围只能与dependencyManagement元素配合使用,其功能为将目标pom文件中dependencyManagement的配置导入合并到当前pom的dependencyManagement中。
3.传递性
当存在间接依赖的情况,间接依赖的jar包的依赖范围只有为compile时,主工程才可以访问间接依赖。
二.maven依赖的原则和排除以及统一管理
1.maven依赖的原则
1). 路径最短者优先:
一个项目依赖了两个jar包,其中A-B-C-X(1.0) , A-D-X(2.0)。由于X(2.0)路径最短,所以项目使用的是X(2.0)。
2). 路径相同先声明者优先
(声明的先后顺序指dependency标签配置的先后顺序) 如果A-B-X(1.0) ,A-C-X(2.0) 路径长度一样,maven会根据pom文件声明的顺序加载,如果先声明了B,后声明了C,那就最后的依赖就会是X(1.0)。
3). 覆写优先
子pom内声明的优先于父pom中的依赖。
2.maven依赖的排除
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
3.maven统一管理目标jar的版本
设置properties属性:
<properties>
<webmagic.version>0.7.3</webmagic.version>
</properties>
在依赖中设置版本:
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>${webmagic.version}</version>
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.slf4j</groupId>-->
<!-- <artifactId>slf4j-log4j12</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
</dependency>
三.继承
1.为什么需要继承机制
在依赖链中,非compile范围的依赖信息无法在依赖链中传递,如junit,使用继承机制可以将这样的依赖信息提取到父工程模块中进行统一管理
2.具体步骤
1). 创建父工程
创建父工程和创建一般的java工程操作一致,唯一需要注意的是,打包方式设置为pom
2). 子工程中引入父工程
<?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>par</artifactId>
<groupId>com.htdata</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>son</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
relativePath:指定从当前pom.xml文件出发,查找父工程的pom.xml文件;
groupId version可忽略
2). 在父工程管理依赖
<?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>com.htdata</groupId>
<artifactId>par</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>son</module>
</modules>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
四.聚合
1.为什么需要聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能生效。修改源码后需要逐个手动clean,而实用聚合后可以批量的进行maven工程的安装清理工作。
2.配置聚合
在总的聚合工程中,使用modules/module标签