springboot配置启动自定义banner及配置原理分析

前言

我们注意到springboot项目启动时,控制台会打印自带的banner,然后对于部分比较骚气的同学来说,太单调太普通太一般了;所以,是时候表演真正的技术了

 

自定义banner

很简单,只需在resources目录下添加自定义的banner.txt文件即可

 

banner.txt内容

${AnsiColor.BRIGHT_RED}
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//        南无阿弥陀佛       南无阿弥陀佛     南无阿弥陀佛             //
////////////////////////////////////////////////////////////////////

 

=================分隔线 ================================

作为一名骚气的程序猿,我们当然不能只停留于会配置自定义banner,下面咱们去源码里瞅瞅为什么这样配置就能实现自定义banner,走起~

首先进入Application的main函数启动入口的run方法,下面我们一步步跟进去瞧瞧

SpringApplication这个类

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class<?>[] { primarySource }, args);
    }

//new SpringApplication(primarySources)这个咱们不用看,里面是springboot自动装配(SPI)的逻辑,咱们直接看后面的run(args)
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); } public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment);
       //我们发现这一步是处理启动banner的逻辑,点进去看看 Banner printedBanner
= printBanner(environment); context = createApplicationContext(); exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } listeners.started(context); callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }

banner处理逻辑

private Banner printBanner(ConfigurableEnvironment environment) {
        if (this.bannerMode == Banner.Mode.OFF) {
            return null;
        }
        ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
                : new DefaultResourceLoader(getClassLoader());
        SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
        if (this.bannerMode == Mode.LOG) {
            return bannerPrinter.print(environment, this.mainApplicationClass, logger);
        }
     //banner没有关闭且没有指定是写到log文件中的时候,会走到这一步
return bannerPrinter.print(environment, this.mainApplicationClass, System.out); } public Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
     //这里获取banner内容 Banner banner
= getBanner(environment); banner.printBanner(environment, sourceClass, out); return new PrintedBanner(banner, sourceClass); } private Banner getBanner(Environment environment) { Banners banners = new Banners();
//我们没有配置最骚气的图片类型的banner内容(做人要含蓄一点),所以我们看下一步 banners.addIfNotNull(getImageBanner(environment));
     //我们配置的是文本型的banner,所以看这里的getTextBanner(environment) banners.addIfNotNull(getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) { return banners; } if (this.fallbackBanner != null) { return this.fallbackBanner; } return DEFAULT_BANNER; }
//到这里同学应该就知道原理了
private Banner getTextBanner(Environment environment) {
//拿到自定义配置的banner文件地址 String location
= environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION); Resource resource = this.resourceLoader.getResource(location); if (resource.exists()) { return new ResourceBanner(resource); } return null; }
//DEFAULT_BANNER_LOCATION常量就指向了banner.txt文件
static final String DEFAULT_BANNER_LOCATION = "banner.txt";

 

posted @ 2020-04-09 14:21  电影公众号  阅读(533)  评论(0编辑  收藏  举报