您好,登錄后才能下訂單哦!
接著上一篇博客開始講:
5. Gradle編譯其他應(yīng)用程序流程(一)
一. BuildActionsFactory.runBuildInProcess
private Runnable runBuildInProcess(StartParameter startParameter, DaemonParameters daemonParameters, ServiceRegistry loggingServices) { ServiceRegistry globalServices = ServiceRegistryBuilder.builder() .displayName("Global services") .parent(loggingServices) .parent(NativeServices.getInstance()) .provider(new GlobalScopeServices(startParameter.isContinuous())) .build(); return runBuildAndCloseServices(startParameter, daemonParameters, globalServices.get(BuildExecuter.class), globalServices); }
這個方法就是很繞的地方了!看了半天才大概明白。
首先runBuildInProcess這個方法分成兩個部分
1. 初始化
2. 執(zhí)行
首先來看初始化,也就是:
ServiceRegistry globalServices = ServiceRegistryBuilder.builder() .displayName("Global services") .parent(loggingServices) .parent(NativeServices.getInstance()) .provider(new GlobalScopeServices(startParameter.isContinuous())) .build();
直接看build():
public ServiceRegistry build() { DefaultServiceRegistry registry = new DefaultServiceRegistry(displayName, parents); for (Object provider : providers) { registry.addProvider(provider); } return registry; }
實例化的是DefaultServiceRegistry對象,那來看看DefaultServiceRegistry的Javadoc,看看怎么描述的。
org.gradle.internal.service.DefaultServiceRegistry A hierarchical ServiceRegistry implementation. Subclasses can register services by: Calling add(Class, Object) to register a service instance. Calling addProvider(Object) to register a service provider bean. A provider bean may have factory, decorator and configuration methods as described below. Adding a factory method. A factory method should have a name that starts with 'create', and have a non-void return type. For example, protected SomeService createSomeService() { .... }. Parameters are injected using services from this registry or its parents. Note that factory methods with a single parameter and an return type equal to that parameter type are interpreted as decorator methods. Adding a decorator method. A decorator method should have a name that starts with 'decorate', take a single parameter, and a have return type equal to the parameter type. Before invoking the method, the parameter is located in the parent service registry and then passed to the method. Adding a configure method. A configure method should be called 'configure', take a ServiceRegistration parameter, and a have a void return type. Additional parameters are injected using services from this registry or its parents. Service instances are created on demand. getFactory(Class) looks for a service instance which implements Factory<T> where T is the expected type. Service instances and factories are closed when the registry that created them is closed using close(). If a service instance or factory implements java.io.Closeable or org.gradle.internal.concurrent.Stoppable then the appropriate close() or stop() method is called. Instances are closed in reverse dependency order. Service registries are arranged in a hierarchy. If a service of a given type cannot be located, the registry uses its parent registry, if any, to locate the service. 主要意思就是DefaultServiceRegistry可以通過add(xxx)方法接受服務(wù)對象,通過addProvider(xxx)方法接受service provider bean對象。 而service provider bean可以有3種類型的方法 factory 方法 'create'開頭,不是void的返回值,等等 decorator 方法 'decorator'開頭,等等 configure 方法 'configure'方法,有個ServiceRegistration參數(shù),void返回類型,等等。
那我們回過頭來看初始化方法,里面?zhèn)魅肓薌lobalScopeServices作為provider,所以看下GlobalScopeServices。
二. GlobalScopeServices
public class GlobalScopeServices { ... void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) { System.out.println("GlobalScopeServices configure registration : " + registration + " classLoaderRegistry: " + classLoaderRegistry); 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); } } ... ClassLoaderRegistry createClassLoaderRegistry(ClassPathRegistry classPathRegistry, HashingClassLoaderFactory classLoaderFactory) { if (GradleRuntimeShadedJarDetector.isLoadedFrom(getClass())) { return new FlatClassLoaderRegistry(getClass().getClassLoader()); } System.out.println("createClassLoaderRegistry"); return new DefaultClassLoaderRegistry(classPathRegistry, classLoaderFactory); } ... }
首先看configure方法
pluginServiceRegistry.registerGlobalServices(registration);
這行代碼registerGlobalServices其實調(diào)用的是LauncherServices.registerGlobalServices
也就是:
public class LauncherServices implements PluginServiceRegistry { public void registerGlobalServices(ServiceRegistration registration) { registration.addProvider(new ToolingGlobalScopeServices()); } static class ToolingGlobalScopeServices { BuildExecuter createBuildExecuter(GradleLauncherFactory gradleLauncherFactory, ServiceRegistry globalServices, ListenerManager listenerManager, FileWatcherFactory fileWatcherFactory, ExecutorFactory executorFactory, StyledTextOutputFactory styledTextOutputFactory) { List<BuildActionRunner> buildActionRunners = globalServices.getAll(BuildActionRunner.class); BuildActionExecuter<BuildActionParameters> delegate = new InProcessBuildActionExecuter(gradleLauncherFactory, new ChainingBuildActionRunner(buildActionRunners)); return new ContinuousBuildActionExecuter(delegate, fileWatcherFactory, listenerManager, styledTextOutputFactory, executorFactory); } ExecuteBuildActionRunner createExecuteBuildActionRunner() { return new ExecuteBuildActionRunner(); } ClassLoaderCache createClassLoaderCache() { return new ClassLoaderCache(); } } }
registerGlobalServices的時候,實例化并添加了ToolingGlobalScopeServices對象。
最主要的是實例化了一個InProcessBuildActionExecuter對象,當然這里又不能免俗的使用了裝飾者模式(ContinuousBuildActionExecuter包含了InProcessBuildActionExecuter,其實還是調(diào)用InProcessBuildActionExecuter.execute)
---------------------------分割線----------------------------------------
這個中間的邏輯非常繞,就是怎么回調(diào)到provider的factory和config方法?
有興趣的同學可以自己去看。我貼一段中間回調(diào)createXXX的代碼調(diào)用堆棧(也就是factory方法的調(diào)用)
java.lang.Exception: Sandy DefaultModule init at org.gradle.api.internal.classpath.DefaultModuleRegistry$DefaultModule.<init>(DefaultModuleRegistry.java:256) at org.gradle.api.internal.classpath.DefaultModuleRegistry.module(DefaultModuleRegistry.java:121) at org.gradle.api.internal.classpath.DefaultModuleRegistry.loadModule(DefaultModuleRegistry.java:89) at org.gradle.api.internal.classpath.DefaultModuleRegistry.getModule(DefaultModuleRegistry.java:77) at org.gradle.api.internal.DynamicModulesClassPathProvider.findClassPath(DynamicModulesClassPathProvider.java:38) at org.gradle.api.internal.DefaultClassPathRegistry.getClassPath(DefaultClassPathRegistry.java:34) at org.gradle.initialization.DefaultClassLoaderRegistry.<init>(DefaultClassLoaderRegistry.java:32) at org.gradle.internal.service.scopes.GlobalScopeServices.createClassLoaderRegistry(GlobalScopeServices.java:212) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75) at org.gradle.internal.service.DefaultServiceRegistry.invoke(DefaultServiceRegistry.java:468) at org.gradle.internal.service.DefaultServiceRegistry.access$1200(DefaultServiceRegistry.java:84) at org.gradle.internal.service.DefaultServiceRegistry$FactoryMethodService.invokeMethod(DefaultServiceRegistry.java:803) at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.create(DefaultServiceRegistry.java:758) at org.gradle.internal.service.DefaultServiceRegistry$ManagedObjectProvider.getInstance(DefaultServiceRegistry.java:595) at org.gradle.internal.service.DefaultServiceRegistry$SingletonService.get(DefaultServiceRegistry.java:640) at org.gradle.internal.service.DefaultServiceRegistry.applyConfigureMethod(DefaultServiceRegistry.java:257) at org.gradle.internal.service.DefaultServiceRegistry.findProviderMethods(DefaultServiceRegistry.java:216) at org.gradle.internal.service.DefaultServiceRegistry.addProvider(DefaultServiceRegistry.java:358) at org.gradle.internal.service.ServiceRegistryBuilder.build(ServiceRegistryBuilder.java:52) at org.gradle.launcher.cli.BuildActionsFactory.runBuildInProcess(BuildActionsFactory.java:135) at org.gradle.launcher.cli.BuildActionsFactory.createAction(BuildActionsFactory.java:91) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.createAction(CommandLineActionFactory.java:255) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:240) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:217) at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:33) at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:210) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:174) at org.gradle.launcher.Main.doAction(Main.java:33) at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:60) at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:37) at org.gradle.launcher.GradleMain.main(GradleMain.java:24)
三. 執(zhí)行
private Runnable runBuildInProcess(StartParameter startParameter, DaemonParameters daemonParameters, ServiceRegistry loggingServices) { ServiceRegistry globalServices = ServiceRegistryBuilder.builder() .displayName("Global services") .parent(loggingServices) .parent(NativeServices.getInstance()) .provider(new GlobalScopeServices(startParameter.isContinuous())) .build(); return runBuildAndCloseServices(startParameter, daemonParameters, globalServices.get(BuildExecuter.class), globalServices); } private Runnable runBuildAndCloseServices(StartParameter startParameter, DaemonParameters daemonParameters, BuildActionExecuter<BuildActionParameters> executer, ServiceRegistry sharedServices, Object... stopBeforeSharedServices) { BuildActionParameters parameters = createBuildActionParamters(startParameter, daemonParameters); Stoppable stoppable = new CompositeStoppable().add(stopBeforeSharedServices).add(sharedServices); return new RunBuildAction(executer, startParameter, clientMetaData(), getBuildStartTime(), parameters, sharedServices, stoppable); } public class RunBuildAction implements Runnable { ServiceRegistry globalServices = ServiceRegistryBuilder.builder() .displayName("Global services") .parent(loggingServices) .parent(NativeServices.getInstance()) .provider(new GlobalScopeServices(startParameter.isContinuous())) .build(); public void run() { try { System.out.println("RunBuildAction executer: " + executer + " startParameter: " + startParameter + " buildActionParameters: " + buildActionParameters); executer.execute( new ExecuteBuildAction(startParameter), new DefaultBuildRequestContext(new DefaultBuildRequestMetaData(clientMetaData, startTime), new DefaultBuildCancellationToken(), new NoOpBuildEventConsumer()), buildActionParameters, sharedServices); } finally { if (stoppable != null) { stoppable.stop(); } } } }
在RunBuildAction里面執(zhí)行的還是executer.execute,也就是第三個參數(shù)globalServices.get(BuildExecuter.class)
globalServices是build出來的DefaultServiceRegistry對象
其實就是GlobalScopeServices.configure方法里面的ServiceRegistration對象。
void configure(ServiceRegistration registration, ClassLoaderRegistry classLoaderRegistry) { System.out.println("GlobalScopeServices configure registration : " + registration + " classLoaderRegistry: " + classLoaderRegistry); 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); } }
打印日志:
GlobalScopeServices configure registration : org.gradle.internal.service.DefaultServiceRegistry$1@56620197 classLoaderRegistry: org.gradle.initialization.DefaultClassLoaderRegistry@393671df
接下來又繼續(xù)在configure然后調(diào)用
pluginServiceRegistry.registerGlobalServices(registration);
根據(jù)前面說明的分析,這個registerGlobalServices方法就是調(diào)用LauncherServices.registerGlobalServices(registration),參數(shù)是DefaultServiceRegistry registration
public class LauncherServices implements PluginServiceRegistry { public void registerGlobalServices(ServiceRegistration registration) { registration.addProvider(new ToolingGlobalScopeServices()); } static class ToolingGlobalScopeServices { BuildExecuter createBuildExecuter(GradleLauncherFactory gradleLauncherFactory, ServiceRegistry globalServices, ListenerManager listenerManager, FileWatcherFactory fileWatcherFactory, ExecutorFactory executorFactory, StyledTextOutputFactory styledTextOutputFactory) { List<BuildActionRunner> buildActionRunners = globalServices.getAll(BuildActionRunner.class); BuildActionExecuter<BuildActionParameters> delegate = new InProcessBuildActionExecuter(gradleLauncherFactory, new ChainingBuildActionRunner(buildActionRunners)); return new ContinuousBuildActionExecuter(delegate, fileWatcherFactory, listenerManager, styledTextOutputFactory, executorFactory); } } }
所以也就是給DefaultServiceRegistry registration add了一個ToolingGlobalScopeServices對象。
這樣就關(guān)聯(lián)起來了,也就是說RunBuildAction.run方法里面執(zhí)行的executer.execute走的就是ContinuousBuildActionExecuter.execute,然后通過裝飾者模式,最后走的是InProcessBuildActionExecuter.execute方法。
很繞!??!
下面來看InProcessBuildActionExecuter.execute方法。
四. InProcessBuildActionExecuter
@Override public GradleLauncher newInstance(StartParameter startParameter, BuildRequestContext requestContext, ServiceRegistry parentRegistry) { // This should only be used for top-level builds if (tracker.getCurrentBuild() != null) { throw new IllegalStateException("Cannot have a current build"); } BuildScopeServices buildScopeServices = createBuildScopeServices(parentRegistry); DefaultGradleLauncher launcher = doNewInstance(startParameter, false, requestContext.getCancellationToken(), requestContext, requestContext.getEventConsumer(), buildScopeServices); DeploymentRegistry deploymentRegistry = parentRegistry.get(DeploymentRegistry.class); deploymentRegistry.onNewBuild(launcher.getGradle()); return launcher; } public class InProcessBuildActionExecuter implements BuildActionExecuter<BuildActionParameters> { private final GradleLauncherFactory gradleLauncherFactory; private final BuildActionRunner buildActionRunner; public InProcessBuildActionExecuter(GradleLauncherFactory gradleLauncherFactory, BuildActionRunner buildActionRunner) { this.gradleLauncherFactory = gradleLauncherFactory; this.buildActionRunner = buildActionRunner; } public Object execute(BuildAction action, BuildRequestContext buildRequestContext, BuildActionParameters actionParameters, ServiceRegistry contextServices) { GradleLauncher gradleLauncher = gradleLauncherFactory.newInstance(action.getStartParameter(), buildRequestContext, contextServices); try { gradleLauncher.addStandardOutputListener(buildRequestContext.getOutputListener()); gradleLauncher.addStandardErrorListener(buildRequestContext.getErrorListener()); GradleBuildController buildController = new GradleBuildController(gradleLauncher); buildActionRunner.run(action, buildController); System.out.println("Sandy buildController.getResult(): " + buildController.getResult()); return buildController.getResult(); } finally { gradleLauncher.stop(); } } }
從代碼來看newInstance返回的對象是DefaultGradleLauncher,那么接下來就真正走到開始編譯的過程了,這個下篇再繼續(xù)分析。
最后,附上一點DefaultGradleLauncher源代碼:
public class DefaultGradleLauncher extends GradleLauncher { private enum Stage { Load, Configure, Build } ... @Override public BuildResult run() { return doBuild(Stage.Build); } @Override public BuildResult getBuildAnalysis() { return doBuild(Stage.Configure); } @Override public BuildResult load() throws ReportedException { return doBuild(Stage.Load); } private BuildResult doBuild(final Stage upTo) { return buildOperationExecutor.run("Run build", new Factory<BuildResult>() { @Override public BuildResult create() { ... doBuildStages(upTo); ... } }); } private void doBuildStages(Stage upTo) { if (stage == Stage.Build) { throw new IllegalStateException("Cannot build with GradleLauncher multiple times"); } if (stage == null) { // Evaluate init scripts initScriptHandler.executeScripts(gradle); // Build `buildSrc`, load settings.gradle, and construct composite (if appropriate) settings = settingsLoader.findAndLoadSettings(gradle); stage = Stage.Load; } if (upTo == Stage.Load) { return; } if (stage == Stage.Load) { // Configure build buildOperationExecutor.run("Configure build", new Runnable() { @Override public void run() { buildConfigurer.configure(gradle); if (!gradle.getStartParameter().isConfigureOnDemand()) { buildListener.projectsEvaluated(gradle); } modelConfigurationListener.onConfigure(gradle); } }); stage = Stage.Configure; } if (upTo == Stage.Configure) { return; } // After this point, the GradleLauncher cannot be reused stage = Stage.Build; // Populate task graph buildOperationExecutor.run("Calculate task graph", new Runnable() { @Override public void run() { buildConfigurationActionExecuter.select(gradle); if (gradle.getStartParameter().isConfigureOnDemand()) { buildListener.projectsEvaluated(gradle); } } }); // Execute build buildOperationExecutor.run("Run tasks", new Runnable() { @Override public void run() { buildExecuter.execute(gradle); } }); } ... }
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。