没有包管理工具的年代
在没有包管理工具的年代, 开发人员只能手动下载编译或者收集好程序开发需要的所有jar包,
例如 java -classpath x1.jar; x2.jar; x..10001.jar; com.testJavaApplication
如果有一万个jar包,就需要手动指定一万个jar的目录路径等等,还要考虑到其中有没有冲突关系,依赖关系等等。
过渡时代
Apache Ant
- 手动下载jar包,放在一个目录中。
- 写XML配置,指定编译的源代码目录、依赖的Jar包、输出目录等。
缺点
- 每个人都要造一套自己的轮子
- 依赖的第三方类库都需要手动下载
- 没有解决ClassPath下的类冲突问题
Ant绝大多数的操作还是需要人工手动去做处理,例如需要自己手动下载源代码进行编译等等,但是为承上启下做了过渡。
Maven时代
Maven是一个划时代的包管理工具,其一系列的先进的项目结构和先进的约定,基本涵盖了软件开发的整个生命周期。
上图就是现在使用Maven工具的典型项目包结构,
基于Maven的约定按照这种方式开发,
就可以享受Maven带来的便利,
当然你可以不遵守Maven的约定,但同时带来的就是与大家的协调不规范等等问题,
就像数学上1+1就是等于2一样,是大家的共识。
Maven有一个哲学思想叫做 约定优于配置 (Convention over configuration),
大家都按照Maven的约定来,你可以很方便的使用别人开发好的代码,
别人也可以很方便的使用你开发好的代码。
Maven的中央仓库
- 按照一定的约定存储jar包,大家可以从网络上访问中央仓库进行下载到本地。
Maven的本地仓库
-
默认位于~/.m2目录下。
-
从网络上下载的jar包存储在这里。
在没有Maven之前,一个jar包的确定性就是它的名字,Maven出现以后赋予了Jar包三个属性,
这三个属性确定了jar包的唯一性,像是一个坐标,通过这三个属性就可以找到它。
这三个属性分别是groupId
、artifactId
、version
,可以类比为图书馆里的书库、书架、排号。
例如我们在pom文件中添加一个jar包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
Maven就会从本地仓库中进行查找org.springframework.boot
这个组织下名为spring-boot-starter-data-redis
的工具包,找到后在这个工具包下面查找版本号为2.0.0.RELEASE
的jar。
在我本机中完整的目录是D:\Java\maven\repo\org\springframework\boot\spring-boot-starter-data-redis\2.0.0.RELEASE
,
jar的名字为spring-boot-starter-data-redis-2.0.0.RELEASE.jar
,
jar名称 = 工具名 + 版本号,
路径中 D:\Java\maven\repo
代表你本地的Maven仓库路径,
\org\springframework\boot\
代表你的组织名称,
\spring-boot-starter-data-redis\
工具包名称,
2.0.0.RELEASE
版本号,
spring-boot-starter-data-redis-2.0.0.RELEASE.jar
最终的jar名称,
只需要通过这么引入,就可以在你的项目中使用这个jar里面提供的类和功能了,Maven自动帮我们做了下载引入等等功能。
那如果本地仓库中没有这个jar呢,Maven是从哪里下载的呢?
https://repo1.maven.org/maven2
这个网址是Maven的默认中央仓库,刚刚咱们这个jar在中央仓库的远程访问路径是:
https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-data-redis/2.0.0.RELEASE/
咱们拆解一下 https://repo1.maven.org/maven2
就类似于本地的 D:\Java\maven\repo
,
然后再看后面的那一段 /org/springframework/boot/spring-boot-starter-data-redis/2.0.0.RELEASE/
是不是和本地的文件夹路径一样?
是的,没错,这又是Maven的约定规范之一,咱们不管是从网络还是本地找jar包都有理可依,可以很方便的快速找到。
一个完成的Maven Jar目录下会有如下几个文件,下面解释一下各自的意思
spring-boot-2.0.0.RELEASE.jar = 真实可用的jar包
spring-boot-2.0.0.RELEASE.pom = jar包的pom,里面包含了这个jar依赖哪些jar,Maven会自动把jar依赖的jar都下载下来,这个解决了传递性依赖的问题,开发者只需要关注自己需要的jar,但是这个jar背后依赖的jar,Maven会自动帮忙处理
spring-boot-2.0.0.RELEASE-sources.jar = jar包的java源代码
spring-boot-2.0.0.RELEASE-doc.jar = java源代码的 doc 文档
语义化版本
spring-boot-2.0.0.RELEASE.jar
, 在这个jar中,2.0.0是有其特殊的含义在里面的,
版本格式: 主版本号,次版本号,修订号,
-
主版本号: 当你做了不兼容的API修改。
-
次版本号: 当你做了向下兼容的功能性新增。
-
修订号: 当你做了向下兼容的问题修正。
具体可以查看这篇文章: https://semver.org/lang/zh-CN/
SNAPSHOT快照版本
我们开发的包是大多数情况下要提供给别人使用的,
Maven约定开发好的包上传后不能再次改动,
但是我们内部自己开发包的时候,可能需要频繁的变动,但是又不想频繁的升级版本号,
这样会造成很多无用的版本包存在,
所以我们可以以spring-boot-2.0.0.SNAPSHOT.jar
这种命名告诉其他团队,
这个包正处于开发不稳定版本中,随时可能会产生变化,如果需要稳定的话,请采用RELEASE
版本。
PS: 有的时候大家还会看到M1(2|3|…),RC1(2|3|…)这种版本,M1代表的是项目里程碑版本,RC1代表的是发布候选版本。
修改Maven中央仓库
- 直接修改项目的pom文件,在节点下添加
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
- 修改Maven的setting.xml文件
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>