/spring-boot-boilerplate-kotlin

Spring Boot 样板项目(使用 Kotlin 与 Gradle)

Primary LanguageKotlinApache License 2.0Apache-2.0

Spring Boot 样板项目(使用 Kotlin 与 Gradle)

本样板项目基于 Spring 官方的 Spring Initializr 生成的 Spring Boot 项目, 并添加一些实用的常见配置,便于在新项目启动时“简单修改即可复用”。

与姊妹项目 Spring Boot 样板项目(使用 Java 与 Maven) 不同的是,本项目假定用户已使用较新的工具链,因而不再保留一些传统设置,项目内容更为精简。

同时,本项目也将不断跟进上游最新版本,以便下游项目一站式更新。

文件目录结构:

spring-boot-boilerplate-kotlin
│  .editorconfig
│  .gitattributes
│  .gitignore
│  build.gradle.kts
│  docker-compose.yml
│  Dockerfile
│  gradlew
│  gradlew.bat
│  LICENSE
│  README.adoc
│  settings.gradle.kts
│
├─docs
│  │  Upgrade-Checklist.adoc
│  │
│  └─Gradle
│          mirrors.init.gradle.kts
│
├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties
│
└─src
    ├─main
    │  ├─kotlin
    │  │  └─com
    │  │      └─example
    │  │          └─demo
    │  │                  DemoApplication.kt
    │  │
    │  └─resources
    │      │  application-DEBUG.yml
    │      │  application-RELEASE.yml
    │      │  application.yml
    │      │
    │      └─static
    │              .gitkeep
    │
    └─test
        └─kotlin
            └─com
                └─example
                    └─demo
                            DemoApplicationTests.kt

项目信息

  • Kotlin 与 Gradle Wrapper 均使用最新正式版本

与姊妹项目 Spring Boot 样板项目(使用 Java 与 Maven) 相比,有如下变动:

  • Profile 命名取 DEBUGRELEASE

  • 去除 Maven 配置样例

  • 去除 Logback 样例

