首先,可能需要先了解一下JVM的工作原理
JVM的工作非常简单:
执行一个类的字节码,假如在这个过程中,碰到了新的类,那么加载它!
而我们执行 java命令时,使用了-classpath 或 -cp
意思就是指定了类路径,那么JVM就从这些地方找到需要的类
类的全限定类名(⽬录层级)唯⼀确定了⼀个类
jar包是什么:jar包就是把许多类放在⼀起打的压缩包
早期的包管理
Apache Ant
- ⼿动下载jar包,放在⼀个⽬录中
- 写XML配置,指定编译的源代码⽬录、依赖的jar包、输出 ⽬录等
缺点
- 每个⼈都要⾃⼰造⼀套轮⼦
- 依赖的第三⽅类库都需要⼿动下载,费时费⼒
- 假如你的应⽤依赖了⼀万个第三⽅的类库呢?
- 没有解决Classpath地狱的问题
Maven ——划时代的包管理
- Convention over configuration,约定优于配置,必须强调,Maven远远不⽌是包管理⼯具
- Maven的中央仓库,按照⼀定的约定存储包
- Maven的本地仓库,默认位于~/.m2,下载的第三⽅包放在这⾥进⾏缓存
Maven包构成:groupId + artifactId + version
而maven的版本号也是严格的按照语义化版本来管理的
Maven包冲突机制
在开发中,无法避免的会遇到依赖不同版本的同名包的情况
在maven的传递性依赖管理中,是不允许同名不同版本的jar包的
一般在compile时遇到如下问题,那么基本就是包冲突问题了
- AbstractMethodError
- NoClassDefFoundError
- ClassNotFoundException
- LinkageError
maven在处理这些问题的时候,采用的原则是:最近的胜出,即采用离依赖root越近的
但是有时候maven的这个处理方式并不能满足你的个性化需求,那么我们有几种方法强制指定依赖的版本包
- 在pom中把想要的依赖写在root下,根据最近原则,则采用用户指定的版本包
- 在pom中为指定包添加exclusions,强大的Idea的Dependency Analyzer也可以比较轻易的帮你对比版本冲突快捷修改