前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gradle构建多模块SpringBoot应用

Gradle构建多模块SpringBoot应用

原创
作者头像
程序员欣宸
修改2021-09-22 11:14:13
1.2K0
修改2021-09-22 11:14:13
举报
文章被收录于专栏:实战docker实战docker

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

关于本篇

本文是一篇笔记,通过实战将Gradle构建多模块的步骤记录下来,为今后新建的项目准备一个脚手架,该脚手架由两个子模块组成:二方库、SpringBoot应用,本文由以下内容组成:

  1. 新建项目;
  2. 新建二方库模块;
  3. 新建SpringBoot应用模块;
  4. 验证;

环境信息

  1. 操作系统:win10
  2. JDK:1.8.0_181
  3. Gradle:6.8.3
  4. IDEA:2020.2.2 (Ultimate Edition)
  5. Spring Boot:2.4.4

源码下载

名称

链接

备注

项目主页

该项目在GitHub上的主页

git仓库地址(https)

该项目源码的仓库地址,https协议

git仓库地址(ssh)

git@github.com:zq2599/blog_demos.git

该项目源码的仓库地址,ssh协议

  • 这个git项目中有多个文件夹,kubebuilder相关的应用在gradlespringbootdemo文件夹下,如下图红框所示:
    在这里插入图片描述
    在这里插入图片描述

新建项目

  • 新建项目:
    在这里插入图片描述
    在这里插入图片描述
  • 选择新建Gradle项目:
在这里插入图片描述
在这里插入图片描述
  • 设置项目名gradlespringbootdemo、GroupId、ArtifactId:
在这里插入图片描述
在这里插入图片描述
  • 完整的build.gradle内容改为如下:
代码语言:txt
复制
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter

// gradle自身会用到的相关设置
buildscript {
    // 仓库
    repositories {
        // 本地
        mavenLocal()

        // 阿里云
        maven {
            url 'http://maven.aliyun.com/nexus/content/groups/public/'
        }
        // 中央仓库
        mavenCentral()
        // grandle插件
        maven {
            url 'https://plugins.gradle.org/m2/'
        }
    }

    // 子模块会用到的变量
    ext {
        springBootVersion = '2.4.4'
    }
}

