Maven是什么
服务于java平台的自动化构建工具,依赖管理工具,和项目信息管理工具。
构建
以“jave源文件”,“框架配置文件”、“JSP”、“HTML”、“等资源为原材料”,去“生产”(编译、部署、搭建)一个可以运行的项目的过程
依赖管理
在这个开源的时代里,几乎任何java应用都会借用一些第三方的开源类库,这些类库都可以通过依赖的方式引入到项目中。
随着依赖的增多,版本不一致、版本冲突、依赖臃肿等问题也接踵而来。
依赖范围
种类:compile,test,provided
概念:maven 项目不同的阶段引入到classpath中的依赖是不同的;对于程序结构来说,compile范围的依赖对主程序和测试程序均有效,test范围的依赖只对测试程序有效。对于开发阶段来说,compile范围的依赖在开发,部署,运行阶段均有效,prorided范围的依赖只在开发阶段有效。
使用
Maven中使用 scope 来指定当前包的依赖范围和依赖的传递性。常见的可选值有:compile, provided, runtime, test, system 等。scope 主要是用在 pom.xml 文件中的依赖定义部分,例如:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>RELEASE</version>
<scope>provided</scope>
</dependency>
compile:
依赖定义中默认为compile,此依赖范围对 于编译、测试、运行三种classpath都有效,举个简单的例子,假如项目中有spring-core的依赖,那么spring-core不管是在编译,测试,还是运行都会被用到。
test:
顾名思义就是针对于测试的,使用此依赖范围的依赖,只对测试classpath有效,在编译主代码和项目打包部署时,都将无法使用该依赖,最典型的例子就是 Junit, 构件在测试时才需要,所以它的依赖范围是测试。
provided:
使用该依赖范围的maven依赖,只对编译和测试的classpath有效,不参与打包与部署,典型的例子就是servlet-api, 编译和测试该项目的时候需要该依赖,但是在运行时,web容器(例如tomcat)已经提供的该依赖,所以运行时就不再需要此依赖。
jar包冲突
1、provided范围依赖导致的jar包冲突
上边提到的provided范围的依赖,由于web容器已经提供,所以在部署运行阶段,会自动忽略该依赖,也就不会吧jar包打到本地仓库,如果不显示指定该依赖范围,就会变成默认的依赖范围compile,那么本地仓库就会有该jar包,那么部署运行的时候就可能会引起版本冲突,这个时候可能会报空指针的异常。
根据错误提示,我们打开第22行,发现我们是无从下手的,而且此时的空指针异常也不是我们常见到类型。如果碰到这种情况,说明是jar冲突。
2、模块工程之间的jar包冲突
2.1 路径短者优先
MakeFriend工程依赖HelloFriend工程,HelloFriend工程依赖Hello工程,HelloFriend工程工程依赖的log4j是2.14,Hello工程依赖的log4j是2.17,因为MakeFriend举例HelloFriend工程最近,所以MakeFriend依赖的log4j是2.14.
2.2 路径相同时先声明者优先
Makefriend工程同时依赖HelloFriend工程和OurFriends工程,但是在dependency标签中先配置的是HelloFriend,所以MakeFriend工程依赖的log4j是2.14。
依赖的传递
加入MakeFriend项目依赖HelloFriend项目,HelloFriend项目需要spring-core依赖,spring-core需要依赖common-logging。那么在执行MakeFriend项目时,会自动把spring-core和commons-logging下载到MakeFriend的jar包文件中。
依赖的排除
接着依赖传递中的例子,如果commons-logging jar包不稳定,MakeFriend项目不希望加入到工程中,那么此时就需要进行依赖的排除了。依赖排除的设置方式只需要用exclusions标签即可。