Gradle + Spring 统一依赖版本实践

项目环境

IntelliJ IDEA 2023.2.5 (Ultimate Edition)
OpenJDK 8
Gradle 7.6.3
PostgreSQL 15

新建项目

image

项目配置

修改 settings.gradle.kts 文件

修改 settings.gradle.tks 文件支持多模块

pluginManagement {
    repositories {
        maven("https://plugins.gradle.org/m2/")
        gradlePluginPortal()
    }
}

rootProject.name = "ops-demo"

rootProject.children.forEach { project ->
    project.buildFileName = "${project.name}.gradle.kts"
    project.children.forEach { p ->
        p.buildFileName = "${p.name}.gradle.kts"
    }
}

修改 build.gradle.kts 文件

plugins {
    `maven-publish`
    `java-library`
    java
    id("org.springframework.boot") version "2.7.18"
    id("io.spring.dependency-management") version "1.1.4"
}

val modules by extra(subprojects.filter { !it.name.endsWith("mvndm") && !it.name.endsWith("bom") && !it.name.endsWith("app") })
val mvndm by extra(subprojects.filter { it.name.endsWith("mvndm") || it.name.endsWith("bom") })
val app by extra(subprojects.filter { it.name.endsWith("app") })

configure(allprojects) {
    group = "com.ops.demo"
    version = "1.0.0"

    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://mirrors.huaweicloud.com/repository/maven")
        maven("https://mirrors.cloud.tencent.com/nexus/repository/maven-public")
        maven("https://plugins.gradle.org/m2/")
        mavenCentral()
        gradlePluginPortal()
    }

    configurations.all {
        resolutionStrategy {
            cacheChangingModulesFor(0, TimeUnit.SECONDS)
            cacheDynamicVersionsFor(0, TimeUnit.SECONDS)
        }
    }
}

configure(modules) {
    apply(plugin = "maven-publish")
    apply(plugin = "java-library")
    java {
        targetCompatibility = JavaVersion.VERSION_1_8
        sourceCompatibility = JavaVersion.VERSION_1_8
    }
    dependencies {
        api(platform(project(":ops-mvndm")))
        // lombok
        annotationProcessor("org.projectlombok:lombok:1.18.30")
        compileOnly("org.projectlombok:lombok:1.18.30")
        testAnnotationProcessor("org.projectlombok:lombok:1.18.30")
        testCompileOnly("org.projectlombok:lombok:1.18.30")
        // Hutool
        implementation("cn.hutool:hutool-all")
        // FastJson
        implementation("com.alibaba.fastjson2:fastjson2")
    }
    configurations {
        compileOnly {
            extendsFrom(configurations.annotationProcessor.get())
        }
    }

    val javadocJar by tasks.registering(Jar::class) {
        archiveClassifier.set("javadoc")
    }
    val sourceJar by tasks.registering(Jar::class) {
        from(sourceSets["main"].allSource)
        archiveClassifier.set("sources")
    }
    publishing {
        publications {
            create<MavenPublication>("lib") {
                groupId = this@configure.group.toString()
                artifactId = this@configure.name
                version = this@configure.version.toString()
                from(components.getByName("java"))

                artifact(javadocJar)
                artifact(sourceJar)
            }
        }

        // 不配置默认是环境变量中配置的 M2_HOME 的 settings.xml 中配置的路径
        repositories {
            // 环境变量中配置的 M2_HOME 的 settings.xml 中配置的路径。梅有默认 USER_HOME/.m2/repository
            mavenLocal()
//            maven {
//                // 凭证
//                credentials {
//                    username = "username"
//                    password = "password"
//                }
//                // 地址
//                setUrl("https://xx.xx.xx/xxxx/xxx")
//            }
        }
    }

}

configure(mvndm) {
    apply {
        plugin("maven-publish")
    }
}

