1. 寫(xiě)在前面
在執(zhí)行g(shù)radle命令的時(shí)候芜辕,你是否想過(guò)它是如何運(yùn)作的疾棵。接下來(lái)幾篇文章將從入口開(kāi)始逐步分析 gradle 的啟動(dòng)蕊苗,構(gòu)建流程栗精。(gradle 源碼版本為 5.6.4)。
2. 啟動(dòng)流程
2.1 整體實(shí)現(xiàn)
這里我整理了啟動(dòng)流程的一些主要操作彪蓬,并繪制了調(diào)用鏈的時(shí)序圖寸莫。如果對(duì)源碼不感興趣的同學(xué)只需要看這一部分的內(nèi)容即可。
2.1.1 時(shí)序圖
2.1.2 主要操作
啟動(dòng)階段 Gradle 主要做了下面這些事情档冬。
- 下載 gradle wrapper 需要的依賴以及gradle源碼膘茎;
- 創(chuàng)建 DefaultServiceRegistry,并注冊(cè)GlobalScopeServices酷誓;
- 反射調(diào)用 GlobalScopeServices 的 configure()披坏,注冊(cè) META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry 下聲明的 PluginServicesRegistry;
- 注冊(cè) CrossBuildSessionScopeServices盐数;
- 注冊(cè) BuildTreeScopeServices棒拂;
- 創(chuàng)建 DefaultGradleLauncher,調(diào)用 executeTasks()進(jìn)入構(gòu)建階段玫氢;
2.2 源碼分析
回想一下帚屉,如果需要構(gòu)建 apk 文件,是不是可以執(zhí)行 ./gradlew :app:assembleRelease 命令琐旁。而這里調(diào)用的就是 gradlew 這個(gè)腳本文件。gradlew 文件只用關(guān)心最后一行猜绣,前面大部分都是環(huán)境灰殴,參數(shù)等的判斷;
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
這里的 JAVACMD
和 CLASSPATH
是什么?這個(gè)時(shí)候再帶著疑問(wèn)向前看牺陶。
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/java
;JAVA_HOME
即環(huán)境變量配置的 JAVA_HOME
掰伸。
這么一來(lái) 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
其實(shí)就是執(zhí)行 gradle-wrapper.jar 里面的 GradleWrapperMain
的 main()
,這就是入口函數(shù)了狮鸭。
2.2.1 下載 Gradle 文件
先來(lái)看看 GradleWrapperMain
的 main()
合搅。
// 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,默認(rèn)為 ~/.gradle
File gradleUserHome = gradleUserHome(options);
addSystemProperties(gradleUserHome, rootDir);
Logger logger = logger(options);
// 執(zhí)行 WrapperExecutor.execute()
WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile);
wrapperExecutor.execute(
args,
new Install(logger, new Download(logger, "gradlew", UNKNOWN_VERSION), new PathAssembler(gradleUserHome)),
new BootstrapMainStarter());
}
這里會(huì)調(diào)用 WrapperExecutor
的 execute()
歧蕉。
// WrapperExecutor.java
public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {
// 這里會(huì)下載 gradle 文件
File gradleHome = install.createDist(config);
// 走啟動(dòng)流程
bootstrapMainStarter.start(args, gradleHome);
}
這里先調(diào)用 Install
的 createDist()
下載 gradle wrapper 需要的依賴以及源碼文件灾部。
// Install.java
public File createDist(final WrapperConfiguration configuration) throws Exception {
// 下面會(huì)拿 gradle/wrapper/gradle-wrapper.properties 里面定義的一些參數(shù)
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. 先看本地有沒(méi)有,如果有的話直接返回
final File markerFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".ok");
if (distDir.isDirectory() && markerFile.isFile()) {
return getAndVerifyDistributionRoot(distDir, distDir.getAbsolutePath());
}
// 2. 如果需要下載惯退,則進(jìn)行下載
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;
}
});
}
可以看到赌髓,這里會(huì)先查看 ~/.gradle/wrapper/dists/gradle-5.6.4-all/xxx/gradle.5.6.4-all.zip.ok 文件是否存在,如果存在則不需要進(jìn)行下載催跪;如果不存在則需要從 gradle-wrapper.properties 里面定義的 distributionUrl 進(jìn)行下載锁蠕。
2.2.2 創(chuàng)建 DefaultServiceRegistry
中間的調(diào)用鏈就不列出源碼了,對(duì)分析沒(méi)有太大幫助懊蒸,感興趣的可以根據(jù)時(shí)序圖自己去查看源碼荣倾。直接看 BuildActionsFactory
的 runBuildInProcess()
。
// BuildActionsFactory.java
private Runnable runBuildInProcess(StartParameterInternal startParameter, DaemonParameters daemonParameters) {
// 創(chuàng)建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));
}
來(lái)看看 ServiceRegistryBuilder
的 build()
榛鼎。
// ServiceRegistryBuilder.java
public ServiceRegistry build() {
// 1. 創(chuàng)建 DefaultServiceRegistry
DefaultServiceRegistry registry = new DefaultServiceRegistry(displayName, parents.toArray(new ServiceRegistry[0]));
for (Object provider : providers) {
// 2. 這里會(huì)把 GlobalScopeServices 添加進(jìn)去
registry.addProvider(provider);
}
return registry;
}
這里會(huì)創(chuàng)建 DefaultServiceRegistry
的對(duì)象逃呼,然后調(diào)用 addProvider()
添加 GlobalScopeServices
,這兩個(gè)地方是重點(diǎn)者娱。來(lái)看看 DefaultServiceRegistry
的構(gòu)造器和 addProvider()
做了什么抡笼。
// DefaultServiceRegistry.java
public DefaultServiceRegistry(String displayName, ServiceRegistry... parents) {
// ... 省略一部分代碼
// 主要是這個(gè)方法
findProviderMethods(this);
}
public DefaultServiceRegistry addProvider(Object provider) {
// 也調(diào)用了這個(gè)方法
findProviderMethods(provider);
}
發(fā)現(xiàn)構(gòu)造器和 addProvider()
都調(diào)用了 findProviderMethods()
。
// DefaultServiceRegistry.java
private void findProviderMethods(Object target) {
Class<?> type = target.getClass();
// 這里會(huì)反射找相應(yīng)的方法
RelevantMethods methods = RelevantMethods.getMethods(type);
// ... 省略部分代碼
}
主要看 RelevantMethods.getMethods()
究竟查找了哪些方法黄鳍。
// RelevantMethods.java
public static RelevantMethods getMethods(Class<?> type) {
// 先看緩存里面有沒(méi)有推姻,如果有則直接返回
RelevantMethods relevantMethods = METHODS_CACHE.get(type);
if (relevantMethods == null) {
// 如果緩存沒(méi)有,則通過(guò)反射獲取相關(guān)方法
relevantMethods = buildRelevantMethods(type);
METHODS_CACHE.putIfAbsent(type, relevantMethods);
}
return relevantMethods;
}
private static RelevantMethods buildRelevantMethods(Class<?> type) {
RelevantMethodsBuilder builder = new RelevantMethodsBuilder(type);
RelevantMethods relevantMethods;
// 以下三行分別找到對(duì)應(yīng)的方法
addDecoratorMethods(builder);
addFactoryMethods(builder);
addConfigureMethods(builder);
relevantMethods = builder.build();
return relevantMethods;
}
// 這里會(huì)解析 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);
}
}
}
}
可以看到,主要查找了三類方法:
-
create
開(kāi)頭或者decorate
開(kāi)頭忍燥,且入?yún)⑴c返回值類型一致的方法(裝飾方法)拧晕; -
create
開(kāi)頭又返回值且不是 static 的方法(工廠方法); -
configure
方法梅垄;
通過(guò)反射查找完對(duì)應(yīng)的方法后厂捞,再回到 DefaultServiceRegistry
的 findProviderMethods()
。
// DefaultServiceRegistry.java
private void findProviderMethods(Object target) {
Class<?> type = target.getClass();
RelevantMethods methods = RelevantMethods.getMethods(type);
// 這里會(huì)遍歷上一步找到的方法
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)反射調(diào)用
ownServices.add(new FactoryMethodService(this, target, method));
}
for (ServiceMethod method : methods.factories) {
// 包裝成FactoryMethodService靡馁,供get(XXX.class)反射調(diào)用
ownServices.add(new FactoryMethodService(this, target, method));
}
// 如果是 configure() 會(huì)直接執(zhí)行欲鹏。
for (ServiceMethod method : methods.configurers) {
applyConfigureMethod(method, target);
}
}
這里通過(guò) RelevantMethods
的 getMethods()
查找完方法后,會(huì)進(jìn)行遍歷臭墨,然后將裝飾方法和工廠方法包裝成 FactoryMethodService
對(duì)象赔嚎,后續(xù)通過(guò) get()
調(diào)用的時(shí)候?qū)嶋H上就是通過(guò) FactoryMethodService
進(jìn)行反射調(diào)用對(duì)應(yīng)的裝飾方法或工廠方法創(chuàng)建對(duì)象。
2.2.3 調(diào)用 configure()胧弛,注冊(cè) PluginServiceRegistry
有趣的點(diǎn)在于 GlobalScopeServices
在經(jīng)歷 findProviderMethods()
后會(huì)調(diào)用其 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);
// ...
}
// 主要是這個(gè)方法叶圃,它會(huì)查找 META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry這個(gè)文件袄膏,并加載里面聲明的 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;
}
根據(jù)調(diào)用鏈,可以看到最終會(huì)查找 META-INF/services/org.gradle.internal.service.scopes.PluginServiceRegistry 這個(gè)文件掺冠,主要記住兩個(gè)關(guān)鍵的 PluginServiceRegistry
沉馆,分別是 org.gradle.composite.internal.CompositeBuildServices
和 org.gradle.tooling.internal.provider.LauncherServices
。
再回到 GlobalScopServices
的 configure()
德崭,查找完 PluginServiceRegistry
后斥黑,會(huì)調(diào)用其 registerGlobalServices
完成注冊(cè)。
// GlobalScopeServices.java
void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) {
final List<PluginServiceRegistry> pluginServiceFactories = new DefaultServiceLocator(classLoaderRegistry.getRuntimeClassLoader(), classLoaderRegistry.getPluginsClassLoader()).getAll(PluginServiceRegistry.class);
// 調(diào)用 PluginServiceRegistry 的registerGlobalServices
for (PluginServiceRegistry pluginServiceRegistry : pluginServiceFactories) {
registration.add(PluginServiceRegistry.class, pluginServiceRegistry);
pluginServiceRegistry.registerGlobalServices(registration);
}
}
2.3.4 注冊(cè) CrossBuildSessionScopeServices
分析完上面的流程眉厨,思緒該回到 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();
// 這里 globalServices.get(BuildExecuter.class) 就是通過(guò)前面存下來(lái)的FactoryMethodService 進(jìn)行反射調(diào)用對(duì)應(yīng)的工廠方法獲取 BuildExecuter對(duì)象
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);
// 實(shí)際上創(chuàng)建的是 RunBuildAction 對(duì)象
return new RunBuildAction(executer, startParameter, clientMetaData(), getBuildStartTime(), parameters, sharedServices, stoppable);
}
這里的 globalServices.get(GradleUserHomeScopeServiceRegistry.class)
就是通過(guò)前面 2.2.2 保存下來(lái)的 FactoryMethodService
反射調(diào)用對(duì)應(yīng)的工廠方法,這里會(huì)調(diào)用到 LauncherServices
內(nèi)部類 ToolingGlobalScopeServices
的 createBuildExecuter()
憾股。
//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
對(duì)象鹿蜀,接著會(huì)在 ParseAndBuildAction
的 execute()
中調(diào)用 RunBuildAction
的 run()
。
// RunBuildAction.java
public void run() {
// ...
// 實(shí)際上是調(diào)用了 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);
// ...
}
前面說(shuō)了服球,這里的 executer
是 SetupLoggingActionExecuter
茴恰,緊接著又是一堆委托調(diào)用,感興趣的可以跟著時(shí)序圖向后看斩熊,就不一一列舉了往枣,這里直接看 SessionScopeBuildActionExecuter
的 execute()
。
public BuildActionResult execute(BuildAction action, BuildRequestContext requestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) {
StartParameter startParameter = action.getStartParameter();
final ServiceRegistry userHomeServices = userHomeServiceRegistry.getServicesFor(startParameter.getGradleUserHomeDir());
// 創(chuàng)建 CrossBuildSessionScopeServices
CrossBuildSessionScopeServices crossBuildSessionScopeServices = new CrossBuildSessionScopeServices(contextServices, startParameter);
// 注冊(cè) CrossBuildSessionScopeServices
ServiceRegistry buildSessionScopeServices = new BuildSessionScopeServices(
userHomeServices,
crossBuildSessionScopeServices,
startParameter,
requestContext,
actionParameters.getInjectedPluginClasspath(),
requestContext.getCancellationToken(),
requestContext.getClient(),
requestContext.getEventConsumer()
);
// 省略部分代碼
}
這里就是注冊(cè) CrossBuildSessionScopeServices
了粉渠,它也會(huì)執(zhí)行 2.2.2 分析的 findProviderMethods()
流程分冈。
2.3.5 注冊(cè) BuildTreeScopeServices
在 SessionScopeBuildActionExecuter
的 execute()
之后會(huì)經(jīng)過(guò)一系列的委托調(diào)用,走到 BuildTreeScopeBuildActionExecuter
的 execute()
霸株。
// BuildTreeScopeBuildActionExecuter.java
public BuildActionResult execute(BuildAction action, BuildRequestContext requestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) {
// ...
BuildTreeScopeServices buildTreeScopeServices = new BuildTreeScopeServices(contextServices);
// ...
}
在 execute()
里面會(huì)注冊(cè) BuildTreeScopeServices
雕沉。
2.3.6 創(chuàng)建 DefaultGradleLauncher,調(diào)用 executeTasks()進(jìn)入構(gòu)建階段
經(jīng)過(guò) BuildTreeScopeServices
的 execute()
后去件,再省略一系列的委托調(diào)用坡椒,到 InProcessBuildActionExecuter
的 execute()
饺著。
public BuildActionResult execute(final BuildAction action, final BuildRequestContext buildRequestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) {
// 這里就是反射獲取的 CompositeBuildServices 的 createIncludedBuildRegistry()
BuildStateRegistry buildRegistry = contextServices.get(BuildStateRegistry.class);
// ...
try {
// 創(chuàng)建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();
}
}
這里首先會(huì)通過(guò)反射調(diào)用 CompositeBuildServices
內(nèi)部類 CompositeBuildTreeScopeServices
的 createIncludedBuildRegistry()
獲取 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
對(duì)象;緊接著調(diào)用了 DefaultIncludedBuildRegistry
的 createRootBuild()
靴跛。
// DefaultIncludedBuildRegistry.java
public RootBuildState createRootBuild(BuildDefinition buildDefinition) {
// ...
// 這里會(huì)創(chuàng)建 DefaultRootBuildState
rootBuild = new DefaultRootBuildState(buildDefinition, gradleLauncherFactory, listenerManager, rootServices);
// ...
}
在 createRootBuild()
里面會(huì)創(chuàng)建 DefaultRootBuildState
缀雳,而在 DefaultRootBuildState
的構(gòu)造器里面會(huì)創(chuàng)建 GradleLauncher
。
// DefaultRootBuildState.java
DefaultRootBuildState(BuildDefinition buildDefinition, GradleLauncherFactory gradleLauncherFactory, ListenerManager listenerManager, BuildTreeScopeServices parentServices) {
this.listenerManager = listenerManager;
gradleLauncher = gradleLauncherFactory.newInstance(buildDefinition, this, parentServices);
}
這里調(diào)用 gradleLauncherFactory
的 newInstance()
創(chuàng)建 GradleLauncher
梢睛,gradleLauncherFactory
也是通過(guò)反射調(diào)用 CrossBuildSessionScopeServices
的 createGradleLauncherFactory()
獲取的肥印。
// DefaultGradleLauncherFactory.java
public GradleLauncher newInstance(BuildDefinition buildDefinition, RootBuildState build, BuildTreeScopeServices parentRegistry) {
// ...
// 調(diào)用 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) {
// ...
// 創(chuàng)建 DefaultGradleLauncher 對(duì)象
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;
}
這部分就是創(chuàng)建 DefaultGradleLauncher
了;緊接著又是一系列的委托調(diào)用绝葡,最終會(huì)走到 ChainingBuildActionRunner
的 run()
深碱。
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();
}
而這里只是簡(jiǎn)單的遍歷傳入的 runners
,調(diào)用其 run()
藏畅;這里的 runners
是通過(guò)反射調(diào)用的 LaunchersServices
內(nèi)部類 ToolingGlobalScopeServices
的 createExecuteBuildActionRunner()
敷硅,即 ExecuteBuildActionRunner
對(duì)象。
// LaunchersServices.java
ExecuteBuildActionRunner createExecuteBuildActionRunner() {
return new ExecuteBuildActionRunner();
}
而 ExecuteBuildActionRunner
的 run()
也只是調(diào)用 buildController
的 run()
愉阎。
// ExecuteBuildActionRunner.java
public Result run(BuildAction action, BuildController buildController) {
// ...
buildController.run();
}
buildController
是在 InProcessBuildActionExecuter
里面調(diào)用 DefaultRootBuildState
的 run()
創(chuàng)建的 GradleBuildController
對(duì)象绞蹦,那么來(lái)看它的 run()
。
public GradleInternal run() {
return doBuild(GradleInternal.BuildType.TASKS, new Action<GradleLauncher>() {
@Override
public void execute(@Nonnull GradleLauncher gradleLauncher) {
gradleLauncher.executeTasks();
}
});
}
這里最終會(huì)調(diào)用到 gradleLauncher
的 executeTasks()
進(jìn)入構(gòu)建階段榜旦;至此 gradle 的啟動(dòng)流程就分析完了幽七。