Gradle 源码分析(一)

1. 写在前面

在执行gradle命令的时候,你是否想过它是如何运作的。接下来几篇文章将从入口开始逐步分析 gradle 的启动,构建流程。(gradle 源码版本为 5.6.4)。

2. 启动流程

2.1 整体实现

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

2.1.1 时序图

启动流程时序图.png

2.1.2 主要操作

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

  1. 下载 gradle wrapper 需要的依赖以及gradle源码;
  2. 创建 DefaultServiceRegistry,并注册GlobalScopeServices;
  3. 反射调用 GlobalScopeServices 的 configure(),注册 META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry 下声明的 PluginServicesRegistry;
  4. 注册 CrossBuildSessionScopeServices;
  5. 注册 BuildTreeScopeServices;
  6. 创建 DefaultGradleLauncher,调用 executeTasks()进入构建阶段;

2.2 源码分析

回想一下,如果需要构建 apk 文件,是不是可以执行 ./gradlew :app:assembleRelease 命令。而这里调用的就是 gradlew 这个脚本文件。gradlew 文件只用关心最后一行,前面大部分都是环境,参数等的判断;

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

这里的 JAVACMDCLASSPATH 是什么?这个时候再带着疑问向前看。

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

可以看到这里的 CLASSPATH 就是工程目录下的 gradle/wrapper/gradle-wrapper.jar;而 JAVACMD$JAVA_HOME/bin/javaJAVA_HOME 即环境变量配置的 JAVA_HOME

这么一来 gradlew 最后一行的命令大致上是这样子的。

exec /Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/bin/java  -classpath projectDir/gradle/wrapper/gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain

其实就是执行 gradle-wrapper.jar 里面的 GradleWrapperMainmain(),这就是入口函数了。

2.2.1 下载 Gradle 文件

先来看看 GradleWrapperMainmain()

// GradleWrapperMain.java
public static void main(String[] args) throws Exception {
    // /gradle/wrapper/gradle-wrapper.jar
    File wrapperJar = wrapperJar();
    // /gradle/wrapper/gradle-wrapper.properties
    File propertiesFile = wrapperProperties(wrapperJar);
    // root dir
    File rootDir = rootDir(wrapperJar);

    CommandLineParser parser = new CommandLineParser();
    parser.allowUnknownOptions();
    parser.option(GRADLE_USER_HOME_OPTION, GRADLE_USER_HOME_DETAILED_OPTION).hasArgument();
    parser.option(GRADLE_QUIET_OPTION, GRADLE_QUIET_DETAILED_OPTION);

    SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();
    converter.configure(parser);

    ParsedCommandLine options = parser.parse(args);

    Properties systemProperties = System.getProperties();
    systemProperties.putAll(converter.convert(options, new HashMap<String, String>()));

    // gradle user home,默认为 ~/.gradle
    File gradleUserHome = gradleUserHome(options);

    addSystemProperties(gradleUserHome, rootDir);

    Logger logger = logger(options);
    // 执行 WrapperExecutor.execute()
    WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile);
    wrapperExecutor.execute(
            args,
            new Install(logger, new Download(logger, "gradlew", UNKNOWN_VERSION), new PathAssembler(gradleUserHome)),
            new BootstrapMainStarter());
}

这里会调用 WrapperExecutorexecute()

// WrapperExecutor.java
public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {
    // 这里会下载 gradle 文件
    File gradleHome = install.createDist(config);
    // 走启动流程
    bootstrapMainStarter.start(args, gradleHome);
}

这里先调用 InstallcreateDist() 下载 gradle wrapper 需要的依赖以及源码文件。

