Gradle-01 概览

gradle概览

  • Distribution
作用
src 源码打包,不能运行
bin 可执行binary脚本(linux/windows)
all 除了源码,还有demo
- 一般通过wrapper
  • Wrapper

    • 作用:开发时,保持版本一致;在未安装gradle的机器上执行,gradle wrapper 时,会启动一个小的jvm加载生成的指令生成的jar包,从gradle官网下载项目对应的gradle版本,
    • 绑定gradle版本gradle+版本号 wrapper
    • gradle wrapper + 项目 指令执行后,会查看本地是否有项目对应的gradle版本,没有则会先去下载到GradleUserHome中去,通过启动的Jvm去访问对应版本的daemon.Jvm进程
    • 若没有找到,则启动一个daemon,连接daemon
    • 本质:在安装目录下,安装一个很小的jar包和一个脚本,用来下载真正的gradle的discription
    • 相关指令:
      • gradle wrapper
  • GradleUserHome

    • 默认路径在~/.gradle/ ,不建议使用本地maven的m2替代,因为原本的.gradle目录下的模块分的很清晰,功能明确
    • 如果启动时,指定参数,使用别的目录代替GradleUserHome ,后果是每次构建需要重新下载插件与依赖到新的目录
    • 默认情况下,gradle运行时,除了和项目打交道,还有当前项目构建的全新的GradleUserHome目录,所有jar包都得重新下载
    目录 desc
    init.d 项目运行前,仓库替换
    wrapper gradle wrapper 指令运行后,下载的安装包会放在此处
    caches 类似于maven的.m2 ,但是除了本地仓库的包以外,还有其他东西,它会进行自动清理
  • Daemon(守护进程)

    • 项目启动时,会开启一个client,然后启动一个daemon,通过client向daemon收发请求,项目关闭,client关闭,daemon保持启动,有类似项目再次部署时,会直接通过新的client访问已经启动的daemon,所以速度很快,默认daemon不使用3小时后关闭;不同项目兼容性考虑,也可使用--no-daemon 启动项目,就没有速度优势了
    • 手动停止daemon,gradle wrapper --stop

Gradle构建

Gradle生命周期

  1. 生命周期介绍
  • Initialization

    • 读取项目信息,确定是单项目还是多项目工程,然后确认哪些项目是要参与进来,并为他们创建Project 实例,一般我们不会接触
  • Configuration

    • 进行配置,从头到尾将build.gradle脚本跑一遍。不运行项目,只是对构建进行一些配置,本质就是对build.gradle执行一次,例如执行哪些任务,运行哪些插件,执行哪些逻辑
  • Execution

    • 运行阶段。具体执行哪些task
  1. 生命周期应用
  • Task。task是gardle中最小的任务单元,任务之间可以进行复杂的操作(动态创建任务,多任务间依赖调用)
    • 用法。task('helloworld',Closure closure),helloworld 即当前任务的名字,closure闭包作用是对helloworld 任务进行Configuration ,可以在closure 中调用doLast或dependsOn等方法,在helloworldConfiguration 期间进行wrapper(例如,调用其他任务,或者动态调用任务等)
    • dependsOn方法,方法参数为其他任务的名字。多任务中通过该方法可执行所依赖的其他任务
    • doLast,在生命周期的configuration阶段,将doLast闭包函数放在任务的最后,并不执行 ,执行任务时,会调用该方法。doFirst相反
  • ./gradlew help ,任何gradle项目都有一个该task,可以执行此命令观察taks执行的流程是否如预期,tips 使用该命令可以查看到所需依赖下载状态(IDE中只能看到是否配置好依赖,但是无法确定还差多少 完成)

Gradle的核心模型

  • Project。gradle项目中一切无主的方法都会去Project中查找,如task;若是多项目工程,用project.parent.childProjects 对不同的子项目进行配置或者依赖

    • afterEvaluate方法,钩子函数。当前项目的Project实例操作完成后(即在生命周期configure阶段gradle引擎执行完一次build.gradle后,才会执行该方法,并不会因为它位置在最前面就先执行,有趣的是Java的main方法执行顺序是按照方法排列的顺序)进行一些动作,beforeEvaluate是与它对应的钩子函数

    • allprojects方法,对一个多项目工程中,所有Project实例进行的操作

    • file方法,读取文件

    • findProject方法,用名字去查找多项目中某一个项目的Project实例

    • findProperty方法,去查找某一个属性

    • getBuildDir方法,查找在项目下一个名为build目录下临时的构建输出

Gradle插件编写入门

  • classpath与gradle

    • gradle启动时会启动一个jvm,有自己的classpath;Java项目的classpath在project/src目录下作用
    • java项目中有需要的jar包,则需在build.gradle中设置仓库
    /**
    *repositories方法和dependencies方法都是无助的闭包函数,构建时会在gradle的Project的API中找具体实现
    *任何grdle项目中的无主方法都在Project的API中
    *
    */
    //指定中央仓库
    repositories{
    	mavenCentral()
    }
    //项目所需的依赖
    dependencies{
    	compile group:'org.apache.commons',name:'commons-lang3',version:'3.9'
    }
    
    • 在构建build.gradle时使用Java的或其他非gradle的API,则需将声明仓库和依赖放在buildscript方法中
    buildscript{
        //指定中央仓库
        repositories{
    	    mavenCentral()
        }
        //项目所需的依赖
        dependencies{
    	    compile group:'org.apache.commons',name:'commons-lang3',version:'3.9'
        }
    }
    
    
    • gradle插件加载顺序
      1. 在加载build.gradle时,如果有buildSrc目录,则会先加载buildSrc中的内容
  1. 类中编写插件
    1. 实现Plugin接口,重写apply方法
    2. 将项目移至类中
    3. 调用apply方法,第一是DSL版。后一种是原版
    • apply plugin: MyAwesomePlugin
    • apply ([plugin:MyAwesomePlugin])

gradle处理jar包原理

  1. Gradle 与 Java 项目运行在各自的JVM中,Java 项目中的依赖的jar 包通过build.gradle中的dependencies 中导入,实际上gradle是将jar添加进了java的classpath中,但是gradle自身的jvm的classpath中并没有导入这样的jar包

  2. Gradle在build.gradle中使用第三方jar包或使用自定义的插件有两种方法:

    • 方法一(buildscript):在build.gradle中使用buildscript方法,在该方法内部使用repositories 写jar包仓库,在dependencies 中填jar包信息,并声明生命周期
    • 方法二(在项目根目录下创建buildSrc包):初始化buildSrc为一个gradle项目,并且创建目录(mkdir -p src/main/java),在java包自定义插件类,然后将插件类引入项目外部的build.gradle中。项目启动时,gradle在 Configuration阶段扫描build.gradle时,会去引入的插件目录确认(buildSrc)。下方是编写插件的示例
public class MyPlugin implements Plugin<Project>{
    @Override
    public void apply(Project project){
        for(int i = 0;i<10;i++){ 
            project.task("task"+i)
	}
    }
}
原文地址:https://www.cnblogs.com/luckyCoder/p/12732443.html