• 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";
  • 相关阅读:
    Vue.js实现的计算器功能完整示例
    vue实现简易计算器
    Vuex中mutations与actions的区别详解
    两个子组件之间的传值
    JS操作元素节点(非常详细)
    js包装类
    Vue Router 的params和query传参的使用和区别(详尽)
    初步了解生命周期
    简单介绍一下Progressive Web App(PWA)
    webpack学习笔记(阮一峰教程demo)
  • 原文地址:https://www.cnblogs.com/vicF/p/12666675.html
Copyright © 2020-2023  润新知