// Install.java
public File createDist(final WrapperConfiguration configuration) throws Exception {
    // 下面会拿 gradle/wrapper/gradle-wrapper.properties 里面定义的一些参数
    final URI distributionUrl = configuration.getDistribution();
    final String distributionSha256Sum = configuration.getDistributionSha256Sum();

    final PathAssembler.LocalDistribution localDistribution = pathAssembler.getDistribution(configuration);
    final File distDir = localDistribution.getDistributionDir();
    final File localZipFile = localDistribution.getZipFile();

    return exclusiveFileAccessManager.access(localZipFile, new Callable<File>() {
        public File call() throws Exception {
            // 1. 先看本地有没有,如果有的话直接返回
            final File markerFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".ok");
            if (distDir.isDirectory() && markerFile.isFile()) {
                return getAndVerifyDistributionRoot(distDir, distDir.getAbsolutePath());
            }
            
            // 2. 如果需要下载,则进行下载
            boolean needsDownload = !localZipFile.isFile();
            URI safeDistributionUrl = Download.safeUri(distributionUrl);

            if (needsDownload) {
                File tmpZipFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".part");
                tmpZipFile.delete();
                logger.log("Downloading " + safeDistributionUrl);
                // 下载gralde源码
                download.download(distributionUrl, tmpZipFile);
                tmpZipFile.renameTo(localZipFile);
            }

            List<File> topLevelDirs = listDirs(distDir);
            for (File dir : topLevelDirs) {
                logger.log("Deleting directory " + dir.getAbsolutePath());
                deleteDir(dir);
            }

            verifyDownloadChecksum(configuration.getDistribution().toString(), localZipFile, distributionSha256Sum);

            try {
                // 3.解压文件
                unzip(localZipFile, distDir);
            } catch (IOException e) {
                logger.log("Could not unzip " + localZipFile.getAbsolutePath() + " to " + distDir.getAbsolutePath() + ".");
                logger.log("Reason: " + e.getMessage());
                throw e;
            }

            File root = getAndVerifyDistributionRoot(distDir, safeDistributionUrl.toString());
            setExecutablePermissions(root);
            markerFile.createNewFile();

            return root;
        }
    });
}

可以看到,这里会先查看 ~/.gradle/wrapper/dists/gradle-5.6.4-all/xxx/gradle.5.6.4-all.zip.ok 文件是否存在,如果存在则不需要进行下载;如果不存在则需要从 gradle-wrapper.properties 里面定义的 distributionUrl 进行下载。

2.2.2 创建 DefaultServiceRegistry

中间的调用链就不列出源码了,对分析没有太大帮助,感兴趣的可以根据时序图自己去查看源码。直接看 BuildActionsFactoryrunBuildInProcess()

// BuildActionsFactory.java
private Runnable runBuildInProcess(StartParameterInternal startParameter, DaemonParameters daemonParameters) {
    // 创建DefaultServiceRegistry
    ServiceRegistry globalServices = ServiceRegistryBuilder.builder()
            .displayName("Global services")
            .parent(loggingServices)
            .parent(NativeServices.getInstance())
            // 添加 GlobalScopeServices
            .provider(new GlobalScopeServices(startParameter.isContinuous()))
            .build();

    // Force the user home services to be stopped first, the dependencies between the user home services and the global services are not preserved currently
    return runBuildAndCloseServices(startParameter, daemonParameters, globalServices.get(BuildExecuter.class), globalServices, globalServices.get(GradleUserHomeScopeServiceRegistry.class));
}

来看看 ServiceRegistryBuilderbuild()

// ServiceRegistryBuilder.java
public ServiceRegistry build() {
    // 1. 创建 DefaultServiceRegistry
    DefaultServiceRegistry registry = new DefaultServiceRegistry(displayName, parents.toArray(new ServiceRegistry[0]));
    for (Object provider : providers) {
        // 2. 这里会把 GlobalScopeServices 添加进去
        registry.addProvider(provider);
    }
    return registry;
}

这里会创建 DefaultServiceRegistry 的对象,然后调用 addProvider() 添加 GlobalScopeServices,这两个地方是重点。来看看 DefaultServiceRegistry 的构造器和 addProvider() 做了什么。

// DefaultServiceRegistry.java
public DefaultServiceRegistry(String displayName, ServiceRegistry... parents) {
    // ... 省略一部分代码
    // 主要是这个方法
    findProviderMethods(this);
}

public DefaultServiceRegistry addProvider(Object provider) {
    // 也调用了这个方法
    findProviderMethods(provider);
}

发现构造器和 addProvider() 都调用了 findProviderMethods()

