Gradle 源码分析(三)

1. 写在前面

在 Gradle源码分析(二)一文中,我们分析了Gradle构建流程的 LoadSettings 阶段,这里将分析 Configure 阶段(gradle 源码版本为 5.6.4)。

2. Configure

2.1 整体实现

这里我整理了 Configure 阶段的一些主要操作,并绘制了调用链的时序图。如果对源码不感兴趣的同学只需要看这一部分的内容即可。

2.1.1 时序图

Configure时序图.png

2.1.2 主要操作

Configure 阶段 Gradle 主要做了下面这些事情。

  1. 创建 root project 和 sub project,它们都是 DefaultProject 对象;
  2. 调用 BuildListenerprojectsLoaded()
  3. 开始配置 root project,调用 ProjectEvaluationListenerbeforeEvaluate(),apply 默认插件,编译执行 build.gradle 文件,调用 ProjectEvaluationListenerafterEvaluate()
  4. 遍历 sub project,重复 3 中配置 root project 的过程;
  5. 调用 BuildListenerprojectEvaluated()

2.2 源码分析

2.2.1 创建 Root Project 和 Sub Project

Configure 过程是发生在 DefaultGradleLauncherprepareProjects() 中,先来看看它的源码。

// DefaultGradleLauncher.java
private void prepareProjects() {
    if (stage == Stage.LoadSettings) {
        // 配置 projects
        projectsPreparer.prepareProjects(gradle);
        // 将状态设置为 Configure
        stage = Stage.Configure;
    }
}

这里的 projectsPreparer 是通过反射调用的 BuildScopeServicescreateBuildConfigurer()

// BuildScopeServices.java
protected ProjectsPreparer createBuildConfigurer(ProjectConfigurer projectConfigurer, BuildStateRegistry buildStateRegistry, BuildLoader buildLoader, ListenerManager listenerManager, BuildOperationExecutor buildOperationExecutor) {
    ModelConfigurationListener modelConfigurationListener = listenerManager.getBroadcaster(ModelConfigurationListener.class);
    return new BuildOperatingFiringProjectsPreparer(
        new DefaultProjectsPreparer(
            projectConfigurer,
            buildStateRegistry,
            buildLoader,
            modelConfigurationListener,
            buildOperationExecutor),
        buildOperationExecutor);
}

BuildOperatingFiringProjectsPreparer 对象,并在构造器中传入了 DefaultProjectsPreparer 的对象。毫无疑问,BuildOperatingFiringProjectsPreparerprepareProjects() 最后会调用到 DefaultProjectsPreparerprepareProjects(),所以直接看 DefaultProjectsPreparerprepareProjects()

// DefaultProjectsPreparer.java
public void prepareProjects(GradleInternal gradle) {
    // ...
    buildLoader.load(gradle.getSettings(), gradle);
    // ...
}

这里的 buildLoader 是通过反射调用的 BuildScoeServicescreateBuildLoader()

// BuildScoeServices.java
protected BuildLoader createBuildLoader(IGradlePropertiesLoader propertiesLoader, IProjectFactory projectFactory, BuildOperationExecutor buildOperationExecutor) {
    return new NotifyingBuildLoader(
        new ProjectPropertySettingBuildLoader(
            propertiesLoader,
            new InstantiatingBuildLoader(
                projectFactory
            )
        ),
        buildOperationExecutor
    );
}

来看看 NotifyingBuildLoaderload()

// NotifyingBuildLoader.java
public void load(final SettingsInternal settings, final GradleInternal gradle) {
    buildOperationExecutor.call(new CallableBuildOperation() {

        @Override
        public Void call(BuildOperationContext context) {
            // 1. 调用 ProjectPropertySettingBuildLoader 的 load()
            buildLoader.load(settings, gradle);
        }
    });
    buildOperationExecutor.run(new RunnableBuildOperation() {
        @Override
        public void run(BuildOperationContext context) {
            // 2. load()走完后,会执行 BuildListener 的 projectesLoaded(),记住这里,后面会提到。
            gradle.getBuildListenerBroadcaster().projectsLoaded(gradle);
        }
    });
}

这里调用了 ProjectPropertySettingBuildLoaderload()

