SpringBoot源码 | printBanner方法解析

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文主要讲述SpringBoot启动流程源码中的printBanner()方法

printBanner

printBanner方法用于打印在src/main/resources下名字是banner的自定义日志文件信息,对于整体的SpringBoot启动流程来说不算主启动业务流程,但是也提供了自定义打印日志内容的可能,有一定存在的意义,所以这里也一起来看一下printBanner方法内部吧,printBanner方法源码加入注释后

privateBannerprintBanner(ConfigurableEnvironmentenvironment) {
//Disable printing of the banner  是否允许打印banner信息if (this.bannerMode==Banner.Mode.OFF) {
returnnull;
    }
//资源加载类ResourceLoaderresourceLoader= (this.resourceLoader!=null) ?this.resourceLoader            : newDefaultResourceLoader(null);
//构造SpringApplicationBannerPrinter 对象SpringApplicationBannerPrinterbannerPrinter=newSpringApplicationBannerPrinter(resourceLoader, this.banner);
//Print the banner to the log file 打印banner到日志文件if (this.bannerMode==Mode.LOG) {
returnbannerPrinter.print(environment, this.mainApplicationClass, logger);
    }
//Print the banner to System.out 打印banner到System.outreturnbannerPrinter.print(environment, this.mainApplicationClass, System.out);
}

整个方法比较简单,也比较容易理解,根据我在源码中添加的注释理解即可,这里我们主要看bannerPrinter.print方法

bannerPrinter.print

首先来看一下print方法的源码

image.png

源码先获取Banner对象,然后返回PrintedBanner对象给调用方

getBanner

getBanner根据environment获取Banner对象

image.png

这里在获取Banner对象的时候会涉及到getImageBanner、getTextBanner方法,返回ImageBanner或者ResourceBanner

getImageBanner

getImageBanner首先会去判断是否配置了banner路径信息,后面根据resourceLoader获取banner是图片相关后缀时返回ImageBanner对象

privateBannergetImageBanner(Environmentenvironment) {
//获取配置的spring.banner.image.location路径,如果存在则加载资源Stringlocation=environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
if (StringUtils.hasLength(location)) {
Resourceresource=this.resourceLoader.getResource(location);
returnresource.exists() ?newImageBanner(resource) : null;
    }
//判断是否是IMAGE_EXTENSION = { "gif", "jpg", "png" }后缀,是则返回ImageBannerfor (Stringext : IMAGE_EXTENSION) {
Resourceresource=this.resourceLoader.getResource("banner."+ext);
if (resource.exists()) {
returnnewImageBanner(resource);
        }
    }
returnnull;
}

getTextBanner

getTextBanner加载默认配置路径的banner.txt文件并判断存在性和不包含特定条件,满足则返回ResourceBanner

privateBannergetTextBanner(Environmentenvironment) {
//获取资源配置spring.banner.location默认文件名banner.txt的资源路径Stringlocation=environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);
//加载资源Resourceresource=this.resourceLoader.getResource(location);
try {
//如果资源存在且resource的URL不包含liquibase-core则返回ResourceBannerif (resource.exists() &&!resource.getURL().toExternalForm().contains("liquibase-core")) {
returnnewResourceBanner(resource);
        }
    }
catch (IOExceptionex) {
// Ignore    }
returnnull;
}

如此便获取到Banner,回到print方法打印banner.txt文本内容

image.png

通过构造方法返回PrintedBanner用于后续打印日志信息输出

image.png

其中构造方法中参数sourceClass是主程序类

image.png

到这里整个printBanner的加载就完成了,结果如图


image.png

banner.txt文本内容为

ApplicationVersion: ${ruoyi.version}
SpringBootVersion: ${spring-boot.version}
//////////////////////////////////////////////////////////////////////                          _ooOoo_                               ////                         o8888888o                              ////                         88" . "88                              ////                         (| ^_^ |)                              ////                         O\  =  /O                              ////                      ____/`---'\____                           ////                    .'  \\|     |//  `.                         ////                   /  \\|||  :  |||//  \                        ////                  /  _||||| -:- |||||-  \                       ////                  |   | \\\  -  /// |   |                       ////                  | \_|  ''\---/''  |   |                       ////                  \  .-\__  `-`  ___/-. /                       ////                ___`. .'  /--.--\  `. . ___                     ////              ."" '<  `.___\_<|>_/___.'  >'"".                  ////            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 ////            \  \ `-.   \_ __\ /__ _/   .-` /  /                 ////      ========`-.____`-.___\_____/___.-`____.-'========         ////                           `=---='                              ////      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ////             打印banner日志信息                                  //////////////////////////////////////////////////////////////////////
相关文章
|
13天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
16天前
|
人工智能
歌词结构的巧妙安排:写歌词的方法与技巧解析,妙笔生词AI智能写歌词软件
歌词创作是一门艺术,关键在于巧妙的结构安排。开头需迅速吸引听众,主体部分要坚实且富有逻辑,结尾则应留下深刻印象。《妙笔生词智能写歌词软件》提供多种 AI 功能,帮助创作者找到灵感,优化歌词结构,写出打动人心的作品。
|
22天前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
38 3
|
17天前
|
人工智能
写歌词的技巧和方法全解析:开启你的音乐创作之旅,妙笔生词智能写歌词软件
怀揣音乐梦想,渴望用歌词抒发情感?掌握关键技巧,你也能踏上创作之旅。灵感来自生活点滴,主题明确,语言简洁,韵律和谐。借助“妙笔生词智能写歌词软件”,AI辅助创作,轻松写出动人歌词,实现音乐梦想。
|
2天前
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
|
9天前
|
机器学习/深度学习 人工智能 安全
TPAMI:安全强化学习方法、理论与应用综述,慕工大、同济、伯克利等深度解析
【10月更文挑战第27天】强化学习(RL)在实际应用中展现出巨大潜力,但其安全性问题日益凸显。为此,安全强化学习(SRL)应运而生。近日,来自慕尼黑工业大学、同济大学和加州大学伯克利分校的研究人员在《IEEE模式分析与机器智能汇刊》上发表了一篇综述论文,系统介绍了SRL的方法、理论和应用。SRL主要面临安全性定义模糊、探索与利用平衡以及鲁棒性与可靠性等挑战。研究人员提出了基于约束、基于风险和基于监督学习等多种方法来应对这些挑战。
21 2
|
10天前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
29 3
|
12天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
16天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
13 1
|
23天前
|
存储 JavaScript 前端开发
Vue3权限控制全攻略:路由与组件层面的用户角色与权限管理方法深度解析
Vue3权限控制全攻略:路由与组件层面的用户角色与权限管理方法深度解析
93 2

推荐镜像

更多
下一篇
无影云桌面