Giter VIP home page Giter VIP logo

spring-boot-boilerplate-java's Introduction

Spring Boot 样板项目(使用 Java 与 Maven)

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

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

本项目以容器或云引擎(例: 阿里云 SAE )为部署目标,简化传统的复杂配置,减少更新维护成本。

文件目录结构:

spring-boot-boilerplate-java
│  .editorconfig
│  .gitattributes
│  .gitignore
│  docker-compose.yml
│  Dockerfile
│  LICENSE
│  mvnw
│  mvnw.cmd
│  pom.xml
│  README.adoc
│
├─.mvn
│  └─wrapper
│          maven-wrapper.jar
│          maven-wrapper.properties
│          MavenWrapperDownloader.java
│
├─docs
│  │  Upgrade-Checklist.adoc
│  │
│  ├─logback
│  │      logback-spring.xml.example
│  │      logback-spring.xml.file.example
│  │      logback-spring.xml.jdbc.example
│  │      logback-spring.xml.sls.example
│  │      README.logback.adoc
│  │
│  └─maven
│          settings.xml
│          settings.xml.more-repos.example
│
└─src
    ├─main
    │  ├─java
    │  │  └─com
    │  │      └─example
    │  │          └─demo
    │  │                  DemoApplication.java
    │  │
    │  └─resources
    │      │  application-dev.yml
    │      │  application-prod.yml
    │      │  application.yml
    │      │
    │      ├─static
    │      │      .gitkeep
    │      │
    │      └─templates
    │              .gitkeep
    │
    └─test
        └─java
            └─com
                └─example
                    └─demo
                            DemoApplicationTests.java

项目信息

  • 构建工具:Maven

  • Java 版本:17

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

  • git 行为配置

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

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

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

  • 编辑器行为配置

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

  • Maven Wrapper 使用【阿里云】**大陆的下载地址,改善下载速度

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

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

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

  • 两个项目配置集

    • 两个 Maven Profile: dev, prod

    • 两个 Spring Profile: dev, prod

    • 启用 Maven Profile prod 会自动启用对应的 Spring Profile prod。而 dev 亦然

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

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

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

    • 版本升级清单

    • Logback 日志配置样例

    • Maven 镜像源配置样例

运行指引

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

使用命令行运行

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

    • Git

    • JDK 17 或更高版本

执行命令:

git clone https://github.com/yanwenkun/spring-boot-boilerplate-java.git
cd spring-boot-boilerplate-java
./mvnw clean spring-boot:run

Ctrl + C 可终止运行。

使用 Docker Compose 运行

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

git clone https://github.com/yanwenkun/spring-boot-boilerplate-java.git
cd spring-boot-boilerplate-java
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("dev")

开发环境 Development

运行时 H2 内存数据库

TRACE

INFO

@Profile("prod")

线上测试环境 Testing

测试数据库

DEBUG

INFO

预发环境 Staging

生产数据库

INFO

WARN

生产环境 Production

生产数据库

WARN

ERROR

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

Profile 用法

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

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

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

  • Maven Profile 不关心 Java 代码中的注解,只关心编译资源(依赖项),pom.xml 中对此有举例

以配置集运行

  • 使用 IDE 可以直接切换配置集

  • 默认激活: dev

  • prod 运行:

./mvnw clean spring-boot:run -P prod
  • 如何修改默认配置集:

    • 修改 pom.xml 中的 activeByDefault 属性

    • 注意仅保持 1 个 activeByDefaulttrue

      • Maven 可以同时激活多个 Profile,但 Spring 只允许同时激活一个

  • Dockerfile 已配置为默认使用 prod

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

日志的配置

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

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

  • 如需详细配置 Logback,请参考本项目中的 Spring Logback 日志配置参考

建议:

  • 编写代码时不要用 System.out.println(),而是使用 Slf4j 分等级记录日志

    • 可用等级(从低到高): TRACE DEBUG INFO WARN ERROR

    • Lombok 可以使用 @Slf4j 注解减少代码,但本项目没有引入该依赖

附录一:JDK 的选择

