一、概述
maven的settings.xml文件里面有proxy、server、repository、mirror的配置,在配置仓库地址的时候容易混淆
proxy是服务器不能直接访问外网时需要设置的代理服务,不常用
server是服务器要打包上传到私服时,设置私服的鉴权信息
repository是服务器下载jar包的仓库地址
mirror是用于替代仓库地址的镜像地址
下面查看源码来确定repository和mirror的优先顺序
二、初始化远程仓库
在maven的远程仓库初始化时会执行newRepositorySession方法,会创建mirror、proxy、authentication和其它系统环境信息:
this .mavenRepositorySystem.injectMirror(request.getRemoteRepositories(), request.getMirrors());
this .mavenRepositorySystem.injectProxy(session, request.getRemoteRepositories());
this .mavenRepositorySystem.injectAuthentication(session, request.getRemoteRepositories());
|
三、遍历注入镜像
在injectMirror方法中:
public void injectMirror(List<ArtifactRepository> repositories, List<Mirror> mirrors)
{
if ((repositories != null ) && (mirrors != null )) {
for (ArtifactRepository repository : repositories)
{
Mirror mirror = getMirror(repository, mirrors);
injectMirror(repository, mirror);
}
}
}
|
遍历repositories,获得mirror然后注入mirror
注:这里不用担心repositories没数据,因为在之前的初始化repositories方法中会判断没有配置"central"中央仓库的时候加入默认仓库
private void injectDefaultRepositories(MavenExecutionRequest request)
throws MavenExecutionRequestPopulationException
{
Set<String> definedRepositories = this .repositorySystem.getRepoIds(request.getRemoteRepositories());
if (!definedRepositories.contains( "central" )) {
try
{
request.addRemoteRepository( this .repositorySystem.createDefaultRemoteRepository(request));
}
catch (Exception e)
{
throw new MavenExecutionRequestPopulationException( "Cannot create default remote repository." , e);
}
}
}
|
public ArtifactRepository createDefaultRemoteRepository(MavenExecutionRequest request)
throws Exception
{
return createRepository( "https://repo.maven./maven2" , "central" , true , "daily" , false , "daily" , "warn" );
}
|
三、匹配镜像
在getMirror方法中:
public static Mirror getMirror(ArtifactRepository repository, List<Mirror> mirrors)
{
String repoId = repository.getId();
if ((repoId != null ) && (mirrors != null ))
{
for (Mirror mirror : mirrors) {
if ((repoId.equals(mirror.getMirrorOf())) && (matchesLayout(repository, mirror))) {
return mirror;
}
}
for (Mirror mirror : mirrors) {
if ((matchPattern(repository, mirror.getMirrorOf())) && (matchesLayout(repository, mirror))) {
return mirror;
}
}
}
return null ;
}
|
忽略不常用的layout配置,第一个循环优先寻找mirrorOf与repositoryId完全相同的mirror
第二个循环通过规则来匹配mirror,matchPattern的方法:
static boolean matchPattern(ArtifactRepository originalRepository, String pattern)
{
boolean result = false ;
String originalId = originalRepository.getId();
if (( "*" .equals(pattern)) || (pattern.equals(originalId)))
{
result = true ;
}
else
{
String[] repos = pattern.split( "," );
for (String repo : repos) {
if ((repo.length() > 1 ) && (repo.startsWith( "!" )))
{
if (repo.substring( 1 ).equals(originalId))
{
result = false ;
break ;
}
}
else
{
if (repo.equals(originalId))
{
result = true ;
break ;
}
if (( "external:*" .equals(repo)) && (isExternalRepo(originalRepository))) {
result = true ;
} else if ( "*" .equals(repo)) {
result = true ;
}
}
}
}
return result;
}
|
如果是mirrorOf是*号就匹配,如果不是就遍历可能是逗号分隔的mirrorOf值,同时看是否是!号排除的
在找到mirror后会执行injectMirror方法,把匹配的mirror注入到repository里面:
private void injectMirror(ArtifactRepository repository, Mirror mirror)
{
if (mirror != null )
{
ArtifactRepository original = createArtifactRepository(repository.getId(), repository.getUrl(), repository.getLayout(), repository
.getSnapshots(), repository.getReleases());
repository.setMirroredRepositories(Collections.singletonList(original));
repository.setId(mirror.getId());
repository.setUrl(mirror.getUrl());
if (StringUtils.isNotEmpty(mirror.getLayout())) {
repository.setLayout(getLayout(mirror.getLayout()));
}
}
}
|
四、总结
1、在mirrorOf与repositoryId相同的时候优先是使用mirror的地址
2、mirrorOf等于*的时候覆盖所有repository配置
3、存在多个mirror配置的时候mirrorOf等于*放到最后
4、只配置mirrorOf为central的时候可以不用配置repository
我的settings.xml一般这样设置:
<? xml version="1.0" encoding="UTF-8"?>
< settings xmlns="http://maven./SETTINGS/1.0.0"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xsi:schemaLocation="http://maven./SETTINGS/1.0.0 http://maven./xsd/settings-1.0.0.xsd">
< localRepository >X:\工具\maven资源\repository</ localRepository >
< pluginGroups ></ pluginGroups >
< proxies ></ proxies >
< servers ></ servers >
< mirrors >
< mirror >
< id >nexus-aliyun</ id >
< name >Nexus aliyun</ name >
< mirrorOf >central</ mirrorOf >
< url >http://maven.aliyun.com/nexus/content/groups/public</ url >
</ mirror >
< mirror >
< id >nexus-mine</ id >
< name >Nexus mine</ name >
< mirrorOf >*</ mirrorOf >
< url >http://xx.xx.xx.xx/nexus/content/groups/public</ url >
</ mirror >
</ mirrors >
< profiles ></ profiles >
</ settings >
|
nexus-aliyun使用阿里云的镜像作为central中央仓库
nexus-mine作为私服,mirrorOf配置为*来提供中央仓库中不存在的jar包
|