有道无术,术尚可求,有术无道,止于术。

Project

在Gradle 中,build.gradle是最核心的文件,这个文件就是Gradle 中的一个Project对象实例,项目中每个模块都会有一个build.gradle文件。

Project接口中的属性和方法就对应了文件中的配置,此接口是用于从构建文件与 Gradle 交互的主要 API。

Project API
在这里插入图片描述
Projectbuild.gradle 文件之间存在一对一的关系。在构建初始化期间,Gradle为每个参与构建的项目组装一个Project对象,步骤如下:

  • 给整个构建创建一个settings实例,一个settings实例就是一个settings.gradle文件,多模块时,只有根项目才有这个文件
  • 针对settings实例的配置,按配置层次扫描并解析配置在 settings.gradle中的所有模块,创建 Project实例的层次结构
  • 针对每个project对应的build.gradle进行初始,并创建Projecte 实例,项目按广度顺序进行评估,因此根项目在其子项目之前进行加载

比如下方示例中,会根据 settings.gradle中配置的子父工程依次进行实例化:
在这里插入图片描述

属性

Project有很多属性,有默认也有自定义的。

比如,我们可以直接在build.gradle文件中获取属性,name属性就表示当前工程名称,我们可以通过以下几种方式获取。

println("name:"+name)
println("name:"+project.name)
println(project.property("name"))

可以在官网中查看Project的所有默认属性,常用的有:

属性描述
allprojects包含此项目及其子项目的集合。
buildDir当前项目的编译目录(自动生成)默认值 porjectDir/build
defaultTasks当前项目的默认任务的名字集,当前构建没有提供任务名时会执行这些默认任务
group当前项目的组名
logger当前项目的日志器,可以用来在 build 文件中写日志
name此项目的名称
parent此项目的父项目
path这个项目的绝对路径
project当前project对象实例
rootDir本项目的根目录。根目录是根项目的项目目录
rootProject当前项目层次结构中的根project
subprojects当前项目的子项目的集合
tasks本项目的task集合。
version此项目的版本

自定义扩展属性时必须通过ext命名空间定义。一旦定义了一个额外的属性,它就可以直接在拥有的对象上使用(比如当前项目、任务和子项目),并且可以读取和更新。

比如可以在扩展属性中定义一个依赖的版本号,然后在版本配置中,引用该属性作为版本号:

ext {
    bootVersion = '2.6.8'
}
dependencies {
    implementation "org.springframework.boot:spring-boot-starter-web:${bootVersion}"
}

属性是有作用域的,读写属性时,Project会按照下面范围的顺序进行查找的,在某个范围找到属性后就会返回该属性。如果没有找到,会抛出异常。

  1. project 对象自身。这个范围里的属性包含 project 实现类中定义有getters和setters方法的所有属性。
  2. Project的ext属性。每个Project都会维护一个额外属性的映射,它可以包含任意的名称+值对。定义
    后,此作用域的属性是可读写的。
  3. 通过插件被添加到Project中的扩展属性(extensions )。每个扩展名都可以作为只读属性使用,其名称与扩展名
    相同。
  4. 通过插件添加到Project中的约定属性(convention)。插件可以通过Project的Convention 对象向Project中添加
    属性和方法。此范围的属性的可读可写性取决于约束对象。
  5. Project中Tasks。可以使用Task的名称作为属性名称来访问task。此范围的属性是只读的。
  6. ext的属性和约定属性从项目的父级继承,递归到根项目。此范围的属性是只读的。

方法

Project还有很多方法,可以直接在build.gradle中编写方法,比如上篇文档我们介绍的dependencies {}添加依赖,实际就是调用的Project中的方法,可以直接按住Ctrl+右键点进去,可以看到该方法参数就是一个groovy 闭包。

在这里插入图片描述
常用的方法如下所示:

常用方法使用案例

buildscript{}

buildscript{}的作用是为运行脚本提供依赖或信息支持。

假设要执行一项指令./gradlew buildImage构建docker镜像,而Gradle官方自身没有,则需要依赖到maven库下载或需要调用第三方插件,这时候就需要在buildscript中指定docker的依赖即可。

buildscript {
    repositories {
        mavenLocal()
        maven {
            url "https://maven.aliyun.com/repository/public"
        }
		mavenCentral()
    }
    dependencies {
        classpath "com.bmuschko:gradle-docker-plugin:3.3.4"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:2.6.5"
    }
}

configurations{}

configurations{} 官网的解释是依赖项的分组配置,在上一篇文档中,我们了解到依赖的是有作用范围的,根据不同的configuration划分到不同的分组中。

