栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

gradle-1启动篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

gradle-1启动篇

gradle-1启动篇
  • grade-1 启动流程(v6.9.1)
    • 引子
    • 准备
    • wrapper模块
      • 1. 下载,解压gradle
      • 2. 启动
    • GradleMain.main

grade-1 启动流程(v6.9.1) 引子

做为Android开发,不仅需要对Apk构建流程熟悉外,还要知道gradle内部实现,通常说的gradle的生命周期你知道分为哪几个阶段吗?在不同生命周期你知道gradle到底做了什么吗?
本篇开始研究下gradle源码内部基本实现吧,你能从中找到答案,此处以6.9.1版本为分析

先看入口吧,gradlew.bat文件,里面核心代码

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

前三个为空,最终调用的是GradleWrapperMain.main方法

准备

准备gradle源码

git clone https://github.com/gradle/gradle
gcb feature_v6.9.1 v6.9.1

修改com.gradle.enterprise:test-distribution-gradle-plugin:1.1.2-rc-1调整为com.gradle.enterprise:test-distribution-gradle-plugin:1.1.2同步即可

wrapper模块

入口如下

// org.gradle.wrapper.GradleWrapperMain.java
public static void main(String[] args) throws Exception {
  			
  			// gradle-wrapper.jar
        File wrapperJar = wrapperJar();
        // load gradle-wrapper.properties file
        File propertiesFile = wrapperProperties(wrapperJar);
        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()));
				
		// gradle home 目录:~/.gradle
        File gradleUserHome = gradleUserHome(options);

        addSystemProperties(gradleUserHome, rootDir);

        Logger logger = logger(options);
				
		// 构建一个wrapper执行器,调用execute;
		// 1. 执行安装(如果本地没有安装
        WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile);
        wrapperExecutor.execute(
                args,
                new Install(logger, new Download(logger, "gradlew", UNKNOWN_VERSION), new PathAssembler(gradleUserHome)),
                new BootstrapMainStarter());
    }

// org.gradle.wrapper.WrapperExecutor.java
public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {				
  			// 
        File gradleHome = install.createDist(config);
        bootstrapMainStarter.start(args, gradleHome);
    }

此处会调用wrapperExecutor.execute方法;主要做了2件事件

  1. createDist -> 如果没有gradle,下载grade文件(Grade-wrapper.properties文件中distributionUrl对应的文件)并解压;否则直接返回gradlehome文件
  2. start -> 调用org.gradle.launcher.GradleMain.main方法(反射)
1. 下载,解压gradle

先看下Grade-wrapper.properties文件格式如下

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

里面包含了需要下载gradle包的链接地址,WrapperConfiguration配置里面就包含了这些元信息

public File createDist(final WrapperConfiguration configuration) throws Exception {
        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() {
            public File call() throws Exception {
                final File markerFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".ok");
              	// 如果本地目录存在&存在.ok文件;
                if (distDir.isDirectory() && markerFile.isFile()) {
                    InstallCheck installCheck = verifyDistributionRoot(distDir, distDir.getAbsolutePath());
                    if (installCheck.isVerified()) {
                      	// 验证通过,直接返回gradlehome
                        return installCheck.gradleHome;
                    }
                    // Distribution is invalid. Try to reinstall.
                    System.err.println(installCheck.failureMessage);
                    markerFile.delete();
                }

                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);
                    download.download(distributionUrl, tmpZipFile);
                    tmpZipFile.renameTo(localZipFile);
                }

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

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

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

                InstallCheck installCheck = verifyDistributionRoot(distDir, safeDistributionUrl.toString());
                if (installCheck.isVerified()) {
                    setExecutablePermissions(installCheck.gradleHome);
                    markerFile.createNewFile();
                    return installCheck.gradleHome;
                }
                // Distribution couldn't be installed.
                throw new RuntimeException(installCheck.failureMessage);
            }
        });
    }
2. 启动

GradleMain.main

GradleMain.main -> ProcessBootstrap.run 最终来到了org.gradle.launcher.Main.run方法 -> DefaultCommandLineActionFactory.convert(Arrays.asList(args)).execute(listener) ==> WithLogging.execute ==>

做了一层装饰器,层层调用最终还是执行了action 也即是ParseAndBuildAction.execute

BuildActionsFactory.createAction ==> runBuildInProcess

private Runnable runBuildInProcess(StartParameterInternal startParameter, DaemonParameters daemonParameters) {
			// DefaultServiceRegistry
  		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));
    }

GlobalScopeServices向DefaultServiceRegistry注册服务,DefaultServiceRegistry构造器比较有意思

private void findProviderMethods(Object target) {
        Class type = target.getClass();
  
  			//1.  方法解析
        RelevantMethods methods = RelevantMethods.getMethods(type);
  
  			// 2. 对方法进行分类处理,转化为相关的方法服务,编译外部调用
        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()));
            }
            ownServices.add(new FactoryMethodService(this, target, method));
        }
        for (ServiceMethod method : methods.factories) {
            ownServices.add(new FactoryMethodService(this, target, method));
        }
  
  			// 3. 针对 config配置,则直接反射调用
        for (ServiceMethod method : methods.configurers) {
            applyConfigureMethod(method, target);
        }
    }
private void applyConfigureMethod(ServiceMethod method, Object target) {
        Object[] params = new Object[method.getParameterTypes().length];
        for (int i = 0; i < method.getParameterTypes().length; i++) {
            Type paramType = method.getParameterTypes()[i];
            if (paramType.equals(ServiceRegistration.class)) {
                params[i] = newRegistration();
            } else {
                Service paramProvider = find(paramType, allServices);
                if (paramProvider == null) {
                    throw new ServiceLookupException(String.format("Cannot configure services using %s.%s() as required service of type %s is not available.",
                        method.getOwner().getSimpleName(),
                        method.getName(),
                        format(paramType)));
                }
                params[i] = paramProvider.get();
            }
        }
        try {
            method.invoke(target, params);
        } catch (Exception e) {
            throw new ServiceLookupException(String.format("Could not configure services using %s.%s().",
                method.getOwner().getSimpleName(),
                method.getName()), e);
        }
    }

回头再看ServiceRegistryBuilder

 public ServiceRegistry build() {
        DefaultServiceRegistry registry = new DefaultServiceRegistry(displayName, parents.toArray(new ServiceRegistry[0]));
        for (Object provider : providers) {
            registry.addProvider(provider);
        }
        return registry;
    }
	
		// DefaultServiceRegistry.java
		
    public DefaultServiceRegistry addProvider(Object provider) {
        assertMutable();
        findProviderMethods(provider);
        return this;
    }

可以看到此处又再次调用了findProviderMethods(provider);也就是对GlobalScopeServices类做解析处理了

中间过层忽略,最终来到了DefaultGradleLauncher.executeTasks

public GradleInternal executeTasks() {
        doBuildStages(Stage.RunTasks);
        return gradle;
}

至此进入了gradle五个Stage流程中

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

        String getDisplayName() {
            return name();
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027723.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号