configure(app) {
    subprojects {
        apply {
            plugin("java")
            plugin("maven-publish")
            plugin("java-library")
            plugin("org.springframework.boot")
            plugin("io.spring.dependency-management")
        }

        java {
            sourceCompatibility = JavaVersion.VERSION_1_8
            targetCompatibility = JavaVersion.VERSION_1_8
        }

        dependencies {
            api(platform(project(":ops-mvndm")))
            implementation(project(":ops-common"))
            // lombok
            annotationProcessor("org.projectlombok:lombok:1.18.30")
            compileOnly("org.projectlombok:lombok:1.18.30")
            testAnnotationProcessor("org.projectlombok:lombok:1.18.30")
            testCompileOnly("org.projectlombok:lombok:1.18.30")
            // Hutool
            implementation("cn.hutool:hutool-all")
            // FastJson
            implementation("com.alibaba.fastjson2:fastjson2")
        }

        configurations {
            compileOnly {
                extendsFrom(configurations.annotationProcessor.get())
            }
        }
    }

}

依赖版本控制模块

  1. 新建模块文件夹 ops-mvndm
    image
  2. 创建模块配置文件ops-mvndm.gradle.kts,并配置ops-mvndm模块
description = "统一依赖版本定义"

plugins {
    `java-platform`
}

javaPlatform {
    allowDependencies()
}

extra.set("springBootVersion", "2.7.18")
extra.set("springCloudVersion", "2021.0.8")
extra.set("springCloudAlibabaVersion", "2021.1")
extra.set("dubboVersion", "3.2.8")
extra.set("knife4jVersion", "4.3.0")
extra.set("lombokVersion", "1.18.30")
extra.set("hutoolVersion", "5.8.23")
extra.set("fastjson2Version", "2.0.42")
extra.set("okhttpVersion", "4.12.0")
extra.set("easyExcelVersion", "3.3.2")
extra.set("mysqlVersion", "8.0.33")
extra.set("lombokVersion", "1.18.30")
extra.set("mybatisPlusVersion", "3.5.3.2")
extra.set("jodaTimeVersion", "2.12.5")
extra.set("xxlJobVersion", "2.4.0")
extra.set("springdocVersion", "1.7.0")
extra.set("postgresqlVersion", "42.7.0")
extra.set("mybatisFlexVersion", "1.7.5")
extra.set("mybatisFlexKotlinVersion", "1.0.3")
extra.set("hikariVersion", "4.0.3")
extra.set("mybatisTypeHandlersVersion", "1.0.2")

dependencies {
    api(platform("org.springframework.boot:spring-boot-dependencies:${project.ext["springBootVersion"]}"))
    api(platform("org.springframework.cloud:spring-cloud-dependencies:${project.ext["springCloudVersion"]}"))
    api(platform("com.alibaba.cloud:spring-cloud-alibaba-dependencies:${project.ext["springCloudAlibabaVersion"]}"))
    api(platform("org.apache.dubbo:dubbo-bom:${project.ext["dubboVersion"]}"))
    api(platform("org.apache.dubbo:dubbo-dependencies-zookeeper-curator5:${project.ext["dubboVersion"]}"))
    api(platform("com.github.xiaoymin:knife4j-dependencies:${project.ext["knife4jVersion"]}"))
    api(platform("com.mybatis-flex:mybatis-flex-dependencies:${project.ext["mybatisFlexVersion"]}"))
    constraints {
        api("cn.hutool:hutool-all:${project.ext["hutoolVersion"]}")
        api("com.alibaba.fastjson2:fastjson2:${project.ext["fastjson2Version"]}")
        api("com.squareup.okhttp3:okhttp:${project.ext["okhttpVersion"]}")
        api("com.alibaba:easyexcel:${project.ext["easyExcelVersion"]}")
        api("com.mysql:mysql-connector-j:${project.ext["mysqlVersion"]}")
        api("org.projectlombok:lombok:${project.ext["lombokVersion"]}")
        api("com.baomidou:mybatis-plus-boot-starter:${project.ext["mybatisPlusVersion"]}")
        api("joda-time:joda-time:${project.ext["jodaTimeVersion"]}")
        api("com.xuxueli:xxl-job-core:${project.ext["xxlJobVersion"]}")
        api("org.springdoc:springdoc-openapi-ui:${project.ext["springdocVersion"]}")
        runtime("org.postgresql:postgresql:${project.ext["postgresqlVersion"]}")
        api("com.zaxxer:HikariCP:${project.ext["hikariVersion"]}")
        api("com.mybatis-flex:mybatis-flex-kotlin-extensions:${project.ext["mybatisFlexKotlinVersion"]}")
        api("com.mybatis-flex:mybatis-flex-processor:${project.ext["mybatisFlexVersion"]}")
        api("org.mybatis:mybatis-typehandlers-jsr310:${project.ext["mybatisTypeHandlersVersion"]}")
    }
}

