Android Gradle学习(七)- gradle任务执行过程

118 阅读14分钟

上一篇Android Gradle学习(六)- gradle插件源码解析讲解了gradle插件如何创建的Task,本篇继续探讨gradle Task的执行过程。还是以com.android.tools.build:gradle:4.1.3gradle-api-6.8.jar为例

学前思考

  1. ./gradlew assembleDebug命令,编译器帮我们做了什么?
  2. Task的顺序是如何构成的?
  3. Task是如何执行的?

1. gradlew文件

项目根目录下有gradlew文件,./linux执行该文件的命令,assembleDebug是入参。

DEFAULT_JVM_OPTS=""  
  
APP_NAME="Gradle"  
# gradlew
APP_BASE_NAME=`basename "$0"`

# 设置gradle-wrapper.jar路径
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# 获取JAVA_HOME的路径
if [ -n "$JAVA_HOME" ] ; then  
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then   
        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

# 执行Java命令,比如java -Xmx64m -Dorg.gradle.appname=gradlew -classpath $APP_HOME/gradle/wrapper/gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain 'assembleRelease'
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

之后一句命令,调用了gradle-wrapper.jar,还可以看到主入口org.gradle.wrapper.GradleWrapperMain

2. gradle wrapper

gradle wrapper是对gradle的包装器,封装了gradle的调用,好处有两点

  • 横向:统一不同开发者编译当前项目的gradle版本
  • 纵向:gradle版本升级时,不需要关心api变动

image.png

上一步调用到了org.gradle.wrapper.GradleWrapperMain

public class GradleWrapperMain {  
    public static final String GRADLE_USER_HOME_OPTION = "g";  
    public static final String GRADLE_USER_HOME_DETAILED_OPTION = "gradle-user-home";  
    public static final String GRADLE_QUIET_OPTION = "q";  
    public static final String GRADLE_QUIET_DETAILED_OPTION = "quiet";  

    public GradleWrapperMain() {  
    }  

    // args是传入的`assembleDebug`
    public static void main(String[] args) throws Exception {  
        // 找到gradle-wrapper.jar
        File wrapperJar = wrapperJar();  
        // 找到gradle-wrapper.properties
        File propertiesFile = wrapperProperties(wrapperJar);  
        File rootDir = rootDir(wrapperJar);  
        CommandLineParser parser = new CommandLineParser();  
        parser.allowUnknownOptions();  
        parser.option(new String[]{"g", "gradle-user-home"}).hasArgument();  
        parser.option(new String[]{"q", "quiet"});  
        SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();  
        converter.configure(parser);  
        ParsedCommandLine options = parser.parse(args);  
        Properties systemProperties = System.getProperties();  
        systemProperties.putAll(converter.convert(options, new HashMap()));  
        File gradleUserHome = gradleUserHome(options);  
        addSystemProperties(gradleUserHome, rootDir);  
        Logger logger = logger(options);  
        // 读取gradle/wrapper/gradle-wrapper.properties
        WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile, logger);  
        wrapperExecutor.execute(args, new Install(logger, new Download(logger, "gradlew", wrapperVersion()), new PathAssembler(gradleUserHome)), new BootstrapMainStarter());  
    }
}

private static void addSystemProperties(File gradleHome, File rootDir) {  
    // 全局的gradle.properties
    System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(gradleHome, "gradle.properties")));  
    // 当前项目的gradle.properties
    System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(rootDir, "gradle.properties")));  
}

main方法主要做了三件事:

  1. 加载gradle-wrapper.jargradle-wrapper.properties
  2. 加载并配置gradle.properties
  3. 启动gradle编译流程

继续跟进WrapperExecutor

public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {  
    // gradle-wrapper.properties里面配置的gradle下载地址,判断是否已经下载过,没有则下载
    File gradleHome = install.createDist(config);  
    // 引导启动器启动gradle编译
    bootstrapMainStarter.start(args, gradleHome);  
}

BootstrapMainStarter:引导启动器

public void start(String[] args, File gradleHome) throws Exception {  
    File gradleJar = findLauncherJar(gradleHome);  
    if (gradleJar == null) {  
        throw new RuntimeException(String.format("Could not locate the Gradle launcher JAR in Gradle distribution '%s'.", gradleHome));  
    }  
    URLClassLoader contextClassLoader = new URLClassLoader(new URL[]{gradleJar.toURI().toURL()}, ClassLoader.getSystemClassLoader().getParent());  
    Thread.currentThread().setContextClassLoader(contextClassLoader);  
    Class<?> mainClass = contextClassLoader.loadClass("org.gradle.launcher.GradleMain");  
    Method mainMethod = mainClass.getMethod("main", String[].class);  
    mainMethod.invoke(null, new Object[]{args});  
    if (contextClassLoader instanceof Closeable) {  
        ((Closeable) contextClassLoader).close();  
    }  
}

可以看到使用反射调用了org.gradle.launcher.GradleMainmain方法,args是传入的"assembleDebug"字符串。至此gradle wrapper的任务就完成了

3. gradle-api-6.8.jar

3.1 GradleMain

public class GradleMain {  
    public static void main(String[] args) {  
        try {  
            // 判断jdk版本,此处最低需要Java1.8
            UnsupportedJavaRuntimeException.assertUsingVersion("Gradle", JavaVersion.VERSION_1_8);  
        } catch (UnsupportedJavaRuntimeException ex) {  
            System.err.println(ex.getMessage());  
            System.exit(1);  
        }  
        // args是传入的"assembleDebug"
        new ProcessBootstrap().run("org.gradle.launcher.Main", args);  
    }  
}

GradleMaingradle编译的主入口,第一步检查jdk版本,第二步使用ProcessBootstrap启动主程序

ProcessBootStrap

public class ProcessBootstrap {  
    /**  
    * Sets up the ClassLoader structure for the given class, creates an instance and invokes {@link EntryPoint#run(String[])} on it.  
    */  
    public void run(String mainClassName, String[] args) {  
        try {  
            runNoExit(mainClassName, args);  
            System.exit(0);  
        } catch (Throwable throwable) {  
            throwable.printStackTrace();  
            System.exit(1);  
        }  
    }  
  
    private void runNoExit(String mainClassName, String[] args) throws Exception {  
        // ...

        try {  
            // 反射调用"org.gradle.launcher.Main"的"run"
            Class<?> mainClass = runtimeClassLoader.loadClass(mainClassName);  
            Object entryPoint = mainClass.getConstructor().newInstance();  
            Method mainMethod = mainClass.getMethod("run", String[].class);  
            mainMethod.invoke(entryPoint, new Object[]{args});  
        } finally {  
            // ...
        }  
    }  
}

可以看到通过反射调用org.gradle.launcher.Main.run("assembleDebug")

3.2 Main

Main.java

public class Main extends EntryPoint {  
    public static void main(String[] args) {  
        new Main().run(args);  
    }  

    @Override  
    protected void doAction(String[] args, ExecutionListener listener) {  
        createActionFactory().convert(Arrays.asList(args)).execute(listener);  
    }  

    CommandLineActionFactory createActionFactory() {  
        return new DefaultCommandLineActionFactory();  
    }  
}

此处执行了DefaultCommandLineActionFactory.WithLogging.execute()