Oracle JDK 的收费背景

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

  • 在 2021 年 9 月发布的 Oracle JDK 17,又可以免费用于生产环境了,但只提供三年支持。三年之后要么升级大版本,要么付费买支持,要么停留在最后的免费版本(不安全)

  • 而完全免费的 Oracle OpenJDK 只更新最新 GA 大版本,每当新的大版本 GA,老版本即停止更新

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

  • 个人建议

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

    • Java 的下一个长期支持版本(LTS)是 21,预计 2023 年 9 月推出,在其广泛可用(GA)之前,建议维持在 Java 17

使用其它提供方的 OpenJDK

考虑以下几点:

  • 开源

  • 有健壮支持

  • 完全免费

推荐如下:

  • Eclipse Temurin

    • 即原先的 AdoptOpenJDK + HotSpot

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

    • 涵盖大版本较广(8、11、16、17、18 …)

    • 老版本(< 16)提供 JRE

  • IBM Semeru

    • 即原先的 AdoptOpenJDK + OpenJ9

    • OpenJ9 是来自 IBM 的开源 JVM,为云环境、容器化优化,内存占用小,提供快速启动选项

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

  • Alibaba Dragonwell

    • 阿里巴巴开源的 OpenJDK

    • 为 LTS 版本提供长期支持

    • 随阿里云的工具链分发

  • Amazon Corretto

    • 亚马逊开源的 OpenJDK

    • 为 LTS 版本提供长期支持

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

附录二:配置集的理解

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

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

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

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

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

Profile 与 Profile 的不同

  • 在本项目中有两种 Profile:

    1. Spring Profile

    2. Maven Profile

  • 两者的实际作用域不同

    • Spring Profile 关心代码与配置项

    • Maven Profile 关心编译与依赖项

  • 为了便于统一管理,本项目中 Spring Profile 和 Maven Profile 共用同一套名称,并通过配置上的绑定,对两者进行了关联

    • 比如,Maven 启用了 prod,Spring 也会启用 prod

    • 但反过来不会

  • 如果配置不当,这两种 Profile 可能会冲突

    • 同一时间只能有一个 Spring Profile 激活

    • 同一时间可以有多个 Maven Profile 激活(在本项目中不推荐这么做)

Profile 的命名

  • devprod 两个命名是 Java 世界中的常见习惯,简洁明了,本项目尊重该习惯

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

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

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

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

某种意义上,这两个 Profile 的含义可以理解为 DEBUGRELEASE,或者 localonline

概念上的简化

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

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

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

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

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

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

更多信息

  • Maven 与 Spring 共用 Profile name 并不是高枕无忧的设计

    • 主要看 Profile 是否与自动化流水线能够流畅配合

  • 如果不需要 Maven 根据环境/阶段管理不同的依赖,可以在 pom.xml 中删除 Profiles 相关定义

    • 如果去掉了 Maven Profiles,可以使用环境变量,使 Spring Boot 程序运行时直接调用不同配置集:

export SPRING_PROFILES_ACTIVE=prod

附录三

版本升级清单

见: 版本升级清单

为什么不默认使用 Lombok

从工程管理的角度出发,Java 项目保持其代码风格的延续是很重要的。而 Lombok 的侵入性,对老项目而言是需要权衡的,请根据团队的意见做出选择。

对于没有历史负担的新项目,可以考虑 Kotlin

使用 Maven 构建 Docker 镜像

在不配置 Maven 插件(即不改动 pom.xml)的前提下,最简单的方法是使用命令行调用 Google Jib:

  • 用法1:构建镜像

./mvnw com.google.cloud.tools:jib-maven-plugin:dockerBuild -Dimage="example/demo:dev"
  • 用法2:构建镜像并推送至仓库(Docker Registry)

./mvnw com.google.cloud.tools:jib-maven-plugin:build -Dimage="example/demo:dev"

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

配置 Maven 使用镜像源

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

  • 不推荐直接在 pom.xml 中配置仓库来源

    • 因为初次构建时还是要从官方源下载包,依然很慢

    • 不利于 CI 的管理

如何配置本地 Maven 使用镜像源:

将【 settings.xml 】复制到【 用户主目录/.m2/ 】下。 或执行命令:

mkdir ~/.m2/
cp docs/maven/settings.xml ~/.m2/

如需 Maven Central 以外的仓库源,请参考【 settings.xml.more-repos.example 】。

许可

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.