// ProjectPropertySettingBuildLoader.java
public void load(SettingsInternal settings, GradleInternal gradle) {
    // 1. 调用 InstantiatingBuildLoader 的 load()
    buildLoader.load(settings, gradle);
    // 2. 解析 project 目录下的 gradle.properties 配置的属性,简单了解一下
    setProjectProperties(gradle.getRootProject(), new CachingPropertyApplicator());
}

这里调用了 InstantiatingBuildLoaderload()

// InstantiatingBuildLoader.java
public void load(SettingsInternal settings, GradleInternal gradle) {
    load(settings.getRootProject(), settings.getDefaultProject(), gradle, settings.getRootClassLoaderScope());
}

private void load(ProjectDescriptor rootProjectDescriptor, ProjectDescriptor defaultProject, GradleInternal gradle, ClassLoaderScope buildRootClassLoaderScope) {
    createProjects(rootProjectDescriptor, gradle, buildRootClassLoaderScope);
    attachDefaultProject(defaultProject, gradle);
}

private void attachDefaultProject(ProjectDescriptor defaultProject, GradleInternal gradle) {
    gradle.setDefaultProject(gradle.getRootProject().getProjectRegistry().getProject(defaultProject.getPath()));
}

private void createProjects(ProjectDescriptor rootProjectDescriptor, GradleInternal gradle, ClassLoaderScope buildRootClassLoaderScope) {
    // 1. 配置 root project
    ProjectInternal rootProject = projectFactory.createProject(rootProjectDescriptor, null, gradle, buildRootClassLoaderScope.createChild("root-project"), buildRootClassLoaderScope);
    // 设置 root project
    gradle.setRootProject(rootProject);
    // 调用 addProjects() 遍历 sub project,创建 sub project
    addProjects(rootProject, rootProjectDescriptor, gradle, buildRootClassLoaderScope);
}

private void addProjects(ProjectInternal parent, ProjectDescriptor parentProjectDescriptor, GradleInternal gradle, ClassLoaderScope buildRootClassLoaderScope) {
    // 遍历 sub project,创建 sub project 
    for (ProjectDescriptor childProjectDescriptor : parentProjectDescriptor.getChildren()) {
        ProjectInternal childProject = projectFactory.createProject(childProjectDescriptor, parent, gradle, parent.getClassLoaderScope().createChild("project-" + childProjectDescriptor.getName()), buildRootClassLoaderScope);
        addProjects(childProject, childProjectDescriptor, gradle, buildRootClassLoaderScope);
    }
}

可以看到,这里主要是通过的 projectFactorycreateProject() 来创建 Project 对象的;而 projectFactory 是通过反射调用的 BuildScopeServicescreateProjectFactory()

// BuildScopeServices.java
protected IProjectFactory createProjectFactory(Instantiator instantiator, ProjectRegistry projectRegistry) {
    return new ProjectFactory(instantiator, projectRegistry);
}

ProjectFactory 对象,来看看其 createProject() 做了什么事情。

// ProjectFactory.java
public DefaultProject createProject(ProjectDescriptor projectDescriptor, ProjectInternal parent, GradleInternal gradle, ClassLoaderScope selfClassLoaderScope, ClassLoaderScope baseClassLoaderScope) {
    // 获取到 build.gradle 
    File buildFile = projectDescriptor.getBuildFile();
    // 加载 build.gradle 
    TextResource resource = resourceLoader.loadFile("build file", buildFile);
    ScriptSource source = new TextResourceScriptSource(resource);
    // 创建 DefaultProject 对象
    DefaultProject project = instantiator.newInstance(DefaultProject.class,
            projectDescriptor.getName(),
            parent,
            projectDescriptor.getProjectDir(),
            buildFile,
            source,
            gradle,
            gradle.getServiceRegistryFactory(),
            selfClassLoaderScope,
            baseClassLoaderScope
    );
    // ...
    if (parent != null) {
        // sub project 添加到其 parent 里面
        parent.addChildProject(project);
    }
    // 注册 project
    projectRegistry.addProject(project);

    return project;
}

这里会创建 project 对象,然后注册 project。

2.2.2 调用 BuildListener 的 projectsLoaded()