@Override  
public void execute(ExecutionListener executionListener) {  
    // ...
    try {  
        解析args
        ParsedCommandLine parsedCommandLine = parser.parse(args);  
        InitialProperties initialProperties = propertiesConverter.convert(parsedCommandLine);  

        // Calculate build layout, for loading properties and other logging configuration  
        buildLayout = buildLayoutConverter.convert(initialProperties, parsedCommandLine, null);  

        // 读取 *.properties 文件  
        AllProperties properties = layoutToPropertiesConverter.convert(initialProperties, buildLayout);  

        // Calculate the logging configuration  
        loggingBuildOptions.convert(parsedCommandLine, properties, loggingConfiguration);  
    } catch (CommandLineArgumentException e) {  
        // Ignore, deal with this problem later  
    }  

    LoggingManagerInternal loggingManager = loggingServices.getFactory(LoggingManagerInternal.class).create();  
    loggingManager.setLevelInternal(loggingConfiguration.getLogLevel());  
    loggingManager.start();  
    try {  
        Action<ExecutionListener> exceptionReportingAction =  
            new ExceptionReportingAction(reporter, loggingManager,  
                new NativeServicesInitializingAction(buildLayout, loggingConfiguration, loggingManager,  
                    new WelcomeMessageAction(buildLayout,  
                        new DebugLoggerWarningAction(loggingConfiguration, action))));  
        exceptionReportingAction.execute(executionListener);  
    } finally {  
        loggingManager.stop();  
    }  
}

layoutToPropertiesConverter.convert读取*.properties文件

public AllProperties convert(InitialProperties initialProperties, BuildLayoutResult layout) {  
    BuildLayoutParameters layoutParameters = new BuildLayoutParameters();  
    layout.applyTo(layoutParameters);  
    Map<String, String> properties = new HashMap<>();  
    // 加载用户目录/.gradle/gradle.properties的属性
    configureFromHomeDir(layoutParameters.getGradleInstallationHomeDir(), properties);  
    // 加载项目根目录/gradle.properties的属性
    configureFromBuildDir(layoutParameters.getSearchDir(), layoutParameters.getSearchUpwards(), properties);  
    configureFromHomeDir(layout.getGradleUserHomeDir(), properties);  
    configureFromSystemPropertiesOfThisJvm(Cast.uncheckedNonnullCast(properties));  
    properties.putAll(initialProperties.getRequestedSystemProperties());  
    return new Result(properties, initialProperties);  
}

此时回到DefaultCommandLineActionFactory execute(),后续依次调用了

  1. ExceptionReportingAction
  2. NativeServicesInitializingAction
  3. WelcomeMessageAction
  4. DebugLoggerWarningAction

最后一个Action执行完成之后,会执行WithLogging构造体传入的action,可以回到Main 查看DefaultCommandLineActionFactory convert方法

@Override  
public CommandLineExecution convert(List<String> args) {  
    ServiceRegistry loggingServices = createLoggingServices();  

    LoggingConfiguration loggingConfiguration = new DefaultLoggingConfiguration();  

    return new WithLogging(loggingServices,  
        args,  
        loggingConfiguration,  
        new ParseAndBuildAction(loggingServices, args),  
        new BuildExceptionReporter(loggingServices.get(StyledTextOutputFactory.class), loggingConfiguration, clientMetaData()));  
}

actionParseAndBuildAction,后续执行execute方法

@Override  
public void execute(ExecutionListener executionListener) {  
    // ...
    Action<? super ExecutionListener> action;  
    try {  
        ParsedCommandLine commandLine = parser.parse(args); 
        // 创建构建action
        action = createAction(actions, parser, commandLine);  
    } catch (CommandLineArgumentException e) {  
        action = new CommandLineParseFailureAction(parser, e);  
    }  

    action.execute(executionListener);  
}

private Action<? super ExecutionListener> createAction(Iterable<CommandLineAction> factories, CommandLineParser parser, ParsedCommandLine commandLine) {  
    for (CommandLineAction factory : factories) {  
        Runnable action = factory.createAction(parser, commandLine);  
        if (action != null) {  
            return Actions.toAction(action);  
        }  
    }  
    throw new UnsupportedOperationException("No action factory for specified command-line arguments.");  
}

可以看到调用createAction(),此处调用了BuildActionsFactory createAction()

@Override  
public Runnable createAction(CommandLineParser parser, ParsedCommandLine commandLine) { 
    // 创建assembleDebug任务
    Parameters parameters = parametersConverter.convert(commandLine, null);  

    // ...
    if (parameters.getDaemonParameters().isEnabled()) {  
        return runBuildWithDaemon(parameters.getStartParameter(), parameters.getDaemonParameters());  
    }  
    if (canUseCurrentProcess(parameters.getDaemonParameters())) {  
        return runBuildInProcess(parameters.getStartParameter(), parameters.getDaemonParameters());  
    }  

    return runBuildInSingleUseDaemon(parameters.getStartParameter(), parameters.getDaemonParameters());  
}

parametersConverter.convert跟进

// org.gradle.launcher.cli.ParametersConverter#convert
public Parameters convert(ParsedCommandLine args, @Nullable File currentDir) throws CommandLineArgumentException {  
    InitialProperties initialProperties = initialPropertiesConverter.convert(args);  
    BuildLayoutResult buildLayout = buildLayoutConverter.convert(initialProperties, args, currentDir);  
    AllProperties properties = layoutToPropertiesConverter.convert(initialProperties, buildLayout);  

    StartParameterInternal startParameter = new StartParameterInternal();  
    // 
    startParameterConverter.convert(args, buildLayout, properties, startParameter);  

    DaemonParameters daemonParameters = new DaemonParameters(buildLayout, fileCollectionFactory, properties.getRequestedSystemProperties());  
    daemonParametersConverter.convert(args, properties, daemonParameters);  

    return new Parameters(buildLayout, startParameter, daemonParameters);  
}

// org.gradle.launcher.cli.converter.StartParameterConverter#convert
public StartParameterInternal convert(ParsedCommandLine parsedCommandLine, BuildLayoutResult buildLayout, AllProperties properties, StartParameterInternal startParameter) throws CommandLineArgumentException {  
    // ...
    if (!parsedCommandLine.getExtraArguments().isEmpty()) {  
        // 任务名称设置为assembleDebug
        startParameter.setTaskNames(parsedCommandLine.getExtraArguments());  
    }  

    buildOptionsConverter.convert(parsedCommandLine, properties, startParameter);  

    return startParameter;  
}

回溯一级,看到createAction()调用了runBuildInProcess()

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();  

    // 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));  
}

private Runnable runBuildAndCloseServices(StartParameterInternal startParameter, DaemonParameters daemonParameters, BuildActionExecuter<BuildActionParameters, BuildRequestContext> executer, ServiceRegistry sharedServices, Object... stopBeforeSharedServices) {  
BuildActionParameters parameters = createBuildActionParameters(startParameter, daemonParameters);  
    Stoppable stoppable = new CompositeStoppable().add(stopBeforeSharedServices).add(sharedServices);  
    return new RunBuildAction(executer, startParameter, clientMetaData(), getBuildStartTime(), parameters, sharedServices, stoppable);  
}

此时返回了RunBuildAction,后续调用其run方法

@Override  
public void run() {  
    try {  
        BuildActionResult result = executer.execute(  
            new ExecuteBuildAction(startParameter),  
            buildActionParameters,  
            new DefaultBuildRequestContext(new DefaultBuildRequestMetaData(clientMetaData, startTime, sharedServices.get(ConsoleDetector.class).isConsoleInput()), new DefaultBuildCancellationToken(), new NoOpBuildEventConsumer())  
        );  
        if (result.hasFailure()) {  
            // Don't need to unpack the serialized failure. It will already have been reported and is not used by anything downstream of this action.  
            throw new ReportedException();  
        }  
    } finally {  
        if (stoppable != null) {  
            stoppable.stop();  
        }  
    }  
}

这个executer是哪里来的?回溯下是globalServices.get(BuildExecuter.class),上面的BuildActionsFactory#runBuildInProcess()创建的。

3.3 GlobalScopeServices

GlobalScopeServices.java

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

org.gradle.internal.service.DefaultServiceLocator#getAll

@Override  
public <T> List<T> getAll(Class<T> serviceType) throws UnknownServiceException {  
    List<ServiceFactory<T>> factories = findFactoriesForServiceType(serviceType);  
    ArrayList<T> services = new ArrayList<T>();  
    for (ServiceFactory<T> factory : factories) {  
        services.add(factory.create());  
    }  
    return services;  
}

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

