Banner 自定义
一句话定位:Spring Boot 启动时的 ASCII Banner 可通过
banner.txt文件和内置占位符进行自定义,也可通过spring.main.banner-mode配置完全关闭,是应用品牌标识和环境区分的第一个展示窗口。
定义与作用
Spring Boot 应用启动时,控制台默认会打印 Spring Logo ASCII 艺术和版本号(:: Spring Boot :: (v2.7.18))。这是 Spring Boot 的标志性视觉元素,但在企业环境中存在两个现实需求:
- 品牌替换:公司希望展示自有 Logo 和系统名称,而非 Spring Boot 默认标识。
- 环境区分:开发、测试、生产环境的启动日志需要一眼区分,避免误操作生产环境。
Spring Boot 的 Banner 机制允许通过文本文件完全替换默认内容,并支持多种占位符注入动态信息。它解决了传统 Java 应用"启动日志千篇一律、无法传递环境上下文"的问题。
| 对比维度 | 传统 Java 应用 | Spring Boot Banner 机制 |
|---|---|---|
| 启动标识 | 通常无标识,或硬编码 System.out.println | 标准化 banner.txt 文件,框架自动读取 |
| 动态信息 | 需手动拼接字符串 | 内置占位符(${spring-boot.version} 等) |
| 环境区分 | 自行在代码中判断环境打印不同内容 | 通过 spring.main.banner-mode + Profile 配置 |
| 关闭方式 | 删除代码 | 一行配置 spring.main.banner-mode=off |
适用位置与常用属性
Banner 完全由资源文件和配置驱动,无需代码注解。
banner.txt 放置位置
| 位置 | 优先级 | 说明 |
|---|---|---|
classpath:banner.txt | 最高 | 项目 src/main/resources/banner.txt |
classpath:banner.gif / banner.jpg / banner.png | 中 | 图片 Banner(自动转 ASCII 艺术) |
classpath:banner.groovy | 低 | Groovy 脚本生成动态 Banner |
| 默认 Spring Boot Banner | 最低 | 未找到自定义文件时回退 |
优先级规则:Spring Boot 按上述顺序查找,一旦找到即使用,不再继续搜索。因此
banner.txt始终优先于图片和脚本。
常用配置属性
# application.yml
spring:
main:
banner-mode: console # console / log / off
| 属性 | 说明 | 可选值 |
|---|---|---|
spring.main.banner-mode | Banner 输出模式 | console(控制台)、log(日志文件)、off(关闭) |
Banner 占位符
| 占位符 | 说明 | 示例输出 |
|---|---|---|
${spring-boot.version} | Spring Boot 版本 | 2.7.18 |
${spring-boot.formatted-version} | 带括号的版本 | (v2.7.18) |
${application.version} | 应用版本(MANIFEST) | 1.0.0 |
${application.formatted-version} | 带括号的应用版本 | (v1.0.0) |
${application.title} | 应用标题(MANIFEST) | student-app |
${AnsiColor.BRIGHT_RED} | ANSI 颜色控制(控制台彩色) | 红色文字 |
${AnsiBackground.GREEN} | ANSI 背景色 | 绿色背景 |
${AnsiStyle.BOLD} | ANSI 样式(加粗) | 加粗文字 |
ANSI 颜色:Spring Boot 会自动检测终端是否支持 ANSI 颜色码,在 Windows CMD 等不支持的环境中自动回退为纯文本。
核心原理
Banner 加载与打印流程
流程解读:
SpringApplication.run()在创建ApplicationContext之前,进入 Banner 打印阶段。SpringApplicationBannerLoader按优先级查找banner.txt、图片、脚本等资源。- 找到后,通过
Environment解析文件中的占位符(版本号、颜色码等)。 - 根据
spring.main.banner-mode决定输出目标:console→System.out.print,log→logger.info(),off→ 不打印。 - 如果未找到任何自定义 Banner,回退到 Spring Boot 内置的默认 ASCII Logo。
Banner 资源优先级层次
完整示例
场景说明
飞翔科技的学生成绩管理系统需要在启动时展示公司标识和系统名称,便于运维人员在多系统混部环境中快速识别。架构师白歌要求:测试环境 Banner 显示黄色警告色和"测试环境"字样,生产环境 Banner 关闭。小崔需要配置 Banner 文件并验证不同环境的表现。
操作前:使用默认 Banner
# 操作前:application.yml(无 Banner 相关配置)
server:
port: 8080
启动时控制台输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.18)
默认 Banner 虽然美观,但无法传递"这是哪个系统、哪个环境、谁负责"等关键信息。
使用该特性的完整代码
步骤一:创建 src/main/resources/banner.txt
${AnsiColor.BRIGHT_YELLOW}
███████╗██╗ ██╗ ██╗██╗██╗ ██╗ ██████╗ ███████╗
██╔════╝██║ ██║ ██║██║██║ ██║ ██╔═══██╗██╔════╝
█████╗ ██║ ██║ ██║██║██║ ██║ ██║ ██║███████╗
██╔══╝ ██║ ██║ ██║██║██║ ██║ ██║ ██║╚════██║
██║ ███████╗╚██████╔╝██║███████╗███████╗╚██████╔╝███████║
╚═╝ ╚══════╝ ╚═════╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚══════╝
${AnsiColor.BRIGHT_GREEN}
系统名称:学生成绩管理系统
所属公司:广州飞翔科技
当前环境:${spring.profiles.active:未知环境}
负 责 人:白歌(架构师) / 小崔(后端开发)
应用版本:${application.version:未定义}
Spring Boot 版本:${spring-boot.formatted-version}
${AnsiColor.DEFAULT}
注意:占位符
${spring.profiles.active}会在运行时注入当前激活的 Profile 名称。如果未激活任何 Profile,则显示默认值。
步骤二:配置 application.yml(开发/测试环境)
spring:
profiles:
active: dev
main:
banner-mode: console
server:
port: 8080
步骤三:配置 application-prod.yml(生产环境)
spring:
main:
banner-mode: off
操作后运行结果及分析
开发/测试环境启动(--spring.profiles.active=dev):
███████╗██╗ ██╗ ██╗██╗██╗ ██╗ ██████╗ ███████╗
██╔════╝██║ ██║ ██║██║██║ ██║ ██╔═══██╗██╔════╝
█████╗ ██║ ██║ ██║██║██║ ██║ ██║ ██║███████╗
██╔══╝ ██║ ██║ ██║██║██║ ██║ ██║ ██║╚════██║
██║ ███████╗╚██████╔╝██║███████╗███████╗╚██████╔╝███████║
╚═╝ ╚══════╝ ╚═════╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚══════╝
系统名称:学生成绩管理系统
所属公司:广州飞翔科技
当前环境:dev
负 责 人:白歌(架构师) / 小崔(后端开发)
应用版本:未定义
Spring Boot 版本:(v2.7.18)
2024-05-20 15:00:00.123 INFO 12345 --- [main] c.f.s.StudentManagementApplication : Starting StudentManagementApplication using Java 1.8
生产环境启动(--spring.profiles.active=prod):
2024-05-20 15:05:00.456 INFO 12345 --- [main] c.f.s.StudentManagementApplication : Starting StudentManagementApplication using Java 1.8
2024-05-20 15:05:00.789 INFO 12345 --- [main] c.f.s.StudentManagementApplication : No active profile set, falling back to default profiles: prod
2024-05-20 15:05:02.123 INFO 12345 --- [main] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http)
生产环境启动日志中完全看不到 Banner,直接跳过进入标准日志输出。
分析:
banner.txt生效:Spring Boot 在 classpath 中找到banner.txt,自动替换默认 Logo。- 占位符解析生效:
${spring.profiles.active}被替换为dev,${spring-boot.formatted-version}被替换为(v2.7.18)。 - ANSI 颜色生效:
BRIGHT_YELLOW和BRIGHT_GREEN在支持 ANSI 的终端(如 IDEA 控制台、Linux 终端)中显示为彩色,在 Windows CMD 中自动回退为纯文本。 banner-mode=off生效:生产环境通过 Profile 配置关闭 Banner,减少日志噪音,避免暴露内部版本信息。
易错场景与面试考点
易错场景一:banner.txt 放错目录导致不生效
小崔将 banner.txt 放在了 src/main/java/com/feixiang/student/resources/ 包下,而非 src/main/resources/ 根目录。
后果:启动时仍然显示 Spring Boot 默认 Banner。Spring Boot 的 ResourceLoader 只会在 classpath 根目录和特定包路径下查找,不会递归扫描所有包目录。
正确做法:banner.txt 必须放在 src/main/resources/ 根目录下(Maven/Gradle 标准资源目录),打包后位于 JAR 的 BOOT-INF/classes/banner.txt。如果放在子目录中,需要显式指定路径:spring.banner.location=classpath:static/my-banner.txt。
易错场景二:ANSI 颜色在日志文件中残留乱码
# 错误示范:将 banner-mode 设为 log,同时使用 ANSI 颜色码
spring:
main:
banner-mode: log
后果:Banner 被输出到日志文件(如 app.log),但 ANSI 转义序列(如 \u001B[33m)被原样写入,在文本编辑器中显示为乱码或方框,影响日志可读性。
正确做法:若 banner-mode 为 log,Banner 内容中应避免使用 ${AnsiColor.*} 和 ${AnsiBackground.*} 占位符,保持纯文本。或者使用 banner-mode: console 仅输出到控制台,不写入日志文件。
易错场景三:占位符拼写错误
# 错误示范:banner.txt 中拼写错误
Spring Boot 版本:${spring.boot.version}
后果:占位符未被解析,原样输出为文本 ${spring.boot.version},而非实际的版本号。
正确做法:正确占位符是 ${spring-boot.version}(连字符,非点号)和 ${spring-boot.formatted-version}。参考 Spring Boot 官方文档确认占位符名称。
面试考点
Q:Spring Boot 启动时的 Banner 是如何加载的?
SpringApplication.run()在创建ApplicationContext之前,调用SpringApplicationBannerLoader按优先级查找banner.txt、图片文件、Groovy 脚本。找到后通过Environment解析占位符,再根据spring.main.banner-mode决定输出到控制台、日志或关闭。未找到自定义资源时回退到默认 Spring Boot Logo。
Q:banner.txt 支持哪些占位符?
支持
${spring-boot.version}(Boot 版本)、${application.version}(应用版本,来自 MANIFEST)、${application.title}(应用标题)。还支持 ANSI 颜色控制:${AnsiColor.BRIGHT_RED}、${AnsiBackground.GREEN}、${AnsiStyle.BOLD}等。所有占位符由Environment解析。
Q:如何为不同环境配置不同的 Banner?
方式一:通过 Profile 配置
spring.main.banner-mode=off关闭生产环境 Banner。方式二:通过spring.banner.location指定不同 Profile 下的 Banner 文件路径,如application-dev.yml中设置spring.banner.location=classpath:banner-dev.txt。方式三:在banner.txt中使用${spring.profiles.active}占位符动态显示环境名称。
Q:图片 Banner 是如何转换为 ASCII 的?
Spring Boot 内置
ImageBanner类,读取banner.gif/jpg/png后,将图片像素按亮度映射为 ASCII 字符集(如@#%*+=-:.),并在控制台输出为灰度 ASCII 艺术。支持通过spring.banner.image.*属性控制宽度和反转颜色。但企业环境更推荐使用纯文本banner.txt,避免不同终端的显示差异。