【史上最全的Maven源码讲解(三)】

遗留的问题: 重要,这是我看源码的动机

远程仓库和镜像之间的映射关系?

此处故意逆向查找,其实在常用类中很容易猜出来repos的来源

找到最终repos出现的位置

org.eclipse.aether.internal.impl.DefaultArtifactResolver#resolve

List<RemoteRepository> repos = request.getRepositories();

来自这个属性: org.eclipse.aether.resolution.ArtifactRequest#repositories

通过断点反查到原始传递的类

其实requests是一个实例

org.eclipse.aether.internal.impl.DefaultArtifactResolver#resolveArtifact

public ArtifactResult resolveArtifact( RepositorySystemSession session, ArtifactRequest request )
    throws ArtifactResolutionException {
    return resolveArtifacts( session, Collections.singleton( request ) ).get( 0 );
}

对象在org.apache.maven.project.ProjectModelResolver#resolveModel创建

public ModelSource resolveModel(String groupId, String artifactId, String version)
            throws UnresolvableModelException {
        File pomFile = null;
        if (modelPool != null) {
            pomFile = modelPool.get(groupId, artifactId, version);
        }
        if (pomFile == null) {
            Artifact pomArtifact = new DefaultArtifact(groupId, artifactId, "", "pom", version);
            try {
                // repositories出现,并且已经有了值
                ArtifactRequest request = new ArtifactRequest(pomArtifact, repositories, context);
                request.setTrace(trace);
                pomArtifact = resolver.resolveArtifact(session, request).getArtifact();
            } catch (ArtifactResolutionException e) {}
            pomFile = pomArtifact.getFile();
        }
        return new FileModelSource(pomFile);
    }

说明在ProjectModelResolver声明中期中赋值,所以重点是看这个对象的创建时期

org.apache.maven.model.building.DefaultModelBuilder#readParentExternally

ModelResolver modelResolver = request.getModelResolver(); // 来自request

org.apache.maven.project.DefaultProjectBuilder#build

ModelBuildingRequest request = getModelBuildingRequest( config ); // repositories来自 config
private ModelBuildingRequest getModelBuildingRequest( InternalConfig config )    {
        ProjectBuildingRequest configuration = config.request;

        ModelBuildingRequest request = new DefaultModelBuildingRequest(); // request

        RequestTrace trace = RequestTrace.newChild( null, configuration ).newChild( request );

        ModelResolver resolver =new ProjectModelResolver( config.session, trace, repoSystem, repositoryManager, config.repositories, configuration.getRepositoryMerging(), config.modelPool ); // repositories

        request.setValidationLevel( configuration.getValidationLevel() );
        request.setProcessPlugins( configuration.isProcessPlugins() );
        request.setProfiles( configuration.getProfiles() );
        request.setActiveProfileIds( configuration.getActiveProfileIds() );
        request.setInactiveProfileIds( configuration.getInactiveProfileIds() );
        request.setSystemProperties( configuration.getSystemProperties() );
        request.setUserProperties( configuration.getUserProperties() );
        request.setBuildStartTime( configuration.getBuildStartTime() );
        request.setModelResolver( resolver ); // ModelResolver 赋值
        request.setModelCache( config.modelCache );

        return request;
    }

org.apache.maven.project.DefaultProjectBuilder#build

InternalConfig config = new InternalConfig( request, modelPool,useGlobalModelCache() ? getModelCache() : new ReactorModelCache() ); // 来自 request
      InternalConfig(ProjectBuildingRequest request, ReactorModelPool modelPool, ReactorModelCache modelCache) {
            this.request = request;
            this.modelPool = modelPool;
            this.modelCache = modelCache;
            session = LegacyLocalRepositoryManager.overlay(request.getLocalRepository(), equest.getRepositorySession(), repoSystem);
            repositories = RepositoryUtils.toRepos(request.getRemoteRepositories()); // 做了类型不让人
          // ArtifactRepository -> RemoteRepository
        }

org.apache.maven.graph.DefaultGraphBuilder#collectProjects

   private void collectProjects(List<MavenProject> projects, List<File> files, MavenExecutionRequest request)
            throws ProjectBuildingException {
        ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest(); // 对象转换了下

        List<ProjectBuildingResult> results = projectBuilder.build(files, request.isRecursive(),
                projectBuildingRequest);
   }