public <T> List<Class<? extends T>> implementationsOf(Class<T> 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 <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;  
}

可以看到resourceName= "META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry",去源码目录找到

image.png

找到LauncherServices.java

3.4 LauncherServices

public class LauncherServices extends AbstractPluginServiceRegistry {  
    @Override  
    public void registerGlobalServices(ServiceRegistration registration) {  
        registration.addProvider(new ToolingGlobalScopeServices());  
    }
}

此时注册了LauncherServices的服务,那么globalServices.get(BuildExecuter.class)就是去找executer

// org.gradle.launcher.cli.BuildActionsFactory#runBuildInProcess
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();  

    // 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));  
}

// org.gradle.internal.service.ServiceRegistryBuilder#build
public ServiceRegistry build() {  
    DefaultServiceRegistry registry = new DefaultServiceRegistry(displayName, parents.toArray(new ServiceRegistry[0]));  
    for (Object provider : providers) {  
        registry.addProvider(provider);  
    }  
    return registry;  
}

此处是DefaultServiceRegistry.get(BuildExecuter.class)

// org.gradle.internal.service.DefaultServiceRegistry#get(java.lang.Class<T>)
@Override  
public <T> T get(Class<T> serviceType) throws UnknownServiceException, ServiceLookupException {  
    return serviceType.cast(get((Type) serviceType));  
}

@Override  
public Object get(Type serviceType) throws UnknownServiceException, ServiceLookupException {  
    Object instance = find(serviceType);  
    if (instance == null) {  
        throw new UnknownServiceException(serviceType, String.format("No service of type %s available in %s.", format(serviceType), getDisplayName()));  
    }  
    return instance;  
}

@Override  
public Object find(Type serviceType) throws ServiceLookupException {  
    assertValidServiceType(unwrap(serviceType));  
    Service provider = getService(serviceType);  
    return provider == null ? null : provider.get();  
}

private Service getService(Type serviceType) {  
    serviceRequested();  
    return find(serviceType, allServices);  
}

private static Service find(Type serviceType, ServiceProvider serviceProvider) {  
    if (serviceType instanceof ParameterizedType) {  
        ParameterizedType parameterizedType = (ParameterizedType) serviceType;  
        Type rawType = parameterizedType.getRawType();  
        if (rawType.equals(Factory.class)) {  
            final Type typeArg = parameterizedType.getActualTypeArguments()[0];  
            return getFactoryService(typeArg, serviceProvider);  
        }  
        if (rawType instanceof Class) {  
            if (((Class<?>) rawType).isAssignableFrom(List.class)) {  
                Type typeArg = parameterizedType.getActualTypeArguments()[0];  
                return getCollectionService(typeArg, serviceProvider);  
            }  
            assertValidServiceType((Class<?>) rawType);  
            return serviceProvider.getService(serviceType);  
        }  
    }  
    if (serviceType instanceof Class<?>) {  
        assertValidServiceType((Class<?>) serviceType);  
        return serviceProvider.getService(serviceType);  
    }  

    throw new ServiceValidationException(String.format("Locating services with type %s is not supported.", format(serviceType)));  
}

看到是通过反射来匹配方法的返回值

找到LauncherServices.java,注册了ToolingGlobalScopeServices,里面createBuildExecuter返回值就是BuildExecuter类型

public class LauncherServices extends AbstractPluginServiceRegistry {  
    @Override  
    public void registerGlobalServices(ServiceRegistration registration) {  
        registration.addProvider(new ToolingGlobalScopeServices());  
    }
    
    static class ToolingGlobalScopeServices {  
        BuildExecuter createBuildExecuter(StyledTextOutputFactory styledTextOutputFactory, 
                LoggingManagerInternal loggingManager,  
                GradleUserHomeScopeServiceRegistry userHomeServiceRegistry,  
                ServiceRegistry globalServices) {  
            // @formatter:off  
            return  
                new SetupLoggingActionExecuter(loggingManager,  
                new SessionFailureReportingActionExecuter(styledTextOutputFactory, Time.clock(),  
                // 校验settings.gradle等文件是否存在
                new StartParamsValidatingActionExecuter(  
                new GradleThreadBuildActionExecuter(  
                new SessionScopeLifecycleBuildActionExecuter(userHomeServiceRegistry, globalServices  
            )))));  
            // @formatter:on  
        }  

        FileSystemChangeWaiterFactory createFileSystemChangeWaiterFactory(FileWatcherFactory fileWatcherFactory) {  
            return new DefaultFileSystemChangeWaiterFactory(fileWatcherFactory);  
        }  

        ExecuteBuildActionRunner createExecuteBuildActionRunner() {  
            return new ExecuteBuildActionRunner();  
        }  

        ClassLoaderCache createClassLoaderCache() {  
            return new ClassLoaderCache();  
        }  
    }
}

createBuildExecuter 也是一个链式调用 SessionScopeLifecycleBuildActionExecuter.execute()

@Override  
public BuildActionResult execute(BuildAction action, BuildActionParameters actionParameters, BuildRequestContext requestContext) {  
    StartParameter startParameter = action.getStartParameter();  
    try (CrossBuildSessionState crossBuildSessionState = new CrossBuildSessionState(globalServices, startParameter)) {  
        try (BuildSessionState buildSessionState = new BuildSessionState(userHomeServiceRegistry, crossBuildSessionState, startParameter, requestContext, actionParameters.getInjectedPluginClasspath(), requestContext.getCancellationToken(), requestContext.getClient(), requestContext.getEventConsumer())) {  
            return buildSessionState.run(context -> {  
                SessionLifecycleListener sessionLifecycleListener = context.getServices().get(ListenerManager.class).getBroadcaster(SessionLifecycleListener.class);  
                try {  
                    sessionLifecycleListener.afterStart();  
                    return context.getServices().get(SessionScopeBuildActionExecutor.class).execute(action, actionParameters, context);  
                } finally {  
                    sessionLifecycleListener.beforeComplete();  
                }  
            });  
        }  
    }  
}

调用了context.getServices().get(SessionScopeBuildActionExecutor.class)SessionScopeBuildActionExecutor的服务是在LauncherServices.java注册的

static class ToolingBuildSessionScopeServices {  
    SessionScopeBuildActionExecutor createActionExecutor(BuildEventListenerFactory listenerFactory,  
        ExecutorFactory executorFactory,  
        ListenerManager listenerManager,  
        BuildOperationListenerManager buildOperationListenerManager,  
        TaskInputsListeners inputsListeners,  
        StyledTextOutputFactory styledTextOutputFactory,  
        FileSystemChangeWaiterFactory fileSystemChangeWaiterFactory,  
        BuildRequestMetaData requestMetaData,  
        BuildCancellationToken cancellationToken,  
        DeploymentRegistryInternal deploymentRegistry,  
        BuildEventConsumer eventConsumer,  
        BuildStartedTime buildStartedTime,  
        Clock clock  
        ) {  
            return new SubscribableBuildActionExecuter(listenerManager, buildOperationListenerManager, listenerFactory, eventConsumer,  
                new ContinuousBuildActionExecuter(fileSystemChangeWaiterFactory, inputsListeners, styledTextOutputFactory, executorFactory, requestMetaData, cancellationToken, deploymentRegistry, listenerManager, buildStartedTime, clock,  
                    new BuildTreeScopeLifecycleBuildActionExecuter()));  
    }  
}

BuildTreeScopeLifecycleBuildActionExecuter#execute()

@Override  
public BuildActionResult execute(BuildAction action, BuildActionParameters actionParameters, BuildSessionContext buildSession) {  
    BuildType buildType = action.isRunTasks() ? BuildType.TASKS : BuildType.MODEL;  
    try (BuildTreeState buildTree = new BuildTreeState(buildSession.getServices(), buildType)) {  
        return buildTree.run(context ->  
            context.getBuildTreeServices().get(BuildTreeBuildActionExecutor.class).execute(action, actionParameters, context));  
    }  
}