创建完 root project 和 sub project 后,思绪该回到之前提到过的 NotifyingBuildLoaderload() 了。

// NotifyingBuildLoader.java
public void load(final SettingsInternal settings, final GradleInternal gradle) {
    buildOperationExecutor.call(new CallableBuildOperation() {
        @Override
        public BuildOperationDescriptor.Builder description() {
        @Override
        public Void call(BuildOperationContext context) {
            // 这里往下走的是前面创建 root project 和 sub project 的过程
            buildLoader.load(settings, gradle);
            return null
        }
    });
    buildOperationExecutor.run(new RunnableBuildOperation() {
        @Override
        public void run(BuildOperationContext context) {
            // 走完 load() 后,回调用 BuildListener 的 projectsLoaded()
            gradle.getBuildListenerBroadcaster().projectsLoaded(gradle);
        }
    });
}

可以看到在 NotifyingBuildLoaderload() 里面在走完 load() 流程后,会执行 BuildListenerprojectsLoaded()

2.2.3 配置 Project

看完 load() 过程,该回到 DefaultProjectPreparerprepareProjects() 继续往下看了。

// DefaultProjectPreparer.java
public void prepareProjects(GradleInternal gradle) {
    maybeInformAboutIncubatingMode(gradle);

    buildLoader.load(gradle.getSettings(), gradle);
    // ...
    // 如果设置了参数 --configure-on-demand 进行按需构建,则只会配置 root project 和 tasks 需要的 projects
    if (gradle.getStartParameter().isConfigureOnDemand()) {
        projectConfigurer.configure(gradle.getRootProject());
    } else {
        // 如果没有设置按需配置,则默认会构建所有的 projects
        projectConfigurer.configureHierarchy(gradle.getRootProject());
        // 这里记一下,也是调用生命周期方法
        new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);
    }
}

可以看到在 load() 之后,会判断是否有 --configure-on-demand 参数配置,如果配置了这个参数,gradle 会进行按需配置(只会构建 root project 和 tasks 需要的 projects);如果没有配置,则默认会构建所有的 projects,它是包含 root projects 的配置过程的,所以这里看 configureHierarchy() 即可。projectConfigurer 是通过反射调用的 BuildScopeServicescreateProjectConfigurer()

// BuildScopeServices.java
protected ProjectConfigurer createProjectConfigurer(BuildCancellationToken cancellationToken) {
    return new TaskPathProjectEvaluator(cancellationToken);
}

TaskPathProjectEvaluator 对象,来看看其 configureHierarchy()

// TaskPathProjectEvaluator.java
public void configure(ProjectInternal project) {
    if (cancellationToken.isCancellationRequested()) {
        throw new BuildCancelledException();
    }
    project.evaluate();
}

@Override
public void configureHierarchy(ProjectInternal project) {
    // 1. 先配置 root project,这个和 --configure-on-demand 是一样的
    configure(project);
    // 2. 然后遍历 sub project,配置 sub project
    for (Project sub : project.getSubprojects()) {
        configure((ProjectInternal) sub);
    }
}

可以看到 configureHierarchy() 会先走 --configure-on-demand 的配置过程,先配置 root project, 然后再配置所有的 sub project。这里的 project 即前面创建的 DefaultProject,来看看其 evaluate()

// DefaultProject.java
public DefaultProject evaluate() {
    getProjectEvaluator().evaluate(this, state);
    return this;
}

public ProjectEvaluator getProjectEvaluator() {
    if (projectEvaluator == null) {
        projectEvaluator = services.get(ProjectEvaluator.class);
    }
    return projectEvaluator;
}

这里的 projectEvaluator 是通过反射调用的 BuildScopeServicescreateProjectEvaluator()

// BuildScopeServices.java
protected ProjectEvaluator createProjectEvaluator(BuildOperationExecutor buildOperationExecutor, CachingServiceLocator cachingServiceLocator, ScriptPluginFactory scriptPluginFactory) {
    ConfigureActionsProjectEvaluator withActionsEvaluator = new ConfigureActionsProjectEvaluator(
        // 这里需要注意一下,一般project都会有默认的任务,其实就是这个类在作怪,它里面执行的时候,会给project apply 默认的插件,然后插件里面会创建任务,所以每个project 才会有一些默认的任务
        PluginsProjectConfigureActions.from(cachingServiceLocator),
        // 这里是解析执行 build.gradle的地方
        new BuildScriptProcessor(scriptPluginFactory),
        new DelayedConfigurationActions()
    );
    return new LifecycleProjectEvaluator(buildOperationExecutor, withActionsEvaluator);
}