// DefaultServiceRegistry.java
private void findProviderMethods(Object target) {
    Class<?> type = target.getClass();
    // 这里会反射找相应的方法
    RelevantMethods methods = RelevantMethods.getMethods(type);
    // ...  省略部分代码
}

主要看 RelevantMethods.getMethods() 究竟查找了哪些方法。

// RelevantMethods.java
public static RelevantMethods getMethods(Class<?> type) {
    // 先看缓存里面有没有,如果有则直接返回
    RelevantMethods relevantMethods = METHODS_CACHE.get(type);
    if (relevantMethods == null) {
        // 如果缓存没有,则通过反射获取相关方法
        relevantMethods = buildRelevantMethods(type);
        METHODS_CACHE.putIfAbsent(type, relevantMethods);
    }
    return relevantMethods;
}

private static RelevantMethods buildRelevantMethods(Class<?> type) {
    RelevantMethodsBuilder builder = new RelevantMethodsBuilder(type);
    RelevantMethods relevantMethods;
    // 以下三行分别找到对应的方法
    addDecoratorMethods(builder);
    addFactoryMethods(builder);
    addConfigureMethods(builder);
    relevantMethods = builder.build();
    return relevantMethods;
}

// 这里会解析 configure()
private static void addConfigureMethods(RelevantMethodsBuilder builder) {
    Class<?> type = builder.type;
    Iterator<Method> iterator = builder.remainingMethods.iterator();
    while (iterator.hasNext()) {
        Method method = iterator.next();
        // 寻找返回值为void 的configure(),并添加到 configures 里面
        if (method.getName().equals("configure")) {
            if (!method.getReturnType().equals(Void.TYPE)) {
                throw new ServiceLookupException(String.format("Method %s.%s() must return void.", type.getSimpleName(), method.getName()));
            }
            builder.add(iterator, builder.configurers, method);
        }
    }
}

// 添加工厂方法
private static void addFactoryMethods(RelevantMethodsBuilder builder) {
    Class<?> type = builder.type;
    Iterator<Method> iterator = builder.remainingMethods.iterator();
    while (iterator.hasNext()) {
        Method method = iterator.next();
        // 非 static 的 createXXX() 方法
        if (method.getName().startsWith("create") && !Modifier.isStatic(method.getModifiers())) {
            if (method.getReturnType().equals(Void.TYPE)) {
                throw new ServiceLookupException(String.format("Method %s.%s() must not return void.", type.getSimpleName(), method.getName()));
            }
            // 添加到 factories 里面
            builder.add(iterator, builder.factories, method);
        }
    }
}

// 添加装饰方法
private static void addDecoratorMethods(RelevantMethodsBuilder builder) {
    Class<?> type = builder.type;
    Iterator<Method> iterator = builder.remainingMethods.iterator();
    while (iterator.hasNext()) {
        Method method = iterator.next();
        // 查找 createXXX() 或 decorateXXX(),传参和返回值一致的方法
        if (method.getName().startsWith("create") || method.getName().startsWith("decorate")) {
            if (method.getReturnType().equals(Void.TYPE)) {
                throw new ServiceLookupException(String.format("Method %s.%s() must not return void.", type.getSimpleName(), method.getName()));
            }
            if (takesReturnTypeAsParameter(method)) {
                // 添加到 decorators 里面
                builder.add(iterator, builder.decorators, method);
            }
        }
    }
}

可以看到,主要查找了三类方法:

  1. create 开头或者 decorate 开头,且入参与返回值类型一致的方法(装饰方法);
  2. create 开头又返回值且不是 static 的方法(工厂方法);
  3. configure 方法;

通过反射查找完对应的方法后,再回到 DefaultServiceRegistryfindProviderMethods()

// DefaultServiceRegistry.java
private void findProviderMethods(Object target) {
    Class<?> type = target.getClass();
    RelevantMethods methods = RelevantMethods.getMethods(type);
    // 这里会遍历上一步找到的方法
    for (ServiceMethod method : methods.decorators) {
        if (parentServices == null) {
            throw new ServiceLookupException(String.format("Cannot use decorator method %s.%s() when no parent registry is provided.", type.getSimpleName(), method.getName()));
        }
        // 包装成FactoryMethodService,供get(XXX.class)反射调用
        ownServices.add(new FactoryMethodService(this, target, method));
    }
    for (ServiceMethod method : methods.factories) {
        // 包装成FactoryMethodService,供get(XXX.class)反射调用
        ownServices.add(new FactoryMethodService(this, target, method));
    }
    // 如果是 configure() 会直接执行。
    for (ServiceMethod method : methods.configurers) {
        applyConfigureMethod(method, target);
    }
}