BuildTreeBuildActionExecutor#execute()

static class ToolingBuildTreeScopeServices {  
    BuildTreeBuildActionExecutor createActionExecuter(List<BuildActionRunner> buildActionRunners,  
        StyledTextOutputFactory styledTextOutputFactory,  
        BuildStateRegistry buildStateRegistry,  
        PayloadSerializer payloadSerializer,  
        BuildOperationNotificationValve buildOperationNotificationValve,  
        BuildCancellationToken buildCancellationToken  
    ) {  
        return new InProcessBuildActionExecuter(buildStateRegistry, payloadSerializer, buildOperationNotificationValve, buildCancellationToken,  
            new RunAsBuildOperationBuildActionRunner(  
                new BuildCompletionNotifyingBuildActionRunner(  
                    new FileSystemWatchingBuildActionRunner(  
                        new ValidatingBuildActionRunner(  
                            new BuildOutcomeReportingBuildActionRunner(styledTextOutputFactory,  
                                new ChainingBuildActionRunner(buildActionRunners)))))));  
    }  
}

InProcessBuildActionExecuter&execute()

@Override  
public BuildActionResult execute(BuildAction action, BuildActionParameters actionParameters, BuildTreeContext buildTree) {  
    buildOperationNotificationValve.start();  
    try {  
        RootBuildState rootBuild = buildStateRegistry.createRootBuild(BuildDefinition.fromStartParameter(action.getStartParameter(), null));  
        return rootBuild.run(buildController -> {  
            BuildActionRunner.Result result = buildActionRunner.run(action, buildController);  
            if (result.getBuildFailure() == null) {  
                return BuildActionResult.of(payloadSerializer.serialize(result.getClientResult()));  
            }  
            if (buildCancellationToken.isCancellationRequested()) {  
                return BuildActionResult.cancelled(payloadSerializer.serialize(result.getBuildFailure()));  
            }  
            return BuildActionResult.failed(payloadSerializer.serialize(result.getClientFailure()));  
        });  
    } finally {  
        buildOperationNotificationValve.stop();  
    }  
}

buildStateRegistry.createRootBuild()buildStateRegistryDefaultIncludedBuildRegistry

@Override  
public RootBuildState createRootBuild(BuildDefinition buildDefinition) {  
    if (rootBuild != null) {  
        throw new IllegalStateException("Root build already defined.");  
    }  
    rootBuild = new DefaultRootBuildState(buildDefinition, gradleLauncherFactory, listenerManager, owner);  
    addBuild(rootBuild);  
    return rootBuild;  
}

DefaultRootBuildState.java

DefaultRootBuildState(BuildDefinition buildDefinition, GradleLauncherFactory gradleLauncherFactory, ListenerManager listenerManager, BuildTreeState owner) {  
    this.listenerManager = listenerManager;  
    this.gradleLauncher = gradleLauncherFactory.newInstance(buildDefinition, this, owner);  
}

DefaultGradleLauncherFactory#newInstance

public GradleLauncher newInstance(BuildDefinition buildDefinition, RootBuildState build, BuildTreeState owner) {  
    // This should only be used for top-level builds  
    if (rootBuild != null) {  
        throw new IllegalStateException("Cannot have a current root build");  
    }  

    GradleLauncher launcher = doNewInstance(buildDefinition, build, null, owner, ImmutableList.of((Stoppable) () -> rootBuild = null));  
    rootBuild = launcher;  

    final DefaultDeploymentRegistry deploymentRegistry = owner.getServices().get(DefaultDeploymentRegistry.class);  
    launcher.getGradle().addBuildListener(new InternalBuildAdapter() {  
        @Override  
        public void buildFinished(BuildResult result) {  
            deploymentRegistry.buildFinished(result);  
        }  
    });  

    return launcher;  
}

private GradleLauncher doNewInstance(  
    BuildDefinition buildDefinition,  
    BuildState owner,  
    @Nullable GradleLauncher parent,  
    BuildTreeState buildTree,  
    List<?> servicesToStop  
    ) {  
    return doNewInstance(  
        buildDefinition,  
        owner,  
        parent,  
        buildTree,  
        servicesToStop,  
        this::createDefaultGradleLauncher,  
        BuildScopeServices::new  
    );  
}

最终调用createDefaultGradleLauncher,创建DefaultGradleLauncher

private GradleLauncher createDefaultGradleLauncher(  
        GradleInternal gradle,  
        BuildScopeServices serviceRegistry,  
        List<?> servicesToStop  
    ) {  

    IncludedBuildControllers includedBuildControllers = gradle.getServices().get(IncludedBuildControllers.class);  
    ProjectsPreparer projectsPreparer = serviceRegistry.get(ProjectsPreparer.class);  
    SettingsPreparer settingsPreparer = serviceRegistry.get(SettingsPreparer.class);  
    TaskExecutionPreparer taskExecutionPreparer = gradle.getServices().get(TaskExecutionPreparer.class);  
    final ListenerManager listenerManager = serviceRegistry.get(ListenerManager.class);  

    return new DefaultGradleLauncher(  
        gradle,  
        projectsPreparer,  
        serviceRegistry.get(ExceptionAnalyser.class),  
        gradle.getBuildListenerBroadcaster(),  
        listenerManager.getBroadcaster(BuildCompletionListener.class),  
        listenerManager.getBroadcaster(InternalBuildFinishedListener.class),  
        gradle.getServices().get(BuildWorkExecutor.class),  
        serviceRegistry,  
        servicesToStop,  
        includedBuildControllers,  
        settingsPreparer,  
        taskExecutionPreparer,  
        gradle.getServices().get(ConfigurationCache.class),  
        new BuildOptionBuildOperationProgressEventsEmitter(  
            gradle.getServices().get(BuildOperationProgressEventEmitter.class)  
        )  
    );  
}

里面获取的服务基本都是在BuildScopeServices里面

3.5 DefaultGradleLauncher

生命周期

public class DefaultGradleLauncher implements GradleLauncher {  
    private enum Stage {  
        LoadSettings, Configure, TaskGraph, RunTasks() {  
            @Override  
            String getDisplayName() {  
                return "Build";  
            }  
        }, Finished;  

        String getDisplayName() {  
            return name();  
        }  
    }
      
}
  1. LoadSettings: 加载
  2. Configure: 配置
  3. TaskGraph: 生成Task执行图
  4. RunTasks: 执行Task
  5. Finished: 完成
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();  
}

3.5.1 LoadSettings阶段

加载setting配置

private void prepareSettings() {  
    if (stage == null) {  
        buildListener.buildStarted(gradle);  

        settingsPreparer.prepareSettings(gradle);  

        stage = Stage.LoadSettings;  
    }  
}

settingsPreparerserviceRegistry.get(SettingsPreparer.class),找到BuildScopeServices#createSettingsPreparer()

protected SettingsPreparer createSettingsPreparer(InitScriptHandler initScriptHandler, SettingsLoaderFactory settingsLoaderFactory, BuildOperationExecutor buildOperationExecutor, BuildDefinition buildDefinition) {  
    return new BuildOperationFiringSettingsPreparer(  
        new DefaultSettingsPreparer(  
            initScriptHandler,  
            settingsLoaderFactory  
        ),  
        buildOperationExecutor,  
        buildDefinition.getFromBuild());  
}

DefaultSettingsPreparer#prepareSettings