public ProjectBuildingRequest getProjectBuildingRequest() {
    if (projectBuildingRequest == null) {
        projectBuildingRequest = new DefaultProjectBuildingRequest();
        projectBuildingRequest.setLocalRepository(getLocalRepository());
        projectBuildingRequest.setSystemProperties(getSystemProperties());
        projectBuildingRequest.setUserProperties(getUserProperties());
        projectBuildingRequest.setRemoteRepositories(getRemoteRepositories()); // 远程仓库复制
        projectBuildingRequest.setPluginArtifactRepositories(getPluginArtifactRepositories());
        projectBuildingRequest.setActiveProfileIds(getActiveProfiles());
        projectBuildingRequest.setInactiveProfileIds(getInactiveProfiles());
        projectBuildingRequest.setProfiles(getProfiles());
        projectBuildingRequest.setProcessPlugins(true);
        projectBuildingRequest.setBuildStartTime(getStartTime());
    }

    return projectBuildingRequest;
}

org.apache.maven.graph.DefaultGraphBuilder#getProjectsForMavenReactor

private List<MavenProject> getProjectsForMavenReactor(MavenSession session) throws ProjectBuildingException {
    MavenExecutionRequest request = session.getRequest(); // 从session中获取到
}

org.apache.maven.DefaultMaven#doExecute(org.apache.maven.execution.MavenExecutionRequest)

MavenSession session = new MavenSession(container, repoSession, request, result); 
    public MavenSession(PlexusContainer container, RepositorySystemSession repositorySession,
            MavenExecutionRequest request, MavenExecutionResult result) {
        this.container = container;
        this.request = request; // 是这个request
        this.result = result;
        this.settings = new SettingsAdapter(request);
        this.repositorySession = repositorySession;
    }

org.apache.maven.cli.MavenCli#execute

这是一个重要时机,因为执行填充前后远程仓库数量变化了

cliRequest.request; // 执行前只有profile的repository没有镜像

执行后多了一个默认的中央仓库,也没有镜像

MavenExecutionRequest request = executionRequestPopulator.populateDefaults(cliRequest.request); // 做了一次属性填充
public MavenExecutionRequest populateDefaults(MavenExecutionRequest request)
            throws MavenExecutionRequestPopulationException {
        baseDirectory(request); // 设置base目录

        localRepository(request); // 本地仓库

        populateDefaultPluginGroups(request); // 填充默认插件组

        injectDefaultRepositories(request); // 注入默认仓库

        injectDefaultPluginRepositories(request); // 注入默认插件仓库

        return request; // 封住后返回
    }

那么核心问题来了, 镜像何时将远程仓库替换掉了: 即mirrorOf配置规则何时生效的

记得List repos = request.getRepositories();执行时候是有一部分仓库被镜像掉了,如下结果


remoteRepository: http://dg.artifact.huawei.com/artifactory/maven-group/
remoteRepository: http://cmc.centralrepo.rnd.huawei.com/maven/
	mirroredRepository: http://dg.artifact.huawei.com/artifactory/maven-local-group/ : 被镜像了的一个
remoteRepository: http://dg.artifact.huawei.com/artifactory/maven-group/
	mirroredRepository: https://repo.maven.apache.org/maven2 : 被镜像掉的默认中央仓库

经过寻找在org.apache.maven.model.building.DefaultModelBuilder#configureResolver找到