需要注意一下,这里在创建 ConfigureActionsProjectEvaluator 的时候传入了 PluginsProjectConfigureActions.from() ,这个东西有点意思滴嘞,来看看它做了什么。

// PluginsProjectConfigureActions.java
public static ProjectConfigureAction from(ServiceLocator serviceLocator) {
    return of(ProjectConfigureAction.class, serviceLocator);
}

public static > ProjectConfigureAction of(Class serviceType,
                                                                            ServiceLocator serviceLocator) {
    return new PluginsProjectConfigureActions(
        ImmutableList.>copyOf(
            serviceLocator.getAll(serviceType)));
}

这里的 serviceLocator 是通过反射调用的 GlobalScopeServicescreatePluginsServiceLocator()

// GlobalScopeServices.java
CachingServiceLocator createPluginsServiceLocator(ClassLoaderRegistry registry) {
    return CachingServiceLocator.of(
        new DefaultServiceLocator(registry.getPluginsClassLoader())
    );
}

直接看 DefaultServiceLocatorgetAll()

// DefaultServiceLocator.java
public  List getAll(Class serviceType) throws UnknownServiceException {
    List> factories = findFactoriesForServiceType(serviceType);
    ArrayList services = new ArrayList();
    for (ServiceFactory factory : factories) {
        services.add(factory.create());
    }
    return services;
}

private  List> findFactoriesForServiceType(Class serviceType) {
    return factoriesFor(serviceType, implementationsOf(serviceType));
}

public  List> implementationsOf(Class serviceType) {
    try {
        return findServiceImplementations(serviceType);
    } catch (ServiceLookupException e) {
        throw e;
    } catch (Exception e) {
        throw new ServiceLookupException(String.format("Could not determine implementation classes for service '%s'.", serviceType.getName()), e);
    }
}
private  List> findServiceImplementations(Class serviceType) throws IOException {
    String resourceName = "META-INF/services/" + serviceType.getName();
    Set implementationClassNames = new HashSet();
    List> implementations = new ArrayList>();
    for (ClassLoader classLoader : classLoaders) {
        Enumeration resources = classLoader.getResources(resourceName);
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            List implementationClassNamesFromResource;
            try {
                implementationClassNamesFromResource = extractImplementationClassNames(resource);
                if (implementationClassNamesFromResource.isEmpty()) {
                    throw new RuntimeException(String.format("No implementation class for service '%s' specified.", serviceType.getName()));
                }
            } catch (Throwable e) {
                throw new ServiceLookupException(String.format("Could not determine implementation class for service '%s' specified in resource '%s'.", serviceType.getName(), resource), e);
            }

            for (String implementationClassName : implementationClassNamesFromResource) {
                if (implementationClassNames.add(implementationClassName)) {
                    try {
                        Class implClass = classLoader.loadClass(implementationClassName);
                        if (!serviceType.isAssignableFrom(implClass)) {
                            throw new RuntimeException(String.format("Implementation class '%s' is not assignable to service class '%s'.", implementationClassName, serviceType.getName()));
                        }
                        implementations.add(implClass.asSubclass(serviceType));
                    } catch (Throwable e) {
                        throw new ServiceLookupException(String.format("Could not load implementation class '%s' for service '%s' specified in resource '%s'.", implementationClassName, serviceType.getName(), resource), e);
                    }
                }
            }
        }
    }
    return implementations;
}

这个过程有没有一点点的熟悉,不就是我们在 Gradle 源码分析(一) 里面分析 PluginServiceRegistry 的注册流程一样的吗,只不过那边是传入的 PluginServiceRegistry.class,这里传入的是 ProjectConfigureAction.class,所以实际上这个流程是在找 META-INF/services/org.gradle.configuration.project.ProjectConfigureAction 文件下配置的 ProjectConfigureAction

ProjectConfigureAction.png