public void prepareSettings(GradleInternal gradle) {  
    // Evaluate init scripts  
    initScriptHandler.executeScripts(gradle);  
    // Build `buildSrc`, load settings.gradle, and construct composite (if appropriate)  
    SettingsLoader settingsLoader = gradle.isRootBuild() ? settingsLoaderFactory.forTopLevelBuild() : settingsLoaderFactory.forNestedBuild();  
    settingsLoader.findAndLoadSettings(gradle);  
}
@Override  
public SettingsLoader forTopLevelBuild() {  
    return new CompositeBuildSettingsLoader(  
        new ChildBuildRegisteringSettingsLoader(  
            new CommandLineIncludedBuildSettingsLoader(  
                defaultSettingsLoader()  
            ),  
            buildRegistry,  
            publicBuildPath,  
            instantiator  
            ),  
        buildRegistry);  
}  
  
@Override  
public SettingsLoader forNestedBuild() {  
    return new ChildBuildRegisteringSettingsLoader(  
        defaultSettingsLoader(),  
        buildRegistry,  
        publicBuildPath,  
        instantiator  
    );  
}  
  
private SettingsLoader defaultSettingsLoader() {  
    return new SettingsAttachingSettingsLoader(  
        new DefaultSettingsLoader(  
            settingsProcessor,  
            buildLayoutFactory,  
            gradlePropertiesController  
        ),  
        projectRegistry  
    );  
}

DefaultSettingsLoader加载rootgradle.propertiessettings,ChildBuildRegisteringSettingsLoader遍历子module

创建project对象

// DefaultGradleLauncher
// projectsPreparer是DefaultGradleLauncherFactory创建DefaultGradleLauncher时传入的
private void prepareProjects() {  
    if (stage == Stage.LoadSettings) {  
        projectsPreparer.prepareProjects(gradle);  
        stage = Stage.Configure;  
    }  
}

// DefaultGradleLauncherFactory
private GradleLauncher createDefaultGradleLauncher() {
    ProjectsPreparer projectsPreparer = serviceRegistry.get(ProjectsPreparer.class);
}

// BuildScopeServices
// 入参BuildLoader由服务创建
ProjectsPreparer createBuildConfigurer(..,BuildLoader buildLoader) {
    return new BuildOperationFiringProjectsPreparer(  
        new BuildTreePreparingProjectsPreparer(  
            new DefaultProjectsPreparer(  
                projectConfigurer,  
                modelConfigurationListener,  
                buildOperationExecutor),  
            buildLoader,  
            buildStateRegistry,  
            buildSourceBuilder),  
        buildOperationExecutor);
}

// BuildScopeServices
protected BuildLoader createBuildLoader(GradleProperties gradleProperties, IProjectFactory projectFactory, BuildOperationExecutor buildOperationExecutor) {  
    return new NotifyingBuildLoader(  
        new ProjectPropertySettingBuildLoader(  
            gradleProperties,  
            new InstantiatingBuildLoader(  
                projectFactory  
            )  
        ),  
        buildOperationExecutor  
    );  
}

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

private void createProjects(GradleInternal gradle, ProjectDescriptor rootProjectDescriptor) {  
    ClassLoaderScope baseProjectClassLoaderScope = gradle.baseProjectClassLoaderScope();  
    ClassLoaderScope rootProjectClassLoaderScope = baseProjectClassLoaderScope.createChild("root-project");  

    ProjectInternal rootProject = projectFactory.createProject(gradle, rootProjectDescriptor, null, rootProjectClassLoaderScope, baseProjectClassLoaderScope);  
    gradle.setRootProject(rootProject);  

    createChildProjectsRecursively(gradle, rootProject, rootProjectDescriptor, rootProjectClassLoaderScope, baseProjectClassLoaderScope);  
}

// ProjectFactory
public ProjectInternal createProject(GradleInternal gradle, ProjectDescriptor projectDescriptor, @Nullable ProjectInternal parent, ClassLoaderScope selfClassLoaderScope, ClassLoaderScope baseClassLoaderScope) {  
    Path projectPath = ((DefaultProjectDescriptor) projectDescriptor).path();  
    ProjectState projectContainer = projectStateRegistry.stateFor(owner.getBuildIdentifier(), projectPath);  

    File buildFile = projectDescriptor.getBuildFile();  
    TextResource resource = textFileResourceLoader.loadFile("build file", buildFile);  
    ScriptSource source = new TextResourceScriptSource(resource);  
    DefaultProject project = instantiator.newInstance(DefaultProject.class,  
        projectDescriptor.getName(),  
        parent,  
        projectDescriptor.getProjectDir(),  
        buildFile,  
        source,  
        gradle,  
        projectContainer,  
        gradle.getServiceRegistryFactory(),  
        selfClassLoaderScope,  
        baseClassLoaderScope  
    );  
    project.beforeEvaluate(p -> {  
        NameValidator.validate(project.getName(), "project name", DefaultProjectDescriptor.INVALID_NAME_IN_INCLUDE_HINT);  
        gradle.getServices().get(DependencyResolutionManagementInternal.class).configureProject(project);  
    });  

    if (parent != null) {  
        parent.addChildProject(project);  
    }  
    projectRegistry.addProject(project);  
    projectContainer.attachMutableModel(project);  
    return project;  
}

至此加载阶段结束。主要加载了setting配置文件和创建Project对象。

3.5.2 Configure阶段

// DefaultGradleLauncher
private void prepareTaskExecution() {  
    if (stage == Stage.Configure) {  
        taskExecutionPreparer.prepareForTaskExecution(gradle);  

        stage = Stage.TaskGraph;  
    }  
}

// GradleScopeServices
TaskExecutionPreparer createTaskExecutionPreparer(BuildConfigurationActionExecuter buildConfigurationActionExecuter, IncludedBuildControllers includedBuildControllers, BuildOperationExecutor buildOperationExecutor) {  
    return new BuildOperationFiringTaskExecutionPreparer(  
        new DefaultTaskExecutionPreparer(buildConfigurationActionExecuter, includedBuildControllers, buildOperationExecutor),  
            buildOperationExecutor);  
}

// DefaultTaskExecutionPreparer#prepareProjects
@Override  
public void prepareProjects(GradleInternal gradle) {  
    if (gradle.getStartParameter().isConfigureOnDemand()) {  
        IncubationLogger.incubatingFeatureUsed("Configuration on demand");  
        projectConfigurer.configure(gradle.getRootProject());  
    } else {  
        projectConfigurer.configureHierarchy(gradle.getRootProject());  
        new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);  
    }  

    modelConfigurationListener.onConfigure(gradle);  
}

// projectConfigurer来自
protected ProjectConfigurer createProjectConfigurer(BuildCancellationToken cancellationToken) {  
    return new TaskPathProjectEvaluator(cancellationToken);  
}

// TaskPathProjectEvaluator#configure
@Override  
public void configure(ProjectInternal project) {  
    if (cancellationToken.isCancellationRequested()) {  
        throw new BuildCancelledException();  
    }  
    // Need to configure intermediate parent projects for configure-on-demand  
    ProjectInternal parentProject = project.getParent();  
    if (parentProject != null) {  
        configure(parentProject);  
    }  
    project.evaluate();  
}

// DefaultProject#evaluate
public DefaultProject evaluate() {  
    // projectEvaluator = services.get(ProjectEvaluator.class);
    getProjectEvaluator().evaluate(this, state);  
    return this;  
}

// BuildScopeServices#createProjectEvaluator
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
public void evaluate(final ProjectInternal project, final ProjectStateInternal state) {  
    if (state.isUnconfigured()) {  
        buildOperationExecutor.run(new EvaluateProject(project, state));  
    }  
}

// EvaluateProject#run
public void run(final BuildOperationContext context) {  
    project.getMutationState().applyToMutableState(p -> {  
        // Note: beforeEvaluate and afterEvaluate ops do not throw, instead mark state as failed  
        try {  
            state.toBeforeEvaluate();  
            buildOperationExecutor.run(new NotifyBeforeEvaluate(project, state));  

            if (!state.hasFailure()) {  
                state.toEvaluate();  
                try {  
                    delegate.evaluate(project, state);  
                } catch (Exception e) {  
                    addConfigurationFailure(project, state, e, context);  
                } finally {  
                    state.toAfterEvaluate();  
                    buildOperationExecutor.run(new NotifyAfterEvaluate(project, state));  
                }  
            }  

            if (state.hasFailure()) {  
                state.rethrowFailure();  
            } else {  
                context.setResult(ConfigureProjectBuildOperationType.RESULT);  
            }  
        } finally {  
            state.configured();  
        }  
    });  
}

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