org.apache.maven.model.building.DefaultModelBuilder#configureResolver
private void configureResolver(ModelResolver modelResolver, Model model, DefaultModelProblemCollector problems,
        boolean replaceRepositories) {
    if (modelResolver == null) {
        return;
    }

    problems.setSource(model);

    List<Repository> repositories = model.getRepositories(); // 这个就是从setting中解析到的两个仓库

    for (Repository repository : repositories) {
        try { // 遍历添加到modelResolver中
            modelResolver.addRepository(repository, replaceRepositories); // TODO : 核心 添加仓库
        } catch (InvalidRepositoryException e) {
            problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE).setMessage(
                    "Invalid repository " + repository.getId() + ": " + e.getMessage())
                    .setLocation(repository.getLocation(""))
                    .setException(e));
        }
    }
}
public void addRepository(final Repository repository, boolean replace) throws InvalidRepositoryException {
    if (!repositoryIds.add(repository.getId())) { // ID存在
        if (!replace) {
            return; // 不替换就return
        }
        // Remove any previous repository with this Id
        removeMatchingRepository(repositories, repository.getId());
        removeMatchingRepository(pomRepositories, repository.getId()); // 如果替换就移除继续执行
    }

    List<RemoteRepository> newRepositories = Collections.singletonList(
            ArtifactDescriptorUtils.toRemoteRepository(repository)); // 转换成集合

    if (ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT.equals(repositoryMerging)) { // 合并
        repositories = remoteRepositoryManager.aggregateRepositories(session, repositories, newRepositories, true);
    } else {
        pomRepositories = remoteRepositoryManager.aggregateRepositories(session, pomRepositories, newRepositories,
                true); // 代码相同, recessiveIsRaw 标记不同, 将结果作为主导仓库,传入下面的方法
        repositories = remoteRepositoryManager.aggregateRepositories(session, pomRepositories, externalRepositories,
                false); // 第二次还有个重要的不同参数externalRepositories
    }
}
public List<RemoteRepository> aggregateRepositories( RepositorySystemSession session,
                                                     List<RemoteRepository> dominantRepositories,
                                                     List<RemoteRepository> recessiveRepositories,
                                                     boolean recessiveIsRaw ){
    if ( recessiveRepositories.isEmpty() ){ // 隐性的仓库如果没有, 就直接返回主导仓库,因为就是要判断它需不需要被镜像
        return dominantRepositories;
    }

    MirrorSelector mirrorSelector = session.getMirrorSelector(); // 镜像选择器,包含了可选的镜像
    AuthenticationSelector authSelector = session.getAuthenticationSelector(); // 用户认证选择器
    ProxySelector proxySelector = session.getProxySelector(); // 代理选择器
	// 第一次肯定没有值,但是隐性仓库的结果会作为主导仓库参数,第二次以recessiveIsRaw = false方式进行第二次调用
    List<RemoteRepository> result = new ArrayList<>( dominantRepositories );

    next: for ( RemoteRepository recessiveRepository : recessiveRepositories ){
        RemoteRepository repository = recessiveRepository; // 可能被镜像的仓库

        if ( recessiveIsRaw ){ // 隐性仓库是原生的
            RemoteRepository mirrorRepository = mirrorSelector.getMirror( recessiveRepository ); // 根据mirrorOf获取被镜像的仓库

            if ( mirrorRepository != null )
            {
                logMirror( session, recessiveRepository, mirrorRepository );
                repository = mirrorRepository;
            }
        }

        String key = getKey( repository );
		// recessiveIsRaw == true时候,一定 不会进入
        for ( ListIterator<RemoteRepository> it = result.listIterator(); it.hasNext(); ){
            }
        }      
    }

    return result;
}
// 好像找错位置了

externalRepositories什么时候赋值的(什么时候解析出仓库被镜像的结果列表)

org.apache.maven.project.DefaultProjectBuilder#getModelBuildingRequest

private ModelBuildingRequest getModelBuildingRequest(InternalConfig config) {
    ProjectBuildingRequest configuration = config.request;

    ModelBuildingRequest request = new DefaultModelBuildingRequest();

    RequestTrace trace = RequestTrace.newChild(null, configuration).newChild(request);

    ModelResolver resolver = new ProjectModelResolver(config.session, trace, repoSystem, repositoryManager,
            config.repositories, configuration.getRepositoryMerging(), config.modelPool);
}
 public ProjectModelResolver(RepositorySystemSession session, RequestTrace trace, RepositorySystem resolver,
            RemoteRepositoryManager remoteRepositoryManager, List<RemoteRepository> repositories,
            ProjectBuildingRequest.RepositoryMerging repositoryMerging, ReactorModelPool modelPool) {
        this.session = session;
        this.trace = trace;
        this.resolver = resolver;
        this.remoteRepositoryManager = remoteRepositoryManager;
        this.pomRepositories = new ArrayList<>();
        this.externalRepositories = Collections.unmodifiableList(new ArrayList<>(repositories)); // 外部仓库赋值
        this.repositories = new ArrayList<>();
        this.repositories.addAll(externalRepositories);
        this.repositoryMerging = repositoryMerging;
        this.repositoryIds = new HashSet<>();
        this.modelPool = modelPool;
    }

此时的仓库已经是

[dg-maven-group (http://dg.artifact.huawei.com/artifactory/maven-group/, default, releases+snapshots), 
mirror-artifactory-maven-group (http://cmc.centralrepo.rnd.huawei.com/maven/, default, releases+snapshots), 
mirror-maven-group (http://dg.artifact.huawei.com/artifactory/maven-group/, default, releases)]
// mirror开头的是镜像仓库
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁月玲珑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值