这里有三个比较重要的 ProjectConfigureAction

  • BuildInitAutoApplyAction
  • WrapperPluginAutoApplyAction
  • HelpTasksAutoApplyAction

一个一个来看,它们究竟做了什么。

2.2.3.1 BuildInitAutoApplyAction

先来看看 BuildInitAutoApplyAction 的源码。

// BuildInitAutoApplyAction.java
public class BuildInitAutoApplyAction implements ProjectConfigureAction {

    @Override
    public void execute(final ProjectInternal project) {
        project.getPluginManager().apply("org.gradle.build-init");
    }

}

这里给 project 添加了插件 org.gradle.build-init,如果你写过 gradle 插件,那么一定清楚注册插件的地方是在 META-INF/gradle-plugins 下面。

org.gradle.build-init.png

它对应的是 BuildInitPlugin 类,来看看它的源码。

// BuildInitPlugin.java
public class BuildInitPlugin implements Plugin {
    @Override
    public void apply(final Project project) {
        // 如果是 root project,注册 init task
        if (project.getParent() == null) {
            project.getTasks().register("init", InitBuild.class, new Action() {
                @Override
                public void execute(InitBuild initBuild) {
                    initBuild.setGroup("Build Setup");
                    initBuild.setDescription("Initializes a new Gradle build.");

                    initBuild.onlyIf(new Spec() {
                        @Override
                        public boolean isSatisfiedBy(Task element) {
                            Object skippedMsg = reasonToSkip(project);
                            if (skippedMsg != null) {
                                project.getLogger().warn((String) skippedMsg);
                                return false;
                            }

                            return true;
                        }
                    });

                    initBuild.dependsOn(new Callable() {
                        @Override
                        public String call() throws Exception {
                            if (reasonToSkip(project) == null) {
                                return "wrapper";
                            } else {
                                return null;
                            }
                        }
                    });
                }
            });
        }
    }
}

这个插件会给 root project 注册 init Task。

2.2.3.2 WrapperPluginAutoApplyAction

来看看 WrapperPluginAutoApplyAction 的源码。

public class WrapperPluginAutoApplyAction implements ProjectConfigureAction {
    @Override
    public void execute(ProjectInternal project) {
        project.getPluginManager().apply("org.gradle.wrapper");
    }
}

可以看到,它给 project 添加了插件 org.gradle.wrapper,同样的在 META-INF/gradle-plugins 下搜索这个插件的注册文件。

org.gradle.wrapper.png

它对应的是 WrapperPlugin,来看看其源码。

// WrapperPlugin.java
public class WrapperPlugin implements Plugin {
    @Override
    public void apply(Project project) {
        // 给root project 注册 wrapper task
        if (project.getParent() == null) {
            project.getTasks().register("wrapper", Wrapper.class, new Action() {
                @Override
                public void execute(Wrapper wrapper) {
                    wrapper.setGroup("Build Setup");
                    wrapper.setDescription("Generates Gradle wrapper files.");
                }
            });
        }
    }
}

可以看到,这里给 root project 注册 wrapper task。

2.2.3.3 HelpTasksAutoApplyAction

最后来看看 HelpTasksAutoApplyAction 的源码。

// HelpTasksAutoApplyAction.java
public class HelpTasksAutoApplyAction implements ProjectConfigureAction {
    @Override
    public void execute(ProjectInternal project) {
        project.getPluginManager().apply("org.gradle.help-tasks");
    }
}

这里给 project 注册了插件 org.gradle.help-tasks,同样在 META-INF/gradle-plugins 下搜索这个插件的注册文件。


org.gradle.help-tasks.png

它对应的是 HelpTasksPlugin ,来看看其源码。