Spring Initializr 生成的 Spring Boot 项目相比,有如下变动:

  • git 行为配置

    • 一个通用的 .gitignore 文件(规定 git 自动忽略哪些文件)

    • 一个通用的 .gitattributes 文件(规定 git 对文本格式的处理)

    • 为空目录添加 .gitkeep 文件(0字节,仅占位,避免空目录被忽略)

  • 编辑器行为配置

    • .editorconfig 文件来规范字符编码、行尾、文件末尾、缩进格式等

  • Gradle Wrapper 的 CDN 在**大陆已经很快了,因此没有单独配置

  • 包含一个基本的 README.adoc 自述文件,以便参考 AsciiDoc 语法

    • AsciiDoc 兼容 Markdown 语法,可在 adoc 中直接写 Markdown

  • 配置文件使用 YAML 格式( application.yml 取代 application.properties

  • 两个项目配置集

    • 两个 Spring Profile: DEBUG, RELEASE

      • 注意:本项目中仅包含 Spring Profile

  • Docker 描述文件(Dockerfiledocker-compose.yml

    • 参照官方最佳实践,使用多段构建

  • docs 目录下附带若干帮助文件

    • 版本升级清单

    • Gradle 镜像源配置样例

运行指引

  • 如果你使用 IDEA / Spring Tool Suite,直接运行项目即可。

使用命令行运行

  • 如果你不想使用 IDE,可以用命令行的方式运行 Spring Boot 项目,你需要先在本地安装:

    • Git

    • JDK 11 或更高版本

执行命令:

git clone https://github.com/yanwenkun/spring-boot-boilerplate-kotlin.git
cd spring-boot-boilerplate-kotlin
./gradlew clean bootRun

Ctrl + C 可终止运行

使用 Docker Compose 运行

如果你安装有 Docker Desktop,直接运行以下命令,即可构建镜像并运行容器:

docker-compose up --build

Ctrl + C 可终止运行。

修改成你的项目

  1. 全局搜索 DemoApplication ,并替换为你的程序名称,比如 SampleApplication (建议保留 Application 后缀)

  2. 全局搜索 com.example.demo ,并替换为你的软件包名称,比如 fun.yanwenkun.sample

  3. 全局搜索 com.example ,并替换为你的组织名称,比如 fun.yanwenkun

  4. 修改 pom.xml 中的软件制品信息(GAV),并管理你的依赖项

  5. 修改代码文件对应的路径、文件名(可通过 IDE 的重构功能完成)

  6. 修改 docker-compose.yml 中的容器与镜像名称

配置集的使用

Table 1. 配置集与运行环境样板
启用配置集 运行环境 数据源 日志级别(业务) 日志级别(框架)

@Profile("DEBUG")

开发环境 Development

运行时 H2 内存数据库

TRACE

INFO

@Profile("RELEASE")

线上测试环境 Testing

测试数据库

DEBUG

INFO

预发环境 Staging

生产数据库

INFO

WARN

生产环境 Production

生产数据库

WARN

ERROR

在实际生产中,该表会更为复杂,但原则不变:使问题尽早暴露、尽早解决。
从脱离本地开发环境开始,所有代码与依赖项均应与生产环境一致,仅配置不同。

Gradle 有其灵活的构建方式,不需要对应 Maven Profile 的使用习惯。因此本项目实际只有一套 Spring Profile,勿混淆。

Profile 用法

  • Spring Profile 在 Java/Kotlin 代码中的用法:

    • 使用Spring注解: @Profile("DEBUG")

    • 未标 @Profile 注解的代码段,均与配置集无关

指定配置集

注意:同一时间只能有一个 Spring Profile 激活

  • 方法1:运行时指定参数

java -jar demo.jar --spring.profiles.active=DEBUG
  • 方法2:修改 application.yaml 中的 spring:profiles:active 属性

  • 方法3:使用环境变量,使 Spring Boot 程序运行时直接调用不同配置集:

export SPRING_PROFILES_ACTIVE=RELEASE
  • Dockerfile 已配置为默认使用 RELEASE

  • 编译服务如 Jenkins 应配置相关参数,代码仓库本身应面向开发者

日志的配置

  • 容器环境下,日志输出到 STDOUT(标准输出、命令行输出)即可,由容器管理日志的收集

  • 程序只需要配置日志输出等级,修改 application-{$profile}.yml 即可

附录一:JDK 的选择

Oracle JDK 的收费背景

  • 在以往几乎完全免费的 Oracle JDK ,从2019年开始,只对开发、个人使用免费,用于生产环境需要付费

  • Oracle OpenJDK 只更新最新 GA 大版本,每当新的大版本 GA,老版本即停止更新

    • Oracle 这么做是为了鼓励开发者跟进新版本,同时也扩大老版本的维护收费

  • 个人建议

    • 对于企业开发,“追新”是为了保持先进、与主流同步,“追最新”则容易踩坑、增加成本。正所谓“领先一步是先驱,领先两步是先烈” :-)

    • Java 的下一个长期支持版本(LTS)是 17,在其广泛可用(GA)之前,建议维持在 Java 11

使用其它提供方的 OpenJDK

考虑以下几点:

  • 开源

  • 有健壮支持

  • 完全免费

推荐如下:

  • AdoptOpenJDK

    • 来自 Java 社区重要成员支持的 OpenJDK

    • 目前涵盖 8 ~ 13 所有大版本

    • 除了 JDK 之外,每个版本还提供 JRE

    • 除了 HotSpot JVM 之外,还提供 OpenJ9 JVM (来自 IBM 开源的 JVM,为云环境、容器化优化,内存占用小,提供快速启动选项)

    • OpenJ9 可选择 Large Heap 预配置版本(堆内存 > 57 GiB),该配置以更大内存占用为代价,提高吞吐与响应,大幅减少 GC 时的暂停时间

  • Alibaba Dragonwell

    • 阿里巴巴开源的 OpenJDK

    • 目前版本只有 8,即将发布 11

    • 目前只支持 Linux x86-64

  • Amazon Corretto

    • 亚马逊开源的 OpenJDK

    • 811 提供长期支持

如果你感到选择困难,请使用 AdoptOpenJDK11+HotSpot ,它的兼容性最佳。

附录二:配置集的理解

  • Profile 直译即“档案”,此处理解为配置、配置集

  • 配置集包含:配置项 + 专有依赖 + 专有代码

  • 对于代码本身,为避免过度复杂,仅使用 2 个配置集:

    • 开发阶段专有代码: @Profile("DEBUG")

    • 生产阶段专有代码: @Profile("RELEASE")

Profile 的命名

  • DEBUGRELEASE 两个命名源自 Android 开发惯例(Kotlin 与 Gradle 的重要领域),同时也是 C# / .NET 的默认命名方式

  • Profile 命名并无绝对标准,比如 Spring 官方文档 中就使用了 devstagingproduction 作为例子

  • 为了避免开发者误解“Profile”与“运行环境”之间的关系,本项目仅使用 DEBUGRELEASE 这两个 Profile

    • DEBUG 仅在开发环境有效,脱离开发环境即开始使用 RELEASE,使潜在问题尽早暴露

实际上,在高度 CI/CD 化之后,开发者不需要过多关心运行环境,而是应该精简配置、写好配置样板,供运维在不同阶段灵活部署。

概念上的简化

  • 开发(本地编码)、验证(各类测试)、生产(发布上线):

    1. 既是软件生命周期中的“阶段”

    2. 也是运维与服务治理中的“环境”

  • 分得过于详细,有过度设计之虞,概念越多越容易出错

  • 作为“偷懒”的做法,将阶段和环境合为一谈,主要目的在于减少心智负担

    • 但扩大开发规模的时候,还是要注意概念上的区分

附录三

版本升级清单

见: 版本升级清单

使用 Gradle 构建 Docker 镜像

首先配置 Gradle 插件(Google Cloud Tools Jib):

build.gradle.kts
plugins {
    // Google Jib 插件,用于快速构建容器镜像并发布
    id("com.google.cloud.tools.jib") version "2.0.0"
}
  • 用法1:构建镜像

./gradlew jibDockerBuild --image=example.com/demo:kotlin
  • 用法2:构建镜像并推送至仓库(Docker Registry)

./gradlew jib --image=example.com/demo:kotlin

注意修改镜像与标签名称 example.com/demo:kotlin
推送至仓库前需要先登录(docker login)。

配置 Gradle 使用 Maven 镜像源

在**大陆访问 Maven 官方源一般会很慢,建议使用镜像源。

  • 不推荐直接在 build.gradle.kts 中配置仓库来源

    • 如果是开源项目,会影响身处国外的开发者

    • 不利于 CI 的管理

如何为本地 Gradle 全局配置 Maven 镜像源:

将【 mirrors.init.gradle.kts 】复制到【 用户主目录/.gradle/init.d/ 】下。 或执行命令:

mkdir ~/.gradle/init.d/
cp docs/Gradle/mirrors.init.gradle.kts ~/.gradle/init.d/

该配置对运行在本地的 Gradle、Gradle Wrapper 均有效。

许可

本项目使用与 Spring Boot 一致的 Apache License 2.0 许可。