这里通过 RelevantMethodsgetMethods() 查找完方法后,会进行遍历,然后将装饰方法和工厂方法包装成 FactoryMethodService 对象,后续通过 get() 调用的时候实际上就是通过 FactoryMethodService 进行反射调用对应的装饰方法或工厂方法创建对象。

2.2.3 调用 configure(),注册 PluginServiceRegistry

有趣的点在于 GlobalScopeServices 在经历 findProviderMethods() 后会调用其 configure()

// GlobalScopeServices.java
void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) {
    final List<PluginServiceRegistry> pluginServiceFactories = new DefaultServiceLocator(classLoaderRegistry.getRuntimeClassLoader(), classLoaderRegistry.getPluginsClassLoader()).getAll(PluginServiceRegistry.class);
    // ...
}

这里 getAll(PluginServiceRegistry.class) 是在查找 PluginServiceRegistry

// DefaultServiceLocator.java
public <T> List<T> getAll(Class<T> serviceType) throws UnknownServiceException {
    List<ServiceFactory<T>> factories = findFactoriesForServiceType(serviceType);
    // ...
}

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

public <T> List<Class<? extends T>> implementationsOf(Class<T> serviceType) {
    // ...
    return findServiceImplementations(serviceType);
    // ...
}

// 主要是这个方法,它会查找 META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry这个文件,并加载里面声明的 PluginServiceRegistry
private <T> List<Class<? extends T>> findServiceImplementations(Class<T> serviceType) throws IOException {
    String resourceName = "META-INF/services/" + serviceType.getName();
    Set<String> implementationClassNames = new HashSet<String>();
    List<Class<? extends T>> implementations = new ArrayList<Class<? extends T>>();
    for (ClassLoader classLoader : classLoaders) {
        Enumeration<URL> resources = classLoader.getResources(resourceName);
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            List<String> 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;
}

根据调用链,可以看到最终会查找 META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry 这个文件,主要记住两个关键的 PluginServiceRegistry,分别是 org.gradle.composite.internal.CompositeBuildServicesorg.gradle.tooling.internal.provider.LauncherServices

PluginServiceRegistry.png

再回到 GlobalScopServicesconfigure(),查找完 PluginServiceRegistry 后,会调用其 registerGlobalServices 完成注册。

// GlobalScopeServices.java
void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) {
    final List<PluginServiceRegistry> pluginServiceFactories = new DefaultServiceLocator(classLoaderRegistry.getRuntimeClassLoader(), classLoaderRegistry.getPluginsClassLoader()).getAll(PluginServiceRegistry.class);
    // 调用 PluginServiceRegistry 的registerGlobalServices
    for (PluginServiceRegistry pluginServiceRegistry : pluginServiceFactories) {
        registration.add(PluginServiceRegistry.class, pluginServiceRegistry);
        pluginServiceRegistry.registerGlobalServices(registration);
    }
}

2.3.4 注册 CrossBuildSessionScopeServices

分析完上面的流程,思绪该回到 BuildActionsFactoryrunBuildInProcess()

private Runnable runBuildInProcess(StartParameterInternal startParameter, DaemonParameters daemonParameters) {
    ServiceRegistry globalServices = ServiceRegistryBuilder.builder()
            .displayName("Global services")
            .parent(loggingServices)
            .parent(NativeServices.getInstance())
            .provider(new GlobalScopeServices(startParameter.isContinuous()))
            .build();
    // 这里 globalServices.get(BuildExecuter.class) 就是通过前面存下来的FactoryMethodService 进行反射调用对应的工厂方法获取 BuildExecuter对象
    return runBuildAndCloseServices(startParameter, daemonParameters, globalServices.get(BuildExecuter.class), globalServices, globalServices.get(GradleUserHomeScopeServiceRegistry.class));
}