比如下图示例中,Gradle会从中央存储库下载依赖,然后根据不同的configuration分组将依赖添加到不同的组中,比如分组是implementation则只用于编译源码,testImplementation只用于Test 目录中。
在这里插入图片描述
这些分组配置,是由java 插件提供的,如果去掉改插件,是会报错找不到implementation
在这里插入图片描述
Java 插件为您的项目添加了许多依赖配置:

  • implementation:仅实现依赖项。
  • compileOnly:仅编译时依赖项,不在运行时使用。
  • compileClasspath:继承compileOnly, implementation,编译类路径,编译源码时使用。由任务使用compileJava。
  • annotationProcessor:编译期间使用的注释处理器。
  • runtimeOnly:仅运行时依赖项。
  • runtimeClasspath:继承runtimeOnly, implementation,运行时类路径包含实现的元素,以及仅运行时的元素。
  • testImplementation:继承implementation,仅实现测试的依赖项。
  • testCompileOnly:仅用于编译测试的附加依赖项,不在运行时使用。
  • testCompileClasspath:继承testCompileOnly, testImplementation,测试编译类路径,在编译测试源时使用。由任务使用compileTestJava。
  • testRuntimeOnly:继承runtimeOnly,运行时仅依赖于运行测试。
  • testRuntimeClasspath:继承testRuntimeOnly, testImplementation,用于运行测试的运行时类路径。由任务使用test。
  • archives:该项目产生的工件(例如罐子)。Gradle 使用它来确定构建时要执行的“默认”任务。
  • default:继承runtimeElements,此项目的项目依赖项使用的默认配置。包含此项目在运行时所需的工件和依赖项。

main 源码目录依赖配置如下图所示:
在这里插入图片描述

test 目录依赖配置如下图所示:
在这里插入图片描述

configurations支持继承,比如testImplementation就继承自implementation,如下所示:

在这里插入图片描述

configurations还支持自定义,比如下方案例中,我们定义一个配置分组,然后将该分组的依赖移入到某个文件夹中:

configurations {
    myconf
}
dependencies {
    myconf 'com.alibaba:fastjson:1.2.58'
}
// afterEvaluate:可以添加一个闭包,它会在项目完成评估后立即执行。
// 当执行属于该项目的构建文件时,会通知此类监听器。
afterEvaluate {
    // 打印 myconf 分组的第一个依赖文件
    println configurations.myconf.files.first()
    // 打印路径
    println configurations.myconf.asPath
    // 移入路径
    def libPath = projectDir.absolutePath + "/src/main/lib2"
    // 复制 依赖到 libPath中
    copy {
        from configurations.myconf.files.first()
        into libPath
    }
}

repositories{}

repositories{}用于配置依赖仓库,参考上一篇

dependencies{}

dependencies{}用于配置依赖,参考上一篇

allprojects{}

allprojects{}用于配置项目及其每个子项目所需要的依赖。一般在多模块项目场景下我们会把公共的部分配置在根项目的allprojects中。

如下所示:

allprojects {
    // 配置共用插件
    apply plugin: "idea"
    apply plugin: "id"
    apply plugin: "maven"
    apply plugin: "war"
    apply plugin: "com.bmuschko.docker-remote-api"
    apply plugin: "org.springframework.boot"
    
    // 配置共用存储库
    repositories {
        mavenLocal()
        maven {url "https://maven.aliyun.com/repository/public"}
        mavenCentral()
    }

    // 配置共用依赖
    dependencies {

    }
}

subprojects{}

subprojects{}allprojects{}差不多,但是它只作用于子项目,当前项目则无效

sourceSets{}

sourceSets{} 用于配置此项目的源码集,默认的源码结构如下:
在这里插入图片描述
可以修改源码的结构,但是一般都不会改,如下所示:

sourceSets {
	// 将main.java目录修改,
    main {
        java {
            srcDir 'thirdParty/src/main/java'
        }
    }
}

还可以排除某个文件或目录,如下所示:

plugins {
    id 'java'
}

sourceSets {
  main {
    java {
      exclude 'some/unwanted/package/**'
    }
  }
}

还可以指定源码的输出目录,如下所示:

sourceSets {
	main {
		output.resourcesDir = output.classesDir = '/WEB-INF/classes/'
		java.srcDir('src')
		resources.srcDir('src')
	}
}

artifacts{}

artifacts{}用于配置交付产品组件信息,比如jar 或者war 包都是一个交互产品,具体用法,后面单独介绍。

publishing{}

publishing{}用于发布当前项目到仓库,具体用法,后面单独介绍。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