1.文件结构
setting.xml 整体结构如下:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>
下面是各个元素的含义:
- localRepository:本地仓库的位置,如果没有设置,Maven会使用默认的~/.m2/repository。
- interactiveMode:交互模式的开关,如果设置为true,Maven会在需要输入时提示用户。
- usePluginRegistry:是否使用插件注册表,如果设置为true,Maven会使用~/.m2/plugin-registry.xml文件。
- offline:离线模式的开关,如果设置为true,Maven不会尝试连接网络。
- pluginGroups:插件组列表,Maven会在这些组中搜索插件。
- servers:定义了一些服务器的配置,包括服务器的 ID、用户名和密码。这些服务器通常用于发布(deploy)项目。
- mirrors:镜像配置,可以设置Maven从哪个镜像站点下载依赖。
- proxies:代理配置,可以设置Maven通过哪个代理服务器连接网络。
- profiles:配置文件,可以包含一组特定的设置,如特定的代理服务器、镜像站点等。
- activeProfiles:激活的配置文件列表,Maven会使用这些配置文件中的设置。
值得注意的是,settings.xml文件中的设置可以被pom.xml文件中的设置覆盖。
2.重要结构说明
2.1localRepository
用于指定本地仓库位置,即 jar 包下载存储的位置(使用时优先从本地仓库加载,没有时再去远程仓库加载)
<localRepository>D:\xxx\mvn\repository</localRepository>
2.2server
一般用于定义远程私服的认证信息:
<server>
<id>releases</id>
<username>zhangsan</username>
<password>123456</password>
</server>
在这个示例中,我们定义了一个服务器,其server.id为releases,用户名为zhangsan,密码为123456。
然后,就可以在pom.xml文件中引用这个服务器。例如,如果你想从这个服务器下载依赖,可以这样配置:
<repositories>
<repository>
<id>releases</id>
<url>http://example.com/repo</url>
</repository>
</repositories>
或者,如果你想把项目部署到这个服务器,你可以这样配置:
<distributionManagement>
<repository>
<id>releases</id>
<url>scp://example.com/path/to/repo</url>
</repository>
</distributionManagement>
在这两个例子中,repository.id与settings.xml文件中的server.id相匹配,所以Maven会使用对应的用户名和密码进行身份验证。
注意:出于安全考虑,不建议在settings.xml文件中明文存储密码。你可以使用Maven的密码加密功能来加密密码。
如果定义了多个 repository,maven 会如何选择?
- Maven会按照它们在pom.xml文件中的顺序来使用这些仓库。
- 当Maven需要下载一个依赖或插件时,它会首先从第一个仓库尝试下载。如果第一个仓库中没有这个依赖或插件,或者下载失败,那么Maven会尝试从第二个仓库下载,以此类推,直到下载成功或者所有的仓库都尝试过。
2.2.1全部配置
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<!--配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中。 -->
<servers>
<!--服务器元素包含配置服务器时需要的信息 -->
<server>
<!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。 -->
<id>server001</id>
<!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 -->
<username>my_login</username>
<!--鉴权密码 。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。密码加密功能已被添加到2.1.0 +。详情请访问密码加密页面 -->
<password>my_password</password>
<!--鉴权时使用的私钥位置。和前两个元素类似,私钥位置和私钥密码指定了一个私钥的路径(默认是${user.home}/.ssh/id_dsa)以及如果需要的话,一个密语。将来passphrase和password元素可能会被提取到外部,但目前它们必须在settings.xml文件以纯文本的形式声明。 -->
<privateKey>${usr.home}/.ssh/id_dsa</privateKey>
<!--鉴权时使用的私钥密码。 -->
<passphrase>some_passphrase</passphrase>
<!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775。 -->
<filePermissions>664</filePermissions>
<!--目录被创建时的权限。 -->
<directoryPermissions>775</directoryPermissions>
</server>
</servers>
...
</settings>
2.3mirrors
定义了一些镜像的配置,包括镜像的 ID、名称和 URL,通常用于下载依赖:
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
其中id与name用来标识唯一的仓库,url为镜像仓库地址,mirrorOf用来匹配当请求什么仓库依赖时使用该镜像。
这里介绍下<mirrorOf>配置的各种选项
<mirrorOf>*<mirrorOf>:匹配所有远程仓库。<mirrorOf>external:*<mirrorOf>:匹配所有远程仓库,使用localhost的除外,使用file://协议的除外。也就是说,匹配所有不在本机上的远程仓库。<mirrorOf>repo1,repo2<mirrorOf>:匹配仓库repo1h和repo2,使用逗号分隔多个远程仓库。<mirrorOf>*,!repo1<mirrorOf>:匹配所有远程仓库,repo1除外,使用感叹号将仓库从匹配中排除。
需要注意的是,由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,Maven仍将无法访问被镜像仓库,因而将无法下载构件。
此外, maven 读取mirror 配置是 从上往下读取的,因此谨慎配置<mirrorOf>*<mirrorOf>,因为如果第一个镜像仓库配置了如此标志,那么如果该仓库即使不存在对应依赖也不会向下游查询。
2.3.1阿里镜像
| 仓库名称 | 阿里云仓库地址 | 阿里云仓库地址(老版) | 源地址 |
|---|---|---|---|
| central | maven.aliyun.com/repository/… | maven.aliyun.com/nexus/conte… | repo1.maven.org/maven2/ |
| public | maven.aliyun.com/repository/… | maven.aliyun.com/nexus/conte… | central仓和jcenter仓的聚合仓 |
central和public区别在于:
- 阿里云仓库中的
central是专门针对 Maven 中央仓库的镜像。 - 而
public仓库则阿里云对多个官方和第三方公共仓库的一个聚合仓库,它不仅包含了 Maven 中央仓库的内容,还可能包括其他常用的开源仓库如JCenter等
阿里镜像搜索jar包地址:developer.aliyun.com/mvn/search
2.3.1镜像认证
有些镜像站点可能需要身份验证,如:
- 镜像站点是私有的,只对特定的用户或组织开放。
- 镜像站点提供了付费的高级服务,需要用户登录才能使用。
这里也借助 server 提供认证信息:
<servers>
<server>
<id>alimaven</id>
<username>myuser</username>
<password>mypassword</password>
</server>
</servers>
Maven会根据mirror.id查找对应的server.id,并使用其中的认证信息。
2.4profiles
根据环境参数来调整构建配置的列表。用于定义一组profile
seetings中的profile是 pom.xml 中 profile 元素的裁剪版本。
它包含了id、activation、repositories、pluginRepositories 和 properties 元素。这里的 profile 元素只包含这五个子元素是因为这里只关心构建系统这个整体(这正是 settings.xml 文件的角色定位),而非单独的项目对象模型设置。如果一个 settings.xml 中的 profile 被激活,它的值会覆盖任何其它定义在 pom.xml 中带有相同 id 的 profile。
<profiles>
<profile>
<id>development</id>
<properties></properties>
<activation></activation>
<repositories>
<!--包含需要连接到远程仓库的信息 -->
<repository>
<!--远程仓库唯一标识 -->
<id>codehausSnapshots</id>
<!--远程仓库名称 -->
<name>Codehaus Snapshots</name>
<!-- 用于定位和排序 artifact 的仓库布局类型-可以是 default(默认)或者 legacy(遗留)-->
<layout>default</layout>
<!--如何处理远程仓库里发布版本的下载 -->
<releases>
<!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled>false</enabled>
<!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
<updatePolicy>always</updatePolicy>
<!--当Maven验证构件校验文件失败时该怎么做-ignore(忽略),fail(失败),或者warn(警告)。 -->
<checksumPolicy>warn</checksumPolicy>
</releases>
<!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 -->
<snapshots>
<enabled />
<updatePolicy />
<checksumPolicy />
</snapshots>
<!--远程仓库URL,按protocol://hostname/path形式 -->
<url>http://snapshots.maven.codehaus.org/maven2</url>
<!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>dev-plugin-repo</id>
<url>http://dev.example.com/maven2</url>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
(1)properties
定义了一组拓展属性,当对应的profile被激活时该属性有效。一般定义在pom.xml文件中
<!--
1. env.X: 在一个变量前加上"env."的前缀,会返回一个shell环境变量。例如,"env.PATH"指代了$path环境变量(在Windows上是%PATH%)。
2. project.x:指代了POM中对应的元素值。例如: <project><version>1.0</version></project>通过${project.version}获得version的值。
3. settings.x: 指代了settings.xml中对应元素的值。例如:<settings><offline>false</offline></settings>通过 ${settings.offline}获得offline的值。
4. java System Properties: 所有可通过java.lang.System.getProperties()访问的属性都能在POM中使用该形式访问,例如 ${java.home}。
5. x: 在<properties/>元素中,或者外部文件中设置,以${someVar}的形式使用。
-->
<properties>
<user.install>${user.home}/our-project</user.install>
</properties>
(2)pluginRepositories
同repositories差不多,不过该标签定义的是插件的远程仓库。
(3)activation
触发激活该profile的条件。
<activation>
<!--profile默认是否激活的标识 -->
<activeByDefault>false</activeByDefault>
<!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。 -->
<jdk>1.5</jdk>
<!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。 -->
<os>
<!--激活profile的操作系统的名字 -->
<name>Windows XP</name>
<!--激活profile的操作系统所属家族(如 'windows') -->
<family>Windows</family>
<!--激活profile的操作系统体系结构 -->
<arch>x86</arch>
<!--激活profile的操作系统版本 -->
<version>5.1.2600</version>
</os>
<!--如果Maven检测到某一个属性(其值可以在POM中通过${name}引用),其拥有对应的name = 值,Profile就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段 -->
<property>
<!--激活profile的属性的名称 -->
<name>mavenVersion</name>
<!--激活profile的属性的值 -->
<value>2.0.3</value>
</property>
<!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。 -->
<file>
<!--如果指定的文件存在,则激活profile。 -->
<exists>${basedir}/file2.properties</exists>
<!--如果指定的文件不存在,则激活profile。 -->
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
2.5activeProfiles
结合 pofiles 元素,activeProfiles主要用于指定默认激活的Profile:
<activeProfiles>
<activeProfile>development</activeProfile>
</activeProfiles>
即,id = development 的 profile 被激活使用了。
还可以通过命令激活profile
mvn package -P dev
3.mirrors与repositories的关系【重要】
从上文可以看到,repository标签与mirror标签都定义了同一个远程仓库的位置,那么当一个依赖同时存在于两个仓库时,会先加载那个依赖呢?
这里需要阐述一下maven加载真正起作用的repository的步骤,
- 首先获取pom.xml中repository的集合,然后获取setting.xml中mirror中元素。
- 如果repository的
id和mirror的mirrorOf的值相同,则该mirror替代该repository。 - 如果该repository找不到对应的mirror,则使用其本身。
- 依此可以得到最终起作用的repository集合。可以理解mirror是复写了对应id的repository。
mirror相当于一个拦截器,会拦截被mirrorOf匹配到的repository,在匹配到后,会用mirror里定义的url替换掉repository。