private Runnable runBuildAndCloseServices(StartParameterInternal startParameter, DaemonParameters daemonParameters, BuildActionExecuter<BuildActionParameters> executer, ServiceRegistry sharedServices, Object... stopBeforeSharedServices) {
    BuildActionParameters parameters = createBuildActionParameters(startParameter, daemonParameters);
    Stoppable stoppable = new CompositeStoppable().add(stopBeforeSharedServices).add(sharedServices);
    // 实际上创建的是 RunBuildAction 对象
    return new RunBuildAction(executer, startParameter, clientMetaData(), getBuildStartTime(), parameters, sharedServices, stoppable);
}

这里的 globalServices.get(GradleUserHomeScopeServiceRegistry.class) 就是通过前面 2.2.2 保存下来的 FactoryMethodService 反射调用对应的工厂方法,这里会调用到 LauncherServices 内部类 ToolingGlobalScopeServicescreateBuildExecuter()

//ToolingGlobalScopeServices.java
BuildExecuter createBuildExecuter(List<BuildActionRunner> buildActionRunners,
                                  List<SubscribableBuildActionRunnerRegistration> registrations,
                                  ListenerManager listenerManager,
                                  BuildOperationListenerManager buildOperationListenerManager,
                                  TaskInputsListener inputsListener,
                                  StyledTextOutputFactory styledTextOutputFactory,
                                  ExecutorFactory executorFactory,
                                  LoggingManagerInternal loggingManager,
                                  GradleUserHomeScopeServiceRegistry userHomeServiceRegistry,
                                  FileSystemChangeWaiterFactory fileSystemChangeWaiterFactory,
                                  ParallelismConfigurationManager parallelismConfigurationManager
) {
    return new SetupLoggingActionExecuter(
        new SessionFailureReportingActionExecuter(
            new StartParamsValidatingActionExecuter(
                new ParallelismConfigurationBuildActionExecuter(
                    new GradleThreadBuildActionExecuter(
                        new SessionScopeBuildActionExecuter(
                            new SubscribableBuildActionExecuter(
                                new ContinuousBuildActionExecuter(
                                    new BuildTreeScopeBuildActionExecuter(
                                        new InProcessBuildActionExecuter(
                                            new RunAsBuildOperationBuildActionRunner(
                                                new BuildCompletionNotifyingBuildActionRunner(
                                                    new ValidatingBuildActionRunner(
                                                        new BuildOutcomeReportingBuildActionRunner(
                                                            new ChainingBuildActionRunner(buildActionRunners),
                                                            styledTextOutputFactory)))))),
                                fileSystemChangeWaiterFactory,
                                inputsListener,
                                styledTextOutputFactory,
                                executorFactory),
                                    listenerManager,
                                    buildOperationListenerManager,
                                    registrations),
                            userHomeServiceRegistry)),
                    parallelismConfigurationManager)),
            styledTextOutputFactory,
            Time.clock()),
        loggingManager);
}

传给 RunBuildAction 的是 SetupLoggingActionExecuter 对象,接着会在 ParseAndBuildActionexecute() 中调用 RunBuildActionrun()

// RunBuildAction.java
public void run() {
        // ...
        // 实际上是调用了 executer 的 execute()
        BuildActionResult result = executer.execute(
                new ExecuteBuildAction(startParameter),
                new DefaultBuildRequestContext(new DefaultBuildRequestMetaData(clientMetaData, startTime, sharedServices.get(ConsoleDetector.class).isConsoleInput()), new DefaultBuildCancellationToken(), new NoOpBuildEventConsumer()),
                buildActionParameters,
                sharedServices);
        // ...
}

前面说了,这里的 executerSetupLoggingActionExecuter,紧接着又是一堆委托调用,感兴趣的可以跟着时序图向后看,就不一一列举了,这里直接看 SessionScopeBuildActionExecuterexecute()

