1、解决jar包冲突:
maven管理jar包依赖的时候,假如你的依赖包A需要间接依赖B的1.0版本,而你的工程里又需要用到B的2.0版本,这个时候就可能会出现运行时jar冲突的异常,会报java.lang.NoSuchMethodError或者 java.lang.ClassNotFoundException 、java.lang.NoClassDefFoundError
解决方法一:
(1)使用mvn dependency:tree可以查看项目所有依赖树
或者使用mvn dependency:tree -Dverbose -Dincludes=org.springframework.boot (等号后接产生冲突的包名)
(2)使用<exclutions>标签可以排除某些依赖jar包
<exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> </exclusions>
解决方法二:
在父级pom中使用dependencyManagement管理公用的jar版本,子类中引入自己需要的jar版本,maven会优先使用子类的jar。
2、dependencyManagement和dependencies的区别
dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。在顶层pom中定义共同的依赖关系。同时可以避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个版本号时,只需要在dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。
pom.xml //只是对版本进行管理,不会实际引入jar <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.7</version> </dependency> </dependencies> </dependencyManagement> //会实际下载jar包 <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> </dependencies>
3、scope的分类的作用
compile
默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去。
test
scope为test表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。比较典型的如junit。
runntime
runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中,和compile区别不是很大。比较常见的如JSR×××的实现,对应的API jar是compile的,具体实现是runtime的,compile只需要知道接口就足够了。oracle jdbc驱动架包就是一个很好的例子,一般scope为runntime。另外runntime的依赖通常和optional搭配使用,optional为true。我可以用A实现,也可以用B实现。
provided
provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。
system
从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。
scope的依赖传递
A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?答案是:
当C是test或者provided时,C直接被丢弃,A不依赖C;
否则A依赖C,C的scope继承于B的scope。
4、maven常用命令
mvn -version 查看maven的版本及配置信息
mvn archetype:create -DgroupId= DartifactId= 构建java项目
mvn archetype:create -DgroupId= DartifactId= -DarchetypeArtifactId=maven-archetype-webapp 创建web项目
mvn compile 编译项目代码
mvn package 打包项目
mvn package -Dmaven.test.skip=true 打包项目时跳过单元测试
mvn test 运行单元测试
mvn clean 清除编译产生的target文件夹内容,可以配合相应命令一起使用,如mvn clean package, mvn clean test
mvn install 打包后将其安装在本地仓库
mvn deploy 打包后将其安装到pom文件中配置的远程仓库
mvn eclipse:eclipse 将maven生成eclipse项目结构
mvn eclipse:clean 清除maven项目中eclipse的项目结构
mvn site 生成站点目录
mvn dependency:list 显示所有已经解析的所有依赖
mvn dependency:tree 以树的结构展示项目中的依赖
mvn dependency:analyze 对项目中的依赖进行分析,依赖未使用,使用单未引入
mvn tomcat:run 启动tomcat