// HelpTasksPlugin.java
    public void apply(final ProjectInternal project) {
        final TaskContainerInternal tasks = project.getTasks();

        // static classes are used for the actions to avoid implicitly dragging project/tasks into the model registry
        String projectName = project.toString();
        // 注册 help task
        tasks.register(ProjectInternal.HELP_TASK, Help.class, new HelpAction());
        // 注册 projects task
        tasks.register(ProjectInternal.PROJECTS_TASK, ProjectReportTask.class, new ProjectReportTaskAction(projectName));
        // 注册 tasks task
        tasks.register(ProjectInternal.TASKS_TASK, TaskReportTask.class, new TaskReportTaskAction(projectName, project.getChildProjects().isEmpty()));
        // 注册 properties task
        tasks.register(PROPERTIES_TASK, PropertyReportTask.class, new PropertyReportTaskAction(projectName));
        // 注册 dependencyInsight task
        tasks.register(DEPENDENCY_INSIGHT_TASK, DependencyInsightReportTask.class, new DependencyInsightReportTaskAction(projectName));
        // 注册 dependencies task
        tasks.register(DEPENDENCIES_TASK, DependencyReportTask.class, new DependencyReportTaskAction(projectName));
        // 注册 buildEnvironment task
        tasks.register(BuildEnvironmentReportTask.TASK_NAME, BuildEnvironmentReportTask.class, new BuildEnvironmentReportTaskAction(projectName));
        // 注册 components task
        tasks.register(COMPONENTS_TASK, ComponentReport.class, new ComponentReportAction(projectName));
        // 注册 model task
        tasks.register(MODEL_TASK, ModelReport.class, new ModelReportAction(projectName));
        // 注册 dependentComponents task
        tasks.register(DEPENDENT_COMPONENTS_TASK, DependentComponentsReport.class, new DependentComponentsReportAction(projectName));
    }

可以看到这里给所有的 project 注册了许多任务,这也是经常说的 project 会有一些默认任务,它就是通过这个插件进行注册的。

经过这个小插曲,思绪该回到 BuildScopeServicecreateProjectEvaluator() 了。

// BuildScopeService.java
protected ProjectEvaluator createProjectEvaluator(BuildOperationExecutor buildOperationExecutor, CachingServiceLocator cachingServiceLocator, ScriptPluginFactory scriptPluginFactory) {
    ConfigureActionsProjectEvaluator withActionsEvaluator = new ConfigureActionsProjectEvaluator(
        PluginsProjectConfigureActions.from(cachingServiceLocator),
        new BuildScriptProcessor(scriptPluginFactory),
        new DelayedConfigurationActions()
    );
    return new LifecycleProjectEvaluator(buildOperationExecutor, withActionsEvaluator);
}

来看看 LifecycleProjectEvaluatorevaluate()

// LifecycleProjectEvaluator.java
public void evaluate(final ProjectInternal project, final ProjectStateInternal state) {
    if (state.isUnconfigured()) {
        buildOperationExecutor.run(new EvaluateProject(project, state));
    }
}

// EvaluateProject (内部类)
public void run(final BuildOperationContext context) {
    project.getMutationState().withMutableState(new Runnable() {
        @Override
        public void run() {
            try {
                // 1. 将 project 状态设置为 IN_BEFORE_EVALUATE
                state.toBeforeEvaluate();
                // 2. 调用 ProjectEvaluationListener 的 beforeEvaluate()
                buildOperationExecutor.run(new NotifyBeforeEvaluate(project, state));

                if (!state.hasFailure()) {
                    // 3. 将 project 的状态设置为 IN_EVALUATE
                    state.toEvaluate();
                    try {
                        // 4. 调用 ConfigureActionsProjectEvaluator 的 evaluate()
                        delegate.evaluate(project, state);
                    } catch (Exception e) {
                        addConfigurationFailure(project, state, e, context);
                    } finally {
                        // 5. 将 project 状态设置为 IN_AFTER_EVALUATE
                        state.toAfterEvaluate();
                        // 6. 调用 ProjectEvaluationListener 的 afterEvaluate()
                        buildOperationExecutor.run(new NotifyAfterEvaluate(project, state));
                    }
                }

                if (state.hasFailure()) {
                    state.rethrowFailure();
                } else {
                    context.setResult(ConfigureProjectBuildOperationType.RESULT);
                }
            } finally {
                // 7. 将 project 状态设置为 CONFIGURED
                state.configured();
            }
        }
    });
}

// NotifyBeforeEvaluate(内部类)
public void run(BuildOperationContext context) {
    try {
        project.getProjectEvaluationBroadcaster().beforeEvaluate(project);
        context.setResult(NotifyProjectBeforeEvaluatedBuildOperationType.RESULT);
    } catch (Exception e) {
        addConfigurationFailure(project, state, e, context);
    }
}

