Gradle Kotlin DSL 多模块项目案例

版本信息

ide: idea2020.1
jdk: openjdk8
gradle: 6.8.3

搭建项目

  1. 新建 Gradle 项目
    Gradle Kotlin DSL 多模块项目案例
    选择 gradle,勾选 Kotlin DSL构建脚本,最后下一步:
    Gradle Kotlin DSL 多模块项目案例
    自定义项目的名称、groupId、artifactId和version:
    Gradle Kotlin DSL 多模块项目案例
    项目初始结构:
    Gradle Kotlin DSL 多模块项目案例

  2. 修改 settings.gradle.kts 文件

rootProject.name = "module-demo"

// 遍历子项目,将子项目的依赖配置脚本的名称进行自定义(可以不自定义)
rootProject.children.forEach { project ->
    project.buildFileName = "${project.name}.gradle.kts"
    // 三层结构的多模块项目会需要,如果只有两层,去掉此处循环即可
    project.children.forEach { p ->
        p.buildFileName = "${p.name}.gradle.kts"
    }
}
  1. 修改 build.gradle.kts 文件
plugins {
    // 使用此插件管理依赖
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
}

group = "com.ninaco"
version = "1.0-SNAPSHOT"
description = "聚合工程 - 父工程"

// 所有项目都有的配置
allprojects {
    repositories {
        mavenLocal()
        maven("https://maven.aliyun.com/nexus/content/repositories/google")
        maven("https://maven.aliyun.com/nexus/content/groups/public")
        maven("https://maven.aliyun.com/nexus/content/repositories/jcenter")
        maven("https://plugins.gradle.org/m2/")
        mavenCentral()
    }
}

// 定义依赖的版本
var cloudVersion = "2021.0.0"
var cloudAlibabaVersion = "2.2.6.RELEASE"
var mybatisPlusVersion = "3.5.0"
var velocityVersion = "2.3"

// 子项目(子模块)的配置
subprojects {
    apply {
        plugin("io.spring.dependency-management")
        plugin("java-library")
    }

    group = "com.ninaco"
    version = "1.0.0"

    // 依赖管理,此功能是插件 io.spring.dependency-management 提供的,类似于 maven dependencyManagement 功能
    dependencyManagement {
        // 导入pom,类似于 Maven 中的 scope=import
        imports {
            mavenBom("org.springframework.cloud:spring-cloud-dependencies:${cloudVersion}")
            mavenBom("com.alibaba.cloud:spring-cloud-alibaba-dependencies:${cloudAlibabaVersion}")
        }

        // 定义依赖(此处定义的依赖,在子模块中无需定义版本)
        dependencies {
            dependency("com.baomidou:mybatis-plus-boot-starter:${mybatisPlusVersion}")
            dependency("org.apache.velocity:velocity-engine-core:${velocityVersion}")
        }

        // 生成自定义的Pom
        generatedPomCustomization {
            enabled(false)
        }

        // 解决方案策略
        resolutionStrategy {
            cacheChangingModulesFor(0, TimeUnit.SECONDS)
        }
    }

}
  1. 新建子模块
    在当前模块下新建文件夹 common,并在 common 文件夹下新建文件 common.gradle.kts :
    Gradle Kotlin DSL 多模块项目案例
    settings.gradle.kts 中新增代码:
rootProject.name = "module-demo"

// 包含 common 子模块(不需要添加 .gradle.kts 后缀)
include("common")

// 遍历子项目,将子项目的依赖配置脚本的名称进行自定义
rootProject.children.forEach { project ->
    project.buildFileName = "${project.name}.gradle.kts"
    // 三层接口的多模块项目会需要,如果只有两层,去掉此处循环即可
    project.children.forEach { p ->
        p.buildFileName = "${p.name}.gradle.kts"
    }
}

更新 gradle 项目,依赖生效

  1. 测试子模块
    在子模块中添加 build.gradle.kts 中定义的依赖:
description = "common 模块"

plugins {
    `java-library`
}

tasks.withType<Jar> {
    enabled = true
}

dependencies {
    // implementation 只能在当前模块使用的依赖
    implementation("org.apache.velocity:velocity-engine-core")
    // api 可以传递给引用当前模块的项目使用的依赖(api 是在 java-library 插件中的方法)
    // api("org.apache.velocity:velocity-engine-core")
}

可以在idea右侧的 Gradle 视图中查看依赖是否添加:
Gradle Kotlin DSL 多模块项目案例
新建目录:src/main/java:
Gradle Kotlin DSL 多模块项目案例
Gradle Kotlin DSL 多模块项目案例
在新建一个Main类,添加主函数入口 main 方法:
Gradle Kotlin DSL 多模块项目案例
Gradle Kotlin DSL 多模块项目案例

  1. 新建子子模块
    删除src目录,并在 common 下新增目录 common-sub,并在 common-sub 下新增 common-sub.gradle.kts:
    Gradle Kotlin DSL 多模块项目案例
    修改 settings.gradle.kts:
rootProject.name = "module-demo"

include("common")
include(":common:common-sub")

// 遍历子项目,将子项目的依赖配置脚本的名称进行自定义
rootProject.children.forEach { project ->
    project.buildFileName = "${project.name}.gradle.kts"
    // 三层接口的多模块项目会需要,如果只有两层,去掉此处循环即可
    project.children.forEach { p ->
        p.buildFileName = "${p.name}.gradle.kts"
    }
}

此时子子模块创建完成,其他使用方式和子模块一致:
Gradle Kotlin DSL 多模块项目案例

  1. 子模块和子子模块的引用
    新建 service 模块,方式和上面模块新建方式一致。修改 service.gradle.kts 脚本:
description = "service 模块"

plugins {
    java
}

dependencies {
    // 引用子模块
    implementation(project(":common"))
    // 引用子子模块
    implementation(project(":common:common-sub"))
}

Gradle Kotlin DSL 多模块项目案例

打包的一些问题

如果你要使用 springboot 相关的框架,可以使用spring官方提供的插件 org.springframework.boot 配合 io.spring.dependency-management 插件使用,打包jar包时,需要打包成jar包的项目,比如 common-sub 项目需要添加如下的配置,不然可能会出现在ide上运行没有问题,但是打包出来却缺少了对应的 common-sub.jar 包:

tasks.withType<Jar> {
	enabled = true
}

Gradle Kotlin DSL 多模块项目案例

注意:使用 springboot 时,打包jar包使用 bootJar 任务进行打包,不然可能会无法运行


如果不是 springboot 项目,不使用插件 org.springframework.boot,那么推荐使用插件 com.github.johnrengelman.shadow 来进行打包 jar 包

注意:使用 shadowJar 插件时,打包jar包使用 shadowJar 任务进行打包

如下案例:

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

description = "子子模块 common-sub"

plugins {
    java
    id("com.github.johnrengelman.shadow") version "5.1.0"
}

dependencies {
    implementation("org.apache.velocity:velocity-engine-core")
}

tasks.named<ShadowJar>("shadowJar") {
    archiveBaseName.set("shadow")
    mergeServiceFiles()
    manifest {
        attributes(mapOf("Main-Class" to "com.ninaco.Main"))
    }
}

tasks {
    build {
        dependsOn(shadowJar)
    }
}
上一篇:CTF-Crypto:hill的秘密


下一篇:vue3中动态引入BMap