public BuildActionResult execute(BuildAction action, BuildRequestContext requestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) {
    StartParameter startParameter = action.getStartParameter();
    final ServiceRegistry userHomeServices = userHomeServiceRegistry.getServicesFor(startParameter.getGradleUserHomeDir());
    // 创建 CrossBuildSessionScopeServices
    CrossBuildSessionScopeServices crossBuildSessionScopeServices = new CrossBuildSessionScopeServices(contextServices, startParameter);
    // 注册 CrossBuildSessionScopeServices
    ServiceRegistry buildSessionScopeServices = new BuildSessionScopeServices(
        userHomeServices,
        crossBuildSessionScopeServices,
        startParameter,
        requestContext,
        actionParameters.getInjectedPluginClasspath(),
        requestContext.getCancellationToken(),
        requestContext.getClient(),
        requestContext.getEventConsumer()
    );
    // 省略部分代码
}

这里就是注册 CrossBuildSessionScopeServices 了,它也会执行 2.2.2 分析的 findProviderMethods() 流程。

2.3.5 注册 BuildTreeScopeServices

SessionScopeBuildActionExecuterexecute() 之后会经过一系列的委托调用,走到 BuildTreeScopeBuildActionExecuterexecute()

// BuildTreeScopeBuildActionExecuter.java
public BuildActionResult execute(BuildAction action, BuildRequestContext requestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) {
    // ...
    BuildTreeScopeServices buildTreeScopeServices = new BuildTreeScopeServices(contextServices);
    // ...
}

execute() 里面会注册 BuildTreeScopeServices

2.3.6 创建 DefaultGradleLauncher,调用 executeTasks()进入构建阶段

经过 BuildTreeScopeServicesexecute() 后,再省略一系列的委托调用,到 InProcessBuildActionExecuterexecute()

public BuildActionResult execute(final BuildAction action, final BuildRequestContext buildRequestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) {
    // 这里就是反射获取的 CompositeBuildServices 的 createIncludedBuildRegistry()
    BuildStateRegistry buildRegistry = contextServices.get(BuildStateRegistry.class);
    // ...
    try {
        // 创建DefaultGradleLauncher。
        RootBuildState rootBuild = buildRegistry.createRootBuild(BuildDefinition.fromStartParameter(action.getStartParameter(), null));
        return rootBuild.run(new Transformer<BuildActionResult, BuildController>() {
            @Override
            public BuildActionResult transform(BuildController buildController) {
                BuildActionRunner.Result result = buildActionRunner.run(action, buildController);
                if (result.getBuildFailure() == null) {
                    return BuildActionResult.of(payloadSerializer.serialize(result.getClientResult()));
                }
                if (buildRequestContext.getCancellationToken().isCancellationRequested()) {
                    return BuildActionResult.cancelled(payloadSerializer.serialize(result.getBuildFailure()));
                }
                return BuildActionResult.failed(payloadSerializer.serialize(result.getClientFailure()));
            }
        });
    } finally {
        buildOperationNotificationValve.stop();
    }
}

这里首先会通过反射调用 CompositeBuildServices 内部类 CompositeBuildTreeScopeServicescreateIncludedBuildRegistry() 获取 BuildStateRegistry

// CompositeBuildServices.java
public BuildStateRegistry createIncludedBuildRegistry(CompositeBuildContext context, ProjectStateRegistry projectRegistry, Instantiator instantiator, WorkerLeaseService workerLeaseService, ImmutableModuleIdentifierFactory moduleIdentifierFactory, GradleLauncherFactory gradleLauncherFactory, ListenerManager listenerManager, ServiceRegistry rootServices) {
    IncludedBuildFactory includedBuildFactory = new DefaultIncludedBuildFactory(instantiator, workerLeaseService);
    IncludedBuildDependencySubstitutionsBuilder dependencySubstitutionsBuilder = new IncludedBuildDependencySubstitutionsBuilder(context, moduleIdentifierFactory);
    return new DefaultIncludedBuildRegistry(includedBuildFactory, projectRegistry, dependencySubstitutionsBuilder, gradleLauncherFactory, listenerManager, (BuildTreeScopeServices) rootServices);
}

返回的是 DefaultIncludedBuildRegistry 对象;紧接着调用了 DefaultIncludedBuildRegistrycreateRootBuild()