// NotifyAfterEvaluate (内部类)
public void run(BuildOperationContext context) {
    ProjectEvaluationListener nextBatch = project.getProjectEvaluationBroadcaster();
    Action fireAction = new Action() {
        @Override
        public void execute(ProjectEvaluationListener listener) {
            listener.afterEvaluate(project, state);
        }
    };
    // ...
}

可以看到这里主要做了如下事情:

  1. 将 project 的状态设置为 IN_BEFORE_EVALUATE
  2. 调用 ProjectEvaluationListenerbeforeEvaluate()
  3. 将 project 的状态设置为 IN_EVALUATE
  4. 调用 ConfigureActionsProjectEvaluatorevaluate()
  5. 将 project 的状态设置为 IN_AFTER_EVALUATE
  6. 调用 ProjectEvaluationListenerafterEvaluate()
  7. 将 project 的状态设置为 CONFIGURED

接下来看 ConfigureActionsProjectEvaluatorevaluate()

// ConfigureActionsProjectEvaluator.java
public void evaluate(ProjectInternal project, ProjectStateInternal state) {
    for (ProjectConfigureAction configureAction : configureActions) {
        configureAction.execute(project);
    }
}

这里调用了 configureActionsexecute(),也就是前面在创建 ConfigureActionsProjectEvaluator 时传入的 PluginsProjectConfigureActions.from(cachingServiceLocator)BuildScriptProcessorexecute();前者已经分析了,是给 project 注册一些任务;而后者就是解析执行 build.gradle 了,来看看其源码。

// BuildScriptProcessor.java
public void execute(final ProjectInternal project) {
    if (LOGGER.isInfoEnabled()) {
        LOGGER.info("Evaluating {} using {}.", project, project.getBuildScriptSource().getDisplayName());
    }
    final Timer clock = Time.startTimer();
    try {
        final ScriptPlugin configurer = configurerFactory.create(project.getBuildScriptSource(), project.getBuildscript(), project.getClassLoaderScope(), project.getBaseClassLoaderScope(), true);
        project.getMutationState().withMutableState(new Runnable() {
            @Override
            public void run() {
                configurer.apply(project);
            }
        });
    }
}

到这里,root project 和 sub project 也就配置完了。

2.2.4 调用 BuildListener 的 projectsEvaluated()

回到 DefaultProjectPreparerprepareProjects(),接着 configureHierarchy() 往后看。

// DefaultProjectPreparer.java
public void prepareProjects(GradleInternal gradle) {
    maybeInformAboutIncubatingMode(gradle);

    buildLoader.load(gradle.getSettings(), gradle);

    if (gradle.getParent() == null) {
        buildRegistry.beforeConfigureRootBuild();
    }
    if (gradle.getStartParameter().isConfigureOnDemand()) {
        projectConfigurer.configure(gradle.getRootProject());
    } else {
        projectConfigurer.configureHierarchy(gradle.getRootProject());
        // 创建 ProjectsEvaluatedNotifier ,调用 notify()
        new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);
    }
}

它创建了 ProjectsEvaluatedNotifier,并调用了 notify()

// ProjectsEvaluatedNotifier.java
public void notify(GradleInternal gradle) {
    buildOperationExecutor.run(new NotifyProjectsEvaluatedListeners(gradle));
}

// NotifyProjectsEvaluatedListeners(内部类)
private class NotifyProjectsEvaluatedListeners implements RunnableBuildOperation {
    @Override
    public void run(BuildOperationContext context) {
        gradle.getBuildListenerBroadcaster().projectsEvaluated(gradle);
    }
}

这里最终调用了 BuildListenerprojectsEvaluated();最后回到 DefaultGradleLauncherprepareProjects()

// DefaultGradleLauncher.java
private void prepareProjects() {
    if (stage == Stage.LoadSettings) {
        projectsPreparer.prepareProjects(gradle);
        // 设置状态为 Configure
        stage = Stage.Configure;
    }
}

执行完 prepareProjects() 后,会将状态设置为 Configure。至此,Gradle 的 Configure 阶段就分析完了。

你可能感兴趣的:(Gradle 源码分析(三))