ConfigureActionsProjectEvaluator构造体传入了一些action

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);  
}

PluginsProjectConfigureActions#from

public static ProjectConfigureAction from(ServiceLocator serviceLocator) {  
    return of(ProjectConfigureAction.class, serviceLocator);  
}  
  
public static <T extends Action<ProjectInternal>> ProjectConfigureAction of(Class<T> serviceType,  
ServiceLocator serviceLocator) {  
    return new PluginsProjectConfigureActions(  
        ImmutableList.<Action<ProjectInternal>>copyOf(  
        serviceLocator.getAll(serviceType)));  
}

serviceLocator拷贝一些实现了ProjectConfigureAction接口的action MATE-INF/services/org.gradle.configuration.project.ProjectConfigureAction看到一些服务

org.gradle.api.plugins.internal.HelpTasksAutoApplyAction  
org.gradle.jvm.toolchain.internal.task.ShowToolchainsTaskConfigurator  
org.gradle.buildinit.plugins.internal.action.BuildInitAutoApplyAction  
org.gradle.buildinit.plugins.internal.action.WrapperPluginAutoApplyAction

BuildInitAutoApplyAction为例

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

可以找到在META-INF/gralde-plugins/org.gradle.build-init.properties

implementation-class=org.gradle.buildinit.plugins.BuildInitPlugin
public class BuildInitPlugin implements Plugin<Project> {  
  
    @Override  
    public void apply(Project project) {  
        if (project.getParent() == null) {  
            project.getTasks().register("init", InitBuild.class, initBuild -> {
            // ...
        }
    }
}

这里就很熟悉了,使用了插件的方式读取init配置,有兴趣的可以看看源码

此时再回到BuildScriptProcessor#execute

public void execute(final ProjectInternal project) {  
    // ...
    try {  
        final ScriptPlugin configurer = configurerFactory.create(project.getBuildScriptSource(), project.getBuildscript(), project.getClassLoaderScope(), project.getBaseClassLoaderScope(), true);  
        project.getMutationState().applyToMutableState(configurer::apply);  
    } finally {  
        // ...
    }  
}

此处是解析build.gradle文件

3.5.3 TaskGraph阶段

//DefaultGradleLauncher#prepareTaskExecution
private void prepareTaskExecution() {  
    if (stage == Stage.Configure) {  
        taskExecutionPreparer.prepareForTaskExecution(gradle);  

        stage = Stage.TaskGraph;  
    }  
}

taskExecutionPreparerTaskExecutionPreparer taskExecutionPreparer = gradle.getServices().get(TaskExecutionPreparer.class);

// GradleScopeServices#createTaskExecutionPreparer
TaskExecutionPreparer createTaskExecutionPreparer(BuildConfigurationActionExecuter buildConfigurationActionExecuter, IncludedBuildControllers includedBuildControllers, BuildOperationExecutor buildOperationExecutor) {  
    return new BuildOperationFiringTaskExecutionPreparer(  
        new DefaultTaskExecutionPreparer(buildConfigurationActionExecuter, includedBuildControllers, buildOperationExecutor),  
        buildOperationExecutor);  
}

// DefaultTaskExecutionPreparer#prepareForTaskExecution
public void prepareForTaskExecution(GradleInternal gradle) {  
    buildConfigurationActionExecuter.select(gradle);  

    TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();  
    taskGraph.populate();  

    includedBuildControllers.populateTaskGraphs();  

    if (gradle.getStartParameter().isConfigureOnDemand()) {  
        new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);  
    }  
}

//  buildConfigurationActionExecuter.select BuildConfigurationActionExecuter获取
BuildConfigurationActionExecuter createBuildConfigurationActionExecuter(CommandLineTaskParser commandLineTaskParser, TaskSelector taskSelector, ProjectConfigurer projectConfigurer, ProjectStateRegistry projectStateRegistry) {  
    List<BuildConfigurationAction> taskSelectionActions = new LinkedList<BuildConfigurationAction>();  
    taskSelectionActions.add(new DefaultTasksBuildExecutionAction(projectConfigurer));  
    taskSelectionActions.add(new TaskNameResolvingBuildConfigurationAction(commandLineTaskParser));  
    return new DefaultBuildConfigurationActionExecuter(Arrays.asList(new ExcludedTaskFilteringBuildConfigurationAction(taskSelector)), taskSelectionActions, projectStateRegistry);  
}

// ExcludedTaskFilteringBuildConfigurationAction排除某些Task
public void configure(BuildExecutionContext context) {  
    GradleInternal gradle = context.getGradle();  
    Set<String> excludedTaskNames = gradle.getStartParameter().getExcludedTaskNames();  
    if (!excludedTaskNames.isEmpty()) {  
        final Set<Spec<Task>> filters = new HashSet<Spec<Task>>();  
        for (String taskName : excludedTaskNames) {  
            filters.add(taskSelector.getFilter(taskName));  
        }  
        gradle.getTaskGraph().useFilter(Specs.intersect(filters));  
    }  

    context.proceed();  
}

// DefaultTasksBuildExecutionAction构建默认的Task
public void configure(BuildExecutionContext context) {  
    StartParameter startParameter = context.getGradle().getStartParameter();  

    for (TaskExecutionRequest request : startParameter.getTaskRequests()) {  
        if (!request.getArgs().isEmpty()) {  
            context.proceed();  
            return;  
        }  
    }  

    // Gather the default tasks from this first group project  
    ProjectInternal project = context.getGradle().getDefaultProject();  

    //so that we don't miss out default tasks  
    projectConfigurer.configure(project);  

    List<String> defaultTasks = project.getDefaultTasks();  
    if (defaultTasks.size() == 0) {  
        defaultTasks = Collections.singletonList(ProjectInternal.HELP_TASK);  
        LOGGER.info("No tasks specified. Using default task {}", GUtil.toString(defaultTasks));  
    } else {  
        LOGGER.info("No tasks specified. Using project default tasks {}", GUtil.toString(defaultTasks));  
    }  

    startParameter.setTaskNames(defaultTasks);  
    context.proceed();  
}

// TaskNameResolvingBuildConfigurationAction#configure 生成任务执行图
public void configure(BuildExecutionContext context) {  
    GradleInternal gradle = context.getGradle();  
    TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();  

    List<TaskExecutionRequest> taskParameters = gradle.getStartParameter().getTaskRequests();  
    for (TaskExecutionRequest taskParameter : taskParameters) {  
        List<TaskSelection> taskSelections = commandLineTaskParser.parseTasks(taskParameter);  
        for (TaskSelection taskSelection : taskSelections) {  
            LOGGER.info("Selected primary task '{}' from project {}", taskSelection.getTaskName(), taskSelection.getProjectPath());  
            taskGraph.addEntryTasks(taskSelection.getTasks());  
        }  
    }  

    context.proceed();  
}

// DefaultTaskExecutionGraph#addEntryTasks
public void addEntryTasks(Iterable<? extends Task> tasks) {  
    assert tasks != null;  

    final Timer clock = Time.startTimer();  

    Set<Task> taskSet = new LinkedHashSet<>();  
    for (Task task : tasks) {  
        taskSet.add(task);  
        requestedTasks.add(task);  
    }  

    executionPlan.addEntryTasks(taskSet);  
    graphState = GraphState.DIRTY;  

    LOGGER.debug("Timing: Creating the DAG took " + clock.getElapsed());  
}

// DefaultExecutionPlan#addEntryTasks
public void addEntryTasks(Collection<? extends Task> tasks) {  
    final Deque<Node> queue = new ArrayDeque<>();  

    for (Task task : sorted(tasks)) {  
        TaskNode node = taskNodeFactory.getOrCreateNode(task);  
        if (node.isMustNotRun()) {  
            requireWithDependencies(node);  
        } else if (filter.isSatisfiedBy(task)) {  
            node.require();  
        }  
        entryNodes.add(node);  
        queue.add(node);  
    }  

    doAddNodes(queue);  
}

此时Task都创建好了,并且都加入到了executionPlan,此时再回到DefaultTaskExecutionPreparer#prepareForTaskExecution

public void prepareForTaskExecution(GradleInternal gradle) {  
    buildConfigurationActionExecuter.select(gradle);  

    TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();  
    taskGraph.populate();  

    includedBuildControllers.populateTaskGraphs();  

    if (gradle.getStartParameter().isConfigureOnDemand()) {  
        new ProjectsEvaluatedNotifier(buildOperationExecutor).notify(gradle);  
    }  
}

taskGraph.populate()最终调用到DefaultExecutionPlan#determineExecutionPlan构建任务执行图

小结:

  1. DefaultGradleLauncher#prepareTaskExecution构建Task开始
  2. DefaultTaskExecutionPreparer#prepareForTaskExecution构建执行
  3. ExcludedTaskFilteringBuildConfigurationAction排除某些Task
  4. DefaultTasksBuildExecutionAction创建默认Task
  5. TaskNameResolvingBuildConfigurationAction把创建好的Task存储到DefaultExecutionPlan
  6. DefaultTaskExecutionPreparer#prepareForTaskExecution -> taskGraph.populate() -> DefaultExecutionPlan#determineExecutionPlan构建Task执行图

3.5.4 RunTasks阶段

// DefaultGradleLauncher#runWork
private void runWork() {  
    List<Throwable> taskFailures = new ArrayList<>();  
    buildExecuter.execute(gradle, taskFailures);  
    stage = Stage.RunTasks;  
}

// buildExecuter = gradle.getServices().get(BuildWorkExecutor.class)
// GradleScopeServices#createBuildExecuter
BuildWorkExecutor createBuildExecuter(StyledTextOutputFactory textOutputFactory, IncludedBuildControllers includedBuildControllers, BuildOperationExecutor buildOperationExecutor) {  
    return new BuildOperationFiringBuildWorkerExecutor(  
        new DeprecateUndefinedBuildWorkExecutor(  
            new IncludedBuildLifecycleBuildWorkExecutor(  
                new DefaultBuildWorkExecutor(  
                    asList(new DryRunBuildExecutionAction(textOutputFactory),  
                        new SelectedTaskExecutionAction())),  
                includedBuildControllers)),  
        buildOperationExecutor);  
}

// SelectedTaskExecutionAction#execute
public void execute(BuildExecutionContext context, Collection<? super Throwable> taskFailures) {  
    GradleInternal gradle = context.getGradle();  
    TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();  
    if (gradle.getStartParameter().isContinueOnFailure()) {  
        taskGraph.setContinueOnFailure(true);  
    }  

    bindAllReferencesOfProject(taskGraph);  
    taskGraph.execute(taskFailures);  
}

//DefaultTaskExecutionGraph#execute -> executeWithServices
private void executeWithServices(ProjectExecutionServiceRegistry projectExecutionServices, Collection<? super Throwable> failures) {  
    Timer clock = Time.startTimer();  
    try {  
        planExecutor.process(  
            executionPlan,  
            failures,  
            new BuildOperationAwareExecutionAction(  
                buildOperationExecutor.getCurrentOperation(),  
                new InvokeNodeExecutorsAction(nodeExecutors, projectExecutionServices)  
            )  
        );  
        LOGGER.debug("Timing: Executing the DAG took " + clock.getElapsed());  
    } finally {  
        coordinationService.withStateLock(resourceLockState -> {  
        executionPlan.clear();  
        return ResourceLockState.Disposition.FINISHED;  
    });  
    }  
}

// DefaultPlanExecutor#process
public void process(ExecutionPlan executionPlan, Collection<? super Throwable> failures, Action<Node> nodeExecutor) {  
    ManagedExecutor executor = executorFactory.create("Execution worker for '" + executionPlan.getDisplayName() + "'");  
    try {  
        WorkerLease parentWorkerLease = workerLeaseService.getCurrentWorkerLease();  
        startAdditionalWorkers(executionPlan, nodeExecutor, executor, parentWorkerLease);  
        new ExecutorWorker(executionPlan, nodeExecutor, parentWorkerLease, cancellationToken, coordinationService).run();  
        awaitCompletion(executionPlan, failures);  
    } finally {  
        executor.stop();  
    }  
}

// DefaultPlanExecutor.ExecutorWorker#run
public void run() {  
    final AtomicLong busy = new AtomicLong(0);  
    Timer totalTimer = Time.startTimer();  
    final Timer executionTimer = Time.startTimer();  

    WorkerLease childLease = parentWorkerLease.createChild();  
    while (true) {  
        boolean nodesRemaining = executeNextNode(childLease, work -> {  
            LOGGER.info("{} ({}) started.", work, Thread.currentThread());  
            executionTimer.reset();  
            nodeExecutor.execute(work);  
            long duration = executionTimer.getElapsedMillis();  
            busy.addAndGet(duration);  
            if (LOGGER.isInfoEnabled()) {  
                LOGGER.info("{} ({}) completed. Took {}.", work, Thread.currentThread(), TimeFormatting.formatDurationVerbose(duration));  
            }  
        });  
        if (!nodesRemaining) {  
            break;  
        }  
    }  

    long total = totalTimer.getElapsedMillis();  

    if (LOGGER.isDebugEnabled()) {  
        LOGGER.debug("Execution worker [{}] finished, busy: {}, idle: {}", Thread.currentThread(), TimeFormatting.formatDurationVerbose(busy.get()), TimeFormatting.formatDurationVerbose(total - busy.get()));  
    }  
}

nodeExecutor创建

// ProjectExecutionServices#createTaskExecuter
TaskExecuter createTaskExecuter(...) {
    TaskExecuter executer = new ExecuteActionsTaskExecuter(  
        buildCacheController.isEnabled()  
            ? ExecuteActionsTaskExecuter.BuildCacheState.ENABLED  
            : ExecuteActionsTaskExecuter.BuildCacheState.DISABLED,  
        gradleEnterprisePluginManager.isPresent()  
            ? ExecuteActionsTaskExecuter.ScanPluginState.APPLIED  
            : ExecuteActionsTaskExecuter.ScanPluginState.NOT_APPLIED,  
        executionHistoryStore,  
        buildOperationExecutor,  
        asyncWorkTracker,  
        actionListener,  
        taskCacheabilityResolver,  
        fingerprinterRegistry,  
        classLoaderHierarchyHasher,  
        executionEngine,  
        listenerManager,  
        reservedFileSystemLocationRegistry,  
        emptySourceTaskSkipper,  
        fileCollectionFactory,  
        fileOperations  
    );  
    executer = new CleanupStaleOutputsExecuter(  
        buildOperationExecutor,  
        cleanupRegistry,  
        deleter,  
        outputChangeListener,  
        outputFilesRepository,  
        executer  
    );  
    executer = new FinalizePropertiesTaskExecuter(executer);  
    executer = new ResolveTaskExecutionModeExecuter(repository, fileCollectionFactory, propertyWalker, executer);  
    executer = new SkipTaskWithNoActionsExecuter(taskExecutionGraph, executer);  
    executer = new SkipOnlyIfTaskExecuter(executer);  
    executer = new CatchExceptionTaskExecuter(executer);  
    executer = new EventFiringTaskExecuter(buildOperationExecutor, taskExecutionListener, taskListenerInternal, executer);  
    return executer;
}
  • EventFiringTaskExecuter: 通知任务开始事件
  • CatchExceptionTaskExecuter: 加上try-catch异常捕获
  • SkipOnlyIfTaskExecuter: 判断Task执行条件是否满足
  • SkipTaskWithNoActionsExecuter: 跳过没有actionTask
  • ResolveTaskExecutionModeExecuter: 解析Task的信息
  • FinalizePropertiesTaskExecuter: 通知任务开始和结束
  • CleanupStaleOutputsExecuter: 任务执行前清除之前输出的产物
  • ExecuteActionsTaskExecuter: 真正执行Task
// EventFiringTaskExecuter#execute
public TaskExecuterResult execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {  
    TaskExecution work = new TaskExecution(task, context, executionHistoryStore, fingerprinterRegistry, classLoaderHierarchyHasher);  
    try {  
        return executeIfValid(task, state, context, work);  
    } catch (WorkValidationException ex) {  
        state.setOutcome(ex);  
        return TaskExecuterResult.WITHOUT_OUTPUTS;  
    }  
}

// TaskExecution#execute
@Override  
public WorkOutput execute(@Nullable InputChangesInternal inputChanges, InputChangesContext context) {
    FileCollection previousFiles = context.getAfterPreviousExecutionState()  
        .map(afterPreviousExecutionState -> (FileCollection) new PreviousOutputFileCollection(task, afterPreviousExecutionState))  
        .orElseGet(fileCollectionFactory::empty);  
    TaskOutputsInternal outputs = task.getOutputs();  
    outputs.setPreviousOutputFiles(previousFiles);  
    try {  
        WorkResult didWork = executeWithPreviousOutputFiles(inputChanges);  
        return new WorkOutput() {  
            @Override  
            public WorkResult getDidWork() {  
                return didWork;  
            }  

            @Override  
            public Object getOutput() {  
                throw new UnsupportedOperationException();  
            }  
        };  
    } finally {  
        outputs.setPreviousOutputFiles(null);  
    }  
}

private WorkResult executeWithPreviousOutputFiles(@Nullable InputChangesInternal inputChanges) {  
    task.getState().setExecuting(true);  
    try {  
        LOGGER.debug("Executing actions for {}.", task);  
        actionListener.beforeActions(task);  
        executeActions(task, inputChanges);  
        return task.getState().getDidWork() ? WorkResult.DID_WORK : WorkResult.DID_NO_WORK;  
    } finally {  
        task.getState().setExecuting(false);  
        actionListener.afterActions(task);  
    }  
}

private void executeActions(TaskInternal task, @Nullable InputChangesInternal inputChanges) {  
    boolean hasTaskListener = listenerManager.hasListeners(TaskActionListener.class) || listenerManager.hasListeners(TaskExecutionListener.class);  
    Iterator<InputChangesAwareTaskAction> actions = new ArrayList<>(task.getTaskActions()).iterator();  
    while (actions.hasNext()) {  
        InputChangesAwareTaskAction action = actions.next();  
        task.getState().setDidWork(true);  
        task.getStandardOutputCapture().start();  
        boolean hasMoreWork = hasTaskListener || actions.hasNext();  
        try {  
            executeAction(action.getDisplayName(), task, action, inputChanges, hasMoreWork);  
        } catch (StopActionException e) {  
            // Ignore  
            LOGGER.debug("Action stopped by some action with message: {}", e.getMessage());  
        } catch (StopExecutionException e) {  
            LOGGER.info("Execution stopped by some action with message: {}", e.getMessage());  
            break;  
        } finally {  
            task.getStandardOutputCapture().stop();  
        }  
    }  
}

private void executeAction(String actionDisplayName, TaskInternal task, InputChangesAwareTaskAction action, @Nullable InputChangesInternal inputChanges, boolean hasMoreWork) {  
    if (inputChanges != null) {  
        action.setInputChanges(inputChanges);  
    }  
    buildOperationExecutor.run(new RunnableBuildOperation() {  
        // ...
    }

    @Override  
    public void run(BuildOperationContext context) {  
        try {  
            BuildOperationRef currentOperation = buildOperationExecutor.getCurrentOperation();  
            Throwable actionFailure = null;  
            try {  
                action.execute(task);  
            } catch (Throwable t) {  
                actionFailure = t;  
            } finally {  
                action.clearInputChanges();  
            }  
        }
        // ...
     }
}

此处开始执行Task

3.5.5 Finished阶段

DefaultGradleLauncher#finishBuild

private void finishBuild(String action, @Nullable Throwable stageFailure) {  
    if (stage == Stage.Finished) {  
        return;  
    }  

    RuntimeException reportableFailure = stageFailure == null ? null : exceptionAnalyser.transform(stageFailure);  
    BuildResult buildResult = new BuildResult(action, gradle, reportableFailure);  
    List<Throwable> failures = new ArrayList<>();  
    includedBuildControllers.finishBuild(failures);  
    try {  
        buildListener.buildFinished(buildResult);  
        buildFinishedListener.buildFinished((GradleInternal) buildResult.getGradle());  
    } catch (Throwable t) {  
        failures.add(t);  
    }  
    stage = Stage.Finished;  

    if (failures.isEmpty() && reportableFailure != null) {  
        throw reportableFailure;  
    }  
    if (!failures.isEmpty()) {  
        if (stageFailure instanceof MultipleBuildFailures) {  
            failures.addAll(0, ((MultipleBuildFailures) stageFailure).getCauses());  
        } else if (stageFailure != null) {  
            failures.add(0, stageFailure);  
        }  
        throw exceptionAnalyser.transform(new MultipleBuildFailures(failures));  
    }  
}

这里就是生命周期回调

至此,任务的创建到执行过程基本跟踪完成了,主要以下几个步骤

  1. 解析setting.gradle文件,并生成Project实例对象
  2. 解析build.gradle并执行
  3. 创建并生成Task执行图
  4. 执行Task

4. 总结

虽然中间逻辑很复杂,面向接口的编程,通过接口类型反射匹配从众多service中找到对应的调用方法,代码跟进难度大,但是好在最终还是慢慢摸清了套路。虽然过程不一定完全正确,但是大致的脉络应该没差。至此,开篇的几个问题终归有了解答。

4.1 学到的东西

4.1.1 面向接口,一些对象的获取,通过service提供

例如:ProjectsPreparer projectsPreparer = serviceRegistry.get(ProjectsPreparer.class)

通过解析ProjectsPreparer.class的类型,从注册的服务树依次匹配,服务BuildScopeServices获取,

protected ProjectsPreparer createBuildConfigurer() {
    // ...
}

4.1.2 装饰模式

protected ProjectsPreparer createBuildConfigurer(ProjectConfigurer projectConfigurer, BuildSourceBuilder buildSourceBuilder, BuildStateRegistry buildStateRegistry, BuildLoader buildLoader, ListenerManager listenerManager, BuildOperationExecutor buildOperationExecutor) {  
    ModelConfigurationListener modelConfigurationListener = listenerManager.getBroadcaster(ModelConfigurationListener.class);  
    return new BuildOperationFiringProjectsPreparer(  
                new BuildTreePreparingProjectsPreparer(  
                    new DefaultProjectsPreparer(  
                        projectConfigurer,  
                        modelConfigurationListener,  
                        buildOperationExecutor),  
                    buildLoader,  
                    buildStateRegistry,  
                    buildSourceBuilder),  
                buildOperationExecutor);  
}

以这个为例,都是实现了ProjectsPreparer接口,然后构造体传入其他的ProjectsPreparer,为其增加不同的功能

4.1.3 外观模式

gradle wrapper封装了不同gradle版本的调用细节,对外提供统一的调用接口,而无需关注gradle的版本变化。

参考:

Gradle构建过程的源码分析

【Android 修炼手册】Gradle 篇 -- Gradle 源码分析