// DefaultIncludedBuildRegistry.java
public RootBuildState createRootBuild(BuildDefinition buildDefinition) {
    // ... 
    // 这里会创建 DefaultRootBuildState
    rootBuild = new DefaultRootBuildState(buildDefinition, gradleLauncherFactory, listenerManager, rootServices);
    // ... 
}

createRootBuild() 里面会创建 DefaultRootBuildState,而在 DefaultRootBuildState 的构造器里面会创建 GradleLauncher

// DefaultRootBuildState.java
DefaultRootBuildState(BuildDefinition buildDefinition, GradleLauncherFactory gradleLauncherFactory, ListenerManager listenerManager, BuildTreeScopeServices parentServices) {
    this.listenerManager = listenerManager;
    gradleLauncher = gradleLauncherFactory.newInstance(buildDefinition, this, parentServices);
}

这里调用 gradleLauncherFactorynewInstance() 创建 GradleLaunchergradleLauncherFactory 也是通过反射调用 CrossBuildSessionScopeServicescreateGradleLauncherFactory() 获取的。

// DefaultGradleLauncherFactory.java
public GradleLauncher newInstance(BuildDefinition buildDefinition, RootBuildState build, BuildTreeScopeServices parentRegistry) {
    // ... 
    // 调用 doNewInstance() 
    DefaultGradleLauncher launcher = doNewInstance(buildDefinition, build, null, parentRegistry, ImmutableList.of(new Stoppable() {
            @Override
            public void stop() {
                rootBuild = null;
            }
        }));
    rootBuild = launcher;
    // ...
    return launcher;
}

private DefaultGradleLauncher doNewInstance(BuildDefinition buildDefinition,
                                            BuildState build,
                                            @Nullable GradleLauncher parent,
                                            BuildTreeScopeServices buildTreeScopeServices,
                                            List<?> servicesToStop) {
    // ... 
    // 创建 DefaultGradleLauncher 对象
    DefaultGradleLauncher gradleLauncher = new DefaultGradleLauncher(
        gradle,
        serviceRegistry.get(ProjectsPreparer.class),
        serviceRegistry.get(ExceptionAnalyser.class),
        gradle.getBuildListenerBroadcaster(),
        listenerManager.getBroadcaster(BuildCompletionListener.class),
        gradle.getServices().get(BuildWorkExecutor.class),
        serviceRegistry,
        servicesToStop,
        includedBuildControllers,
        settingsPreparer,
        taskExecutionPreparer,
        gradle.getServices().get(InstantExecution.class)
    );
    // ...
    return gradleLauncher;
}

这部分就是创建 DefaultGradleLauncher 了;紧接着又是一系列的委托调用,最终会走到 ChainingBuildActionRunnerrun()

public Result run(BuildAction action, BuildController buildController) {
    for (BuildActionRunner runner : runners) {
        Result result = runner.run(action, buildController);
        if (result.hasResult()) {
            return result;
        }
    }
    return Result.nothing();
}

而这里只是简单的遍历传入的 runners,调用其 run();这里的 runners 是通过反射调用的 LaunchersServices 内部类 ToolingGlobalScopeServicescreateExecuteBuildActionRunner(),即 ExecuteBuildActionRunner 对象。

// LaunchersServices.java
ExecuteBuildActionRunner createExecuteBuildActionRunner() {
      return new ExecuteBuildActionRunner();
}

ExecuteBuildActionRunnerrun() 也只是调用 buildControllerrun()

// ExecuteBuildActionRunner.java
public Result run(BuildAction action, BuildController buildController) {
    // ...
    buildController.run();
}

buildController 是在 InProcessBuildActionExecuter 里面调用 DefaultRootBuildStaterun() 创建的 GradleBuildController 对象,那么来看它的 run()

public GradleInternal run() {
    return doBuild(GradleInternal.BuildType.TASKS, new Action<GradleLauncher>() {
        @Override
        public void execute(@Nonnull GradleLauncher gradleLauncher) {
            gradleLauncher.executeTasks();
        }
    });
}

这里最终会调用到 gradleLauncherexecuteTasks() 进入构建阶段;至此 gradle 的启动流程就分析完了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容