1. 写在前面
在 Gradle源码分析(二)一文中,我们分析了Gradle构建流程的
LoadSettings
阶段,这里将分析Configure
阶段(gradle 源码版本为 5.6.4)。
2. Configure
2.1 整体实现
这里我整理了 Configure
阶段的一些主要操作,并绘制了调用链的时序图。如果对源码不感兴趣的同学只需要看这一部分的内容即可。
2.1.1 时序图
2.1.2 主要操作
Configure
阶段 Gradle 主要做了下面这些事情。
- 创建 root project 和 sub project,它们都是
DefaultProject
对象; - 调用
BuildListener
的projectsLoaded()
; - 开始配置 root project,调用
ProjectEvaluationListener
的beforeEvaluate()
,apply 默认插件,编译执行 build.gradle 文件,调用ProjectEvaluationListener
的afterEvaluate()
; - 遍历 sub project,重复 3 中配置 root project 的过程;
- 调用
BuildListener
的projectEvaluated()
。
2.2 源码分析
2.2.1 创建 Root Project 和 Sub Project
Configure
过程是发生在 DefaultGradleLauncher
的 prepareProjects()
中,先来看看它的源码。
// DefaultGradleLauncher.java
private void prepareProjects() {
if (stage == Stage.LoadSettings) {
// 配置 projects
projectsPreparer.prepareProjects(gradle);
// 将状态设置为 Configure
stage = Stage.Configure;
}
}
这里的 projectsPreparer
是通过反射调用的 BuildScopeServices
的 createBuildConfigurer()
。
// 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
的对象。毫无疑问,BuildOperatingFiringProjectsPreparer
的 prepareProjects()
最后会调用到 DefaultProjectsPreparer
的 prepareProjects()
,所以直接看 DefaultProjectsPreparer
的 prepareProjects()
。
// DefaultProjectsPreparer.java
public void prepareProjects(GradleInternal gradle) {
// ...
buildLoader.load(gradle.getSettings(), gradle);
// ...
}
这里的 buildLoader
是通过反射调用的 BuildScoeServices
的 createBuildLoader()
。
// BuildScoeServices.java
protected BuildLoader createBuildLoader(IGradlePropertiesLoader propertiesLoader, IProjectFactory projectFactory, BuildOperationExecutor buildOperationExecutor) {
return new NotifyingBuildLoader(
new ProjectPropertySettingBuildLoader(
propertiesLoader,
new InstantiatingBuildLoader(
projectFactory
)
),
buildOperationExecutor
);
}
来看看 NotifyingBuildLoader
的 load()
。
// 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);
}
});
}
这里调用了 ProjectPropertySettingBuildLoader
的 load()
。
// 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());
}
这里调用了 InstantiatingBuildLoader
的 load()
。
// 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);
}
}
可以看到,这里主要是通过的 projectFactory
的 createProject()
来创建 Project
对象的;而 projectFactory
是通过反射调用的 BuildScopeServices
的 createProjectFactory()
。
// 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 后,思绪该回到之前提到过的 NotifyingBuildLoader
的 load()
了。
// 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);
}
});
}
可以看到在 NotifyingBuildLoader
的 load()
里面在走完 load()
流程后,会执行 BuildListener
的 projectsLoaded()
。
2.2.3 配置 Project
看完 load()
过程,该回到 DefaultProjectPreparer
的 prepareProjects()
继续往下看了。
// 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
是通过反射调用的 BuildScopeServices
的 createProjectConfigurer()
。
// 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
是通过反射调用的 BuildScopeServices
的 createProjectEvaluator()
。
// 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
是通过反射调用的 GlobalScopeServices
的 createPluginsServiceLocator()
。
// GlobalScopeServices.java
CachingServiceLocator createPluginsServiceLocator(ClassLoaderRegistry registry) {
return CachingServiceLocator.of(
new DefaultServiceLocator(registry.getPluginsClassLoader())
);
}
直接看 DefaultServiceLocator
的 getAll()
。
// 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
。
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 下面。
它对应的是 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 下搜索这个插件的注册文件。
它对应的是 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 下搜索这个插件的注册文件。
它对应的是 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 会有一些默认任务,它就是通过这个插件进行注册的。
经过这个小插曲,思绪该回到 BuildScopeService
的 createProjectEvaluator()
了。
// 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);
}
来看看 LifecycleProjectEvaluator
的 evaluate()
。
// 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);
}
};
// ...
}
可以看到这里主要做了如下事情:
- 将 project 的状态设置为
IN_BEFORE_EVALUATE
; - 调用
ProjectEvaluationListener
的beforeEvaluate()
; - 将 project 的状态设置为
IN_EVALUATE
; - 调用
ConfigureActionsProjectEvaluator
的evaluate()
; - 将 project 的状态设置为
IN_AFTER_EVALUATE
; - 调用
ProjectEvaluationListener
的afterEvaluate()
; - 将 project 的状态设置为
CONFIGURED
。
接下来看 ConfigureActionsProjectEvaluator
的 evaluate()
。
// ConfigureActionsProjectEvaluator.java
public void evaluate(ProjectInternal project, ProjectStateInternal state) {
for (ProjectConfigureAction configureAction : configureActions) {
configureAction.execute(project);
}
}
这里调用了 configureActions
的 execute()
,也就是前面在创建 ConfigureActionsProjectEvaluator
时传入的 PluginsProjectConfigureActions.from(cachingServiceLocator)
和 BuildScriptProcessor
的 execute()
;前者已经分析了,是给 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()
回到 DefaultProjectPreparer
的 prepareProjects()
,接着 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);
}
}
这里最终调用了 BuildListener
的 projectsEvaluated()
;最后回到 DefaultGradleLauncher
的 prepareProjects()
。
// DefaultGradleLauncher.java
private void prepareProjects() {
if (stage == Stage.LoadSettings) {
projectsPreparer.prepareProjects(gradle);
// 设置状态为 Configure
stage = Stage.Configure;
}
}
执行完 prepareProjects()
后,会将状态设置为 Configure
。至此,Gradle 的 Configure
阶段就分析完了。