• Gradle系列【4】Project对象


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

    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"))
    
    • 1
    • 2
    • 3

    可以在官网中查看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}"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    属性是有作用域的,读写属性时,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"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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 {
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    subprojects{}

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

    sourceSets{}

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

    sourceSets {
    	// 将main.java目录修改,
        main {
            java {
                srcDir 'thirdParty/src/main/java'
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    plugins {
        id 'java'
    }
    
    sourceSets {
      main {
        java {
          exclude 'some/unwanted/package/**'
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

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

    sourceSets {
    	main {
    		output.resourcesDir = output.classesDir = '/WEB-INF/classes/'
    		java.srcDir('src')
    		resources.srcDir('src')
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    artifacts{}

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

    publishing{}

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

  • 相关阅读:
    计算机操作系统笔记总结
    Docker 安装(方法4):使用二进制文件压缩包安装
    一遍关于vue基础语法上篇
    在UE4虚幻引擎中加入导航网格体边界体积后丧尸不能移动和发现玩家
    SqlServer中去除字段空格及特殊空格/回车/换行等
    【Java八股文总结】之多线程
    028-从零搭建微服务-搜索服务(二)
    音视频入门基础:H.264专题(5)——FFmpeg源码中 解析NALU Header的函数分析
    (附源码)计算机毕业设计Java大学生学科竞赛报名管理系统
    Linux搭建DNS服务
  • 原文地址:https://blog.csdn.net/qq_43437874/article/details/125381747