// 插件
plugins {
    id 'java'
    id 'java-library'
    // 有这个声明,子模块可以使用org.springframework.boot插件而无需指定版本,但是apply=false表示当前模块不使用此插件
    id 'org.springframework.boot' version "${springBootVersion}" apply false
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

// gradle wrapper指定版本
wrapper {
    gradleVersion = '6.8.3'
}

// 取当前时间
def buildTimeAndDate = OffsetDateTime.now()

// 根据时间生成字符串变量
ext {
    projectVersion = project.version
    buildDate = DateTimeFormatter.ISO_LOCAL_DATE.format(buildTimeAndDate)
    buildTime = DateTimeFormatter.ofPattern('HH:mm:ss.SSSZ').format(buildTimeAndDate)
}

// 针对所有project的配置,包含根项目
allprojects {
    group 'com.bolingcavalry'
    version '1.0-SNAPSHOT'

    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'io.spring.dependency-management'

    // 编译相关参数
    compileJava {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
        options.encoding = 'UTF-8'
        options.compilerArgs =  [
                '-Xlint:all', '-Xlint:-processing'
        ]
    }

    // Copy LICENSE
    tasks.withType(Jar) {
        from(project.rootDir) {
            include 'LICENSE'
            into 'META-INF'
        }
    }

    // 生成jar文件时,MANIFEST.MF的内容如下
    jar {
        manifest {
            attributes(
                    'Created-By': "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})".toString(),
                    'Built-By': 'travis',
                    'Build-Date': buildDate,
                    'Build-Time': buildTime,
                    'Built-OS': "${System.properties['os.name']}",
                    'Specification-Title': project.name,
                    'Specification-Version': project.version,
                    'Specification-Vendor': 'Will Zhao',
                    'Implementation-Title': project.name,
                    'Implementation-Version': project.version,
                    'Implementation-Vendor': 'Will Zhao'
            )
        }
    }

    // 仓库
    repositories {
        // 本地
        mavenLocal()
        // 如果有私服就在此配置,如果没有请注释掉
        maven {
            url 'http://192.168.50.43:8081/repository/aliyun-proxy/'
        }
        // 阿里云
        maven {
            url 'http://maven.aliyun.com/nexus/content/groups/public/'
        }
        // 中央仓库
        mavenCentral()
        // grandle插件
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
}

// 类似maven的dependencyManagement,这里将所有jar的版本指定好,子模块在依赖时可以不用指定版本
allprojects { project ->
    buildscript {
        dependencyManagement {
            imports {
                mavenBom "org.springframework.boot:spring-boot-starter-parent:${springBootVersion}"
                mavenBom "org.junit:junit-bom:5.7.0"
            }

            dependencies {
                dependency 'org.projectlombok:lombok:1.16.16'
                dependency 'org.apache.commons:commons-lang3:3.11'
                dependency 'commons-collections:commons-collections:3.2.2'
                dependency 'net.devh:grpc-server-spring-boot-starter:2.11.0.RELEASE'
            }
        }
    }
}
  • 上述配置中,我使用了自己在局域网搭建的nexus3服务器作为私服,目的是缓存jar库,局域网内的速度还是要比阿里云快一些的,如果您没有搭建此类私服,将此配置删除即可(我这里是http://192.168.50.43:8081/repository/aliyun-proxy/);
  • 现在父工程已经设置完成,可以添加子模块了;

新增二方库子模块

  • 二方库是常用功能,A系统调用B系统服务时,通常要求B系统提供二方库,里面包含了数据结构和接口定义,这样双方的数据结构和接口都能对齐了,因此咱们来创建一个二方库子模块,里面包含了数据结构和接口;
  • 新增Module:
在这里插入图片描述
在这里插入图片描述
  • 新增module时,依旧是选中Gradle、JDK1.8、Java:
在这里插入图片描述
在这里插入图片描述
  • 模块名为democlient
在这里插入图片描述
在这里插入图片描述
  • 新增的模块内也有build.gradle文件,将里面内容清空后写为以下内容:
代码语言:txt
复制
// 构建二方库的插件
plugins {
    id 'java-library'
}

// 这里可以指定构建出来的jar的文件名
archivesBaseName = 'demo-client'

// 子模块自己的依赖
dependencies {
    // 使用api,将依赖传递给使用democlient的模块
    api 'org.projectlombok:lombok'
    // annotationProcessor不会传递,使用了lombok生成代码的模块,需要自己声明annotationProcessor
    annotationProcessor 'org.projectlombok:lombok'
}
  • democlient模块增加一个类,其他模块会用到此类:
代码语言:txt
复制
package com.bolingcavalry.dto;

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
@Builder
public class Student {
    String name;
    int age;
}
  • democlient模块编码完成了,试试构建任务,操作如下图:
在这里插入图片描述
在这里插入图片描述
  • 构建完成后生成下图红框中的jar文件:
在这里插入图片描述
在这里插入图片描述
  • 用解压工具解开上图红框中的文件,除了预料之中的class文件,再来检查META-INF/MANIFEST.MF,如下图所示,是咱们在前面的gradle脚本中定制的内容:
在这里插入图片描述
在这里插入图片描述

新增SpringBoot应用模块

接下来要创建的是一个SpringBoot应用,并且使用了democlient模块中的Student类;

  • 新建Gradle模块:
在这里插入图片描述
在这里插入图片描述
  • 基本信息如下:
在这里插入图片描述
在这里插入图片描述
  • 新模块的build.gradle内容如下,有几处要注意的地方稍后会讲到:
代码语言:txt
复制
plugins {
    id 'org.springframework.boot'
}

// 用了插件org.springframework.boot之后,jar task会失效,可用bootJar取代
bootJar {
    archiveBaseName = project.name
    archiveVersion = project.version

    manifest {
        attributes(
                'Created-By': "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})".toString(),
                'Built-By': 'travis',
                'Build-Date': buildDate,
                'Build-Time': buildTime,
                'Built-OS': "${System.properties['os.name']}",
                'Specification-Title': project.name,
                'Specification-Version': projectVersion,
                'Specification-Vendor': 'Will Zhao',
                'Implementation-Title': project.name,
                'Implementation-Version': projectVersion,
                'Implementation-Vendor': 'Will Zhao'
        )
    }
}

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

// 子模块自己的依赖
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // 二方库依赖
    implementation project(':democlient')
    // annotationProcessor不会传递,使用了lombok生成代码的模块,需要自己声明annotationProcessor
    annotationProcessor 'org.projectlombok:lombok'

}

test {
    useJUnitPlatform()
}
  • 上述脚本中需要有以下四点需要注意: a. 要使用springboot的插件org.springframework.boot,此处无需指定版本,因为根模块中已通过mavenBom导入了版本依赖关系; b. jar{...}的配置会失效,如果想设置jar的一些信息,如文件名、manifest等,要使用bootJar配置; c. 依赖了democlient模块,这是典型的二方库开发和使用方式; d. 稍后的java代码中会实例化Student对象,此时用到lombok生成的代码,因此要用annotationProcessor依赖lombok库,否则编译会出问题;
  • 最后新建一个启动类DemoApplication,用于验证springboot应用能否正常启动,代码中有使用Student类,这是为了验证使用二方库是否正常:
代码语言:txt
复制
package com.bolingcavalry;

import com.bolingcavalry.dto.Student;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@SpringBootApplication
@RestController
public class DemoApplication {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "Hello "
                + new Date()
                + "--"
                + new Student("Tom", 11);
    }


    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  • 运行应用试试,操作如下图红框:
在这里插入图片描述
在这里插入图片描述
  • 符合预期:
在这里插入图片描述
在这里插入图片描述
  • 再验证打包成jar是否正常,先停掉前面启动的应用,然后操作如下图红框:
在这里插入图片描述
在这里插入图片描述
  • 已生成jar文件:
在这里插入图片描述
在这里插入图片描述
  • 在jar文件所在目录执行命令java -jar webapp-1.0-SNAPSHOT.jar,启动应用正常:
在这里插入图片描述
在这里插入图片描述
  • 至此,多模块Gradle项目开发就完成了,如果您正在新建此类项目,希望本文能给您提供一些参考;

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢迎关注公众号:程序员欣宸

微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 欢迎访问我的GitHub
  • 关于本篇
  • 环境信息
  • 源码下载
  • 新建项目
  • 新增二方库子模块
  • 新增SpringBoot应用模块
  • 你不孤单,欣宸原创一路相伴
  • 欢迎关注公众号:程序员欣宸
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档