摘要:Maven
,本地仓库
,远程仓库
,仓库配置
,仓库认证
,镜像
为什么需要仓库
在Maven中任何一个依赖
,插件
或者项目输出
都称为构件,任何一个构件都有一组唯一标识。仓库的作用就是对这些构件进行统一管理,避免磁盘存储重复构件
的浪费,仓库可以在某一位置同意存储所有Maven项目共享的构件,在需要的时候Maven会自动根据坐标找到仓库中的构件并使用它们。
仓库布局
任何一个构件都有唯一坐标,根据坐标可以定义其在仓库中的唯一存储路径
,路径和坐标的大只关系为groupId/artifactId/version/artifactId-version.packaging
。
dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.11</artifactId>
<version>0.10.0.0</version>
</dependency>
root@ubuntu:/root/.m2/repository/org/apache/kafka/kafka_2.11/0.10.0.0# tree
.
├── kafka_2.11-0.10.0.0.jar
├── kafka_2.11-0.10.0.0.jar.sha1
├── kafka_2.11-0.10.0.0.pom
├── kafka_2.11-0.10.0.0.pom.sha1
└── _remote.repositories
其中路径是/org/apache/kafka/kafka_2.11/0.10.0.0
分别代表groupId
,artifactId
,version
,目录下kafka_2.11-0.10.0.0.jar
为依赖。
仓库的分类
仓库分为两类:本地仓库
和远程仓库
,Maven根据坐标寻找构件先从本地仓库开始找,如果有就直接用,没有或者需要查看是否有更新的构件版本就去远程仓库找,在远程仓库发现对应构件之后下载到本地仓库,如果本地仓库和远程仓库都没有Maven会报错。
远程仓库有分为中央仓库
,私服
,其他公共库
,默认本地找不到会去中央仓库,私服是一种特殊的远程仓库,为了节省宽带时间
应该在局域网
内架设一个私有的仓库服务器
,用其代理所有的外部远程仓库,内部的项目
还能部署带私服上供其他项目使用。除了中央仓库和私服还有很多其他公开的远程私服,Maven的仓库分类如下:
本地仓库
在Maven项目下没有lib/
文件夹存放项目依赖,Maven需要编译执行项目时总是基于依赖坐标从本地仓库找到依赖文件。默认情况下仓库目录在用户名根目录下的.m2/repository/
下,可以在.m2/
下的settings.xml
文件(需要先复制一份过去)中修改localRepository
标签本地仓库位置
<localRepository>/home/java/repository</localRepository>
一个构件只有在本地仓库中后才能在其他Maven项目中使用,如何将构件引入本地仓库,最常见的是从远程仓库下载和将本地项目安装
到本地仓库。
编辑一个项目安装到本地仓库,在新的项目中通过仓库坐标引入这个安装的项目。
安装命令
mvn clean install
root@ubuntu:~/.m2/repository/org/mycom/example# tree
.
└── InstallTest
├── 1.0-SNAPSHOT
│ ├── InstallTest-1.0-SNAPSHOT.jar
│ ├── InstallTest-1.0-SNAPSHOT.pom
│ ├── maven-metadata-local.xml
│ └── _remote.repositories
└── maven-metadata-local.xml
在新项目中引用该坐标
<dependency>
<groupId>org.mycom.example</groupId>
<artifactId>InstallTest</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在脚本中调用该依赖的方法returnString
package org.example.FPGrowth
import org.mycom.example.utils.Main.returnString
object Test {
def main(args: Array[String]): Unit = {
val a = returnString()
println(a) // 输出"a"
}
}
中央仓库
Maven的安装文件自带了中央仓库的配置,打开/usr/share/maven/lib
下的maven-model-builder-3.x.jar
下的pom-4.0.0.xml
文件,其中https://repo.maven.apache.org/maven2
就是中央仓库的地址。
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
这段pom是所有Maven项目都会继承的超级pom,其中使用id: central
作为中央仓库的唯一标识,snapshots
标签enabled
为false说明不从中央仓库下载快照版本的构件。
私服
私服是一种特殊的远程仓库,它是架设在局域网的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件时从私服请求,如果私服不存在该构件,则从外部远程仓库下载缓存
在私服上,缓存之后再为Maven的下载请求提供服务。一些无法在外部仓库下载到的构件也能从本地上传
到私服上供大家使用。
即使在一台直接链接Internet的个人机器上也应该使用私服,私服的优势
-
节省外网宽带
: 大量对于外部仓库的重复请求很消耗宽带,私服代理外部仓库后对于重复构建不需要重复下载
,降低外网宽带压力 -
加速Maven构建
: Maven在执行构建的时候不停的检查远程仓库数据,当Maven只需要检查私服数据时,构建速度大大提升。 -
部署第三方构件
: 当组织内部生成的私有构件,肯定在外部仓库无法获得,可以将这些构件上传到私服,供内部其他Maven项目使用。 -
提高稳定性,增强管理
;当远程仓库不稳定的时候,就算Internet不稳定由于在私服缓存了大量构件,所以Maven依然可以运行,另外某些私服软件提供额外的功能比如权限管理,因此获得更高级的控制。 -
降低中央仓库的负荷
: 建立私服之后下载只会在内网范围内,私服对于中央仓库只有一次下载
。
远程仓库的配置
当默认的中央仓库无法满足项目需求时,项目需要的构件可能存在在另一个远程仓库中,可在项目的pom
中进行配置
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>
使用repositories
和repository
声明需要引入的远程的中央仓库,仓库的id都是唯一的,如果这个id和中央仓库的idcentral
一致就会覆盖掉默认的中央仓库,url指向仓库地址。repository下有id的同级元素releases
和snapshots
,分别代表发布版本构件和快照版本构件,配合子标签enabled
标签的true/false使用,代表下载的选择。releases
和snapshots
还有一个子元素updatePolicy
,updatePolicy用来配置Maven从远程仓库检查更新的频率,daily
每天一次,never
从不检查更新,always
每次构建都更新,主要是检查快照版本
是否有更新。
远程仓库的认证
大部分远程仓库无需认证直接访问,但是有时出于安全考虑需要提供认证信息才能远程访问,比如组织内部的Maven仓库需要提供一组用户名
和密码
才能访问。认证信息配置在settings.xml
文件中,因为pom可能会提交到代码仓库,但是settings.xml只会留在本地,所以放在settings.xml中更安全。
<servers>
<server>
<id>myproject</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
使用servers
和server
进行信息认证,id
是要连接的仓库和pom
中的id配置的一致,username
和password
分别提供用户名和密码,其中id
将仓库配置和仓库认证联系在一起。
Maven从仓库解析依赖的机制
(1): 当依赖范围是system
时,Maven直接从本地文件系统解析构件
(2): 根据依赖坐标计算仓库路径,先从本地找
,找不到去远程仓库
(3): 找远程仓库时,如果依赖版本是显式的发布版本
,遍历所有远程仓库发现后下载解析使用
(4): 如果依赖版本是RELEASE
或者LATEST
则请求远程仓库计算这两个值的真实值,再在本地或者远程找
(5): 如果依赖版本是SNAPSHOT
,读取远程仓库或者最新的快照版本,再从本地读取或者远程下载
镜像配合私服
如果仓库X可提供仓库Y的所有构件那么就认为仓库X就是仓库Y的一个镜像,可以在给指定的远程仓库设置
<mirrors>
<mirror>
<id>maven.net.cn</id>
<name>china maven mirror</name>
<url>http://maven.oschina.net/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
通过mirrors
和mirror
指定镜像,mirrorOf
指定为中央仓库central的镜像,镜像更为常用的做法是结合私服使用
<servers>
<server>
<id>myproject</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
<mirrors>
<mirror>
<id>myproject</id>
<mirrorOf>*</mirrorOf>
<url>http://192.168.60.72:8081/nexus/content/groups/myproject-group/</url>
</mirror>
</mirrors>
mirrorOf为*
,表示该配置是所有maven仓库的镜像,任何对于远程仓库的请求都会被转至这个url,如果该镜像需要认证则走server
中的用户名和密码。
网友评论