gradle-configure篇
gradle-3-(configure篇)
1. 入口
DefaultGradleLauncher.java
private void doClassicBuildStages(Stage upTo) {
if (stage == null) {
configurationCache.prepareForConfiguration();
}
prepareSettings();
if (upTo == Stage.LoadSettings) {
return;
}
prepareProjects();
if (upTo == Stage.Configure) {
return;
}
prepareTaskExecution();
if (upTo == Stage.TaskGraph) {
return;
}
configurationCache.save();
runWork();
}
// 配置操作
private void prepareProjects() {
if (stage == Stage.LoadSettings) {
projectsPreparer.prepareProjects(gradle);
stage = Stage.Configure;
}
}
上述方法prepareProjects就是我们传说中的gradle配置阶段
Configure阶段到底做了什么呢?我看先来看下调用链路
2. 调用链路
上面的projectsPreparer对象其实是来自BuildScropServices类中的createBuildConfigurer方法返回值,也就是BuildOperationFiringProjectsPreparer
BuildScropServices.java
从上图可以看出,其实是个链式调用(反射调的,不明白可以看篇一),整体结构还是比较清晰的;
因为configure篇东西有点多,先总结下主要流程,后面在详细展开
3. 总结
configure阶段其实大体可以分为三个部分
- project的初始化
- 创建工程中的各个project对象(反射及递归实现,后面会说)
- 给各工程做些配置(eg,加载gradle.properties属性给每个工程)
- buildSrc工程的编译及构建
- project的构建脚本(通常是build.gradle)的编译与加载
BuildOperationFiringProjectsPreparer其实没做啥事情主要就是代理转发任务,只要看BuildTreePreparingProjectsPreparer即可,它其实就本篇的主要流程,可以看到就是我们上面总结的三大流程
// BuildTreePreparingProjectsPreparer.java
@Override
public void prepareProjects(GradleInternal gradle) {
// Setup classloader for root project, all other projects will be derived from this.
SettingsInternal settings = gradle.getSettings();
ClassLoaderScope settingsClassLoaderScope = settings.getClassLoaderScope();
ClassLoaderScope buildSrcClassLoaderScope = settingsClassLoaderScope.createChild("buildSrc[" + gradle.getIdentityPath() + "]");
gradle.setBaseProjectClassLoaderScope(buildSrcClassLoaderScope);
// 1. attaches root project
buildLoader.load(gradle.getSettings(), gradle);
// Makes included build substitutions available
if (gradle.isRootBuild()) {
buildStateRegistry.beforeConfigureRootBuild();
}
// 2. Build buildSrc and export classpath to root project
buildBuildSrcAndLockClassloader(gradle, buildSrcClassLoaderScope);
// 3. buildFile的编译与加载
delegate.prepareProjects(gradle);
// Make root build substitutions available
if (gradle.isRootBuild()) {
buildStateRegistry.afterConfigureRootBuild();
}
}
4. 流程1-init-project
流程1就是代码
buildLoader.load(gradle.getSettings(), gradle);
的内部实现;buildLoader对象的创建其实也是通过调用BuildScopeServices.createBuildLoader方法来实现的
调用链路非常清晰(装饰器模式)
先看NotifyingBuildLoader
4.1 NotifyingBuildLoader.load干啥了?
先看代码吧
@Override
public void load(final SettingsInternal settings, final GradleInternal gradle) {
final String buildPath = gradle.getIdentityPath().toString();
buildOperationExecutor.call(new CallableBuildOperation<Void>() {
@Override
publ