publishing {
    publications {
        create<MavenPublication>("bom") {
            groupId = "${project.group}"
            artifactId = "${project.name}-bom"
            version = "${project.version}"
            from(components.getByName("javaPlatform"))

            pom {
                packaging = "pom"
                name.set("${project.name}-bom")
                description.set("BOM 依赖版本定义")

                developers {
                    developer {
                        name.set("Anbuis")
                        email.set("1577123083@qq.com")
                        roles.set(listOf("Java Development Engineer", "Kotlin Development Engineer"))
                    }
                }
            }
        }
    }
}

此时,ops-mvndm模块下会新增发布依赖版本定义的bom类型的pom文件的gradle task。执性该任务会在maven仓库中生成pom类型的bom文件,此文件可以给maven项目使用。
到此,一个功能上类似maven父工程的项目就搭建好了。

创建公共模块

创建 ops-common 公共模块:
image
修改其项目配置文件 ops-common.gradle.kts:

description = "公共模块"

// 此时不需要定义依赖版本
dependencies {
    // SpringDoc Swagger Annotation
    api("io.swagger.core.v3:swagger-annotations")
    // mybatis-flex-core 核心包
    api("com.mybatis-flex:mybatis-flex-core")
    // mybatis-flex-spring
    api("com.mybatis-flex:mybatis-flex-spring")
    // Spring Data Commons
    api("org.springframework.data:spring-data-commons")
}

定义统一返回结构 ApiResponse

package com.ops.demo.common.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author a1517
 * @since 2023-12-31 11:56:48
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "统一返回结果", description = "统一返回结果")
public class ApiResponse<T> implements Serializable {

    @Schema(description = "返回代码")
    private Integer code;

    @Schema(description = "返回信息")
    private String message;

    @Schema(description = "返回数据")
    private T data;

    @Schema(description = "是否成功 0 是成功,其他的都是失败")
    public boolean isSuccess() {
        return code == 0;
    }

    public static <T> ApiResponse<T> build(Integer code, String message, T data) {
        return ApiResponse.<T>builder()
                .code(code)
                .message(message)
                .data(data)
                .build();
    }

    public static <T> ApiResponse<T> build(ApiResponseCode responseCode, T data) {
        return build(responseCode.getCode(), responseCode.getMessage(), data);
    }

    public static <T> ApiResponse<T> ok(T data) {
        return build(BaseApiResponseCode.OPS_SUCCESS, data);
    }

    public static <T> ApiResponse<T> ok() {
        BaseApiResponseCode opsSuccess = BaseApiResponseCode.OPS_SUCCESS;
        return ApiResponse.<T>builder()
                .code(opsSuccess.getCode())
                .message(opsSuccess.getMessage())
                .build();
    }

    public static <T> ApiResponse<T> error(Integer code, String message) {
        return ApiResponse.<T>builder()
                .code(code)
                .message(message)
                .build();
    }

    public static <T> ApiResponse<T> error(ApiResponseCode responseCode) {
        return error(responseCode.getCode(), responseCode.getMessage());
    }

}

创建 APP 模块

创建 ops-ucenter-app 模块

image

修改 ops-ucenter-app 模块的配置:

description = "用户中心"

创建ops-ucenter-app的子模块 ops-ucenter-app-api:

image

修改 ops-ucenter-app-api 模块的配置:

description = "用户中心API模块"

dependencies {
    api(project(":ops-common"))
    api("com.mybatis-flex:mybatis-flex-core")
}

tasks.bootJar {
    enabled = false
}

tasks.jar {
    enabled = true
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

以上就是一个比较简单的多模块版本统一结构的设置。

代码地址

https://github.com/anbuis/ops-demo

posted @   疑问号?  阅读(468)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示