接着上一篇博客开始讲:

5. Gradle编译其他应用程序流程(一)



一. BuildActionsFactory.runBuildInProcess

1
2
3
4
5
6
7
8
9
10
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. 执行


首先来看初始化,也就是:

1
2
3
4
5
6
ServiceRegistry globalServices = ServiceRegistryBuilder.builder()
         .displayName( "Global services" )
         .parent(loggingServices)
         .parent(NativeServices.getInstance())
         .provider( new  GlobalScopeServices(startParameter.isContinuous()))
         .build();

直接看build():

1
2
3
4
5
6
7
public  ServiceRegistry build() {
     DefaultServiceRegistry registry =  new  DefaultServiceRegistry(displayName, parents);
     for  (Object provider : providers) {
         registry.addProvider(provider);
     }
     return  registry;
}



实例化的是DefaultServiceRegistry对象,那来看看DefaultServiceRegistry的Javadoc,看看怎么描述的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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)方法接受服务对象,通过addProvider(xxx)方法接受service provider bean对象。
而service provider bean可以有3种类型的方法
 
factory 方法
'create'开头,不是void的返回值,等等
 
decorator 方法
'decorator'开头,等等
 
configure 方法
'configure'方法,有个ServiceRegistration参数,void返回类型,等等。



那我们回过头来看初始化方法,里面传入了GlobalScopeServices作为provider,所以看下GlobalScopeServices。



二. GlobalScopeServices

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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其实调用的是LauncherServices.registerGlobalServices


也就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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,其实还是调用InProcessBuildActionExecuter.execute)


---------------------------分割线----------------------------------------



这个中间的逻辑非常绕,就是怎么回调到provider的factory和config方法?


有兴趣的同学可以自己去看。我贴一段中间回调createXXX的代码调用堆栈(也就是factory方法的调用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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 )




三. 执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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里面执行的还是executer.execute,也就是第三个参数globalServices.get(BuildExecuter.class)


globalServices是build出来的DefaultServiceRegistry对象


其实就是GlobalScopeServices.configure方法里面的ServiceRegistration对象。

1
2
3
4
5
6
7
8
9
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);
     }
}



打印日志:

1
GlobalScopeServices configure registration : org.gradle.internal.service.DefaultServiceRegistry$1@56620197 classLoaderRegistry: org.gradle.initialization.DefaultClassLoaderRegistry@393671df


接下来又继续在configure然后调用

1
pluginServiceRegistry.registerGlobalServices(registration);


根据前面说明的分析,这个registerGlobalServices方法就是调用LauncherServices.registerGlobalServices(registration),参数是DefaultServiceRegistry registration


1
2
3
4
5
6
7
8
9
10
11
12
13
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对象。


这样就关联起来了,也就是说RunBuildAction.run方法里面执行的executer.execute走的就是ContinuousBuildActionExecuter.execute,然后通过装饰者模式,最后走的是InProcessBuildActionExecuter.execute方法。


很绕!!!


下面来看InProcessBuildActionExecuter.execute方法。



四. InProcessBuildActionExecuter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@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,那么接下来就真正走到开始编译的过程了,这个下篇再继续分析。


最后,附上一点DefaultGradleLauncher源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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);
             }
         });
     }
     
     ...
}