玩转Gradle构建工具(五)、多模块构建

296 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

前言

本系列目录

  1. Task
  2. Project、Task常用API
  3. 文件操作
  4. 依赖管理
  5. 多模块构建
  6. 插件编写
  7. SpringBoot插件源码分析
  8. 过度到Kotlin

大型项目都会分模块,就是将代码拆分为多个较小的模块,每个模块都定义与其他模块的依赖关系,各行其责,这也有助于维护代码,在Gradle中使用多模块很简单,要比Maven容易。

一般我们都会使用IDEA创建Gradle项目,这种方式创建的项目结构默认根路径就是主模块,但是使用gradle init这种方法创建的application项目,会引入一个名叫app的模块,Android项目的目录结构就是这样的,这样也挺好,更有层次感,如下。

ls -l
drwxrwxr-x 3 hxl hxl 4096 62 11:47 app
drwxrwxr-x 3 hxl hxl 4096 62 11:46 gradle
-rwxrwxr-x 1 hxl hxl 8070 62 11:46 gradlew
-rw-rw-r-- 1 hxl hxl 2763 62 11:46 gradlew.bat
-rw-rw-r-- 1 hxl hxl  366 62 11:47 settings.gradle

app目录下才会是src/main/java这样标准的开发路径,这也是官方推荐的项目结构,注意,根项目没有build.gradle构建文件(但可以有),只有一个settings.gradle文件,在settings.gradle中你会发现有这么一行,这个表示要引入app这个模块。

include('app')

include

我们新建一个web文件夹,然后在settings.gradle中增加include('web')

include('app')
include('web')

如果成功的话,在IDEA中打开,那么Web模块会变成这个样子的图标,和app一样。

image.png

这时可以通过命令./gradlew -q projects查看这个项目引入了哪些模块。

Root project 'gradle-test'
+--- Project ':app'
\--- Project ':web'

注意,官方称之为multi-project,多项目,但我们更多时候称为多模块,如上app是主模块,web是辅模块。

但是web模块还缺少一些配置才可用,首先需要在web根目录下新建一个build.gradle文件,内容如下。

plugins {
    id 'java'
}
version '1.0'

然后引入一个java插件,表示当前模块是一个java项目,这样后,src下面文件夹才会被识别出来,才会被编译。

每个模块下都需要一个build.gradle文件。

模块依赖。

如果在web模块中编写代码,要在app中使用,那么需要app的build.gradle下需要手动依赖web,如下,否则app中是无法访问web中的类的。

dependencies {
    implementation( project(":web"))
}

父模块配置

但这并不是我们平常的做法,平常做法还需要一个父模块,在父模块中统一配置一些子模块共有的东西。

首先在项目根路径下创建一个build.gradle,内容如下。

subprojects {
    apply plugin: 'java'
    repositories {
        mavenCentral()
    }
    dependencies {
        implementation group: 'com.alibaba', name: 'fastjson', version: '2.0.5'
    }
}

subprojects中的内容都将会应用于所有子模块,在这里,我们做了一个统一对子模块增加java插件、maven的中央仓库、并引入fastjson库的这样一个配置。

执行指定模块task

如下,现在web模块中有这样一个任务。

task taskA{
    doLast {
        println("test")
    }
}

调用时需要指定他所在的模块,但也可以省略。

./gradlew web:taskA

如果需要对这个模块打包的话,如使用SpringBoot的打包插件。

 ./gradlew web:bootJar

动态引入依赖

如果有3个模块,模块A、B都需要引入fastjson,C不需要,这时候可以写if语句判断,当我第一次看到还能这样玩,被Gradle的强大折服。

subprojects {
    apply plugin: 'java'
    repositories {
        mavenCentral()
    }
    dependencies {
       if(name !="C"){
           implementation group: 'com.alibaba', name: 'fastjson', version: '2.0.5'
       }
    }
}