zoukankan      html  css  js  c++  java
  • SpringBoot之Banner介绍

    一、Banner 介绍

    1.1 Banner 是什么?

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.2.5.RELEASE)
    

    如上图所示的,是我们每次启动 SpringBoot 项目时就会在控制器输出的内容,这个就是 **Banner **。

    1.2 banner的输出模式

    * LOG:将 banner 信息输出到日志文件。
    * CONSOLE:将 banner 信息输出到控制台。
    * OFF:禁用 banner 的信息输出。
    

    二、自定义 Banner

    2.1 文本形式 banner

    resources 目录下新建 banner.txt 文件,内容如下:

    /*
                       _ooOoo_
                      o8888888o
                      88" . "88
                      (| -_- |)
                      O  =  /O
                   ____/`---'\____
                 .'  \|     |//  `.
                /  \|||  :  |||//  
               /  _||||| -:- |||||-  
               |   | \  -  /// |   |
               | \_|  ''---/''  |   |
                 .-\__  `-`  ___/-. /
             ___`. .'  /--.--  `. . __
          ."" '<  `.___\_<|>_/___.'  >'"".
         | | :  `- \`.;` _ /`;.`/ - ` : | |
            `-.   \_ __ /__ _/   .-` /  /
    ======`-.____`-.___\_____/___.-`____.-'======
                       `=---='
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             佛祖保佑       永无BUG
    */
    

    启动项目,观察控制台输出:

    /*
                       _ooOoo_
                      o8888888o
                      88" . "88
                      (| -_- |)
                      O  =  /O
                   ____/`---'\____
                 .'  \|     |//  `.
                /  \|||  :  |||//  
               /  _||||| -:- |||||-  
               |   | \  -  /// |   |
               | \_|  ''---/''  |   |
                 .-\__  `-`  ___/-. /
             ___`. .'  /--.--  `. . __
          ."" '<  `.___\_<|>_/___.'  >'"".
         | | :  `- \`.;` _ /`;.`/ - ` : | |
            `-.   \_ __ /__ _/   .-` /  /
    ======`-.____`-.___\_____/___.-`____.-'======
                       `=---='
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             佛祖保佑       永无BUG
    */
    

    可以看到 Banner 样式已经改变了。

    2.2 图片样式 Banner

    resources下创建 banner.jpg 文件

    启动项目,查看控制台输出:

              &&&&&&&&&&                                       &&                 
            &&&       :                                        &&                 
           &&*                                                 &&                 
          &&&                8888888*    :******     &&&&&&&&: &&   8888888       
          &&&      &&&&&&&& 88&    888  **     **:  &&     &&: &&  88:   .88      
           &&           && 888      88 ***      ** &&.     &&: && :8888888        
            &&&        &&&  88      88 ***     *** &&&     &&: &&  88.            
             8&&&&&&&&&&    .88888888   *********   &&&&&&&&&: &&   88888888      
                 :&&.          .8&         .**         o&  &&*        .88         
                                                   .&&    .&&                     
                                                     &&&&&&&             
    

    三、修改默认文件名

    bannerSpringBoot 默认名,我们也可以自定义文件名称。

    3.1 通过配置文件指定文件名

    # 文本形式
    spring.banner.location=icon.txt
    # 图片形式
    spring.banner.image.location=icon.jpg    
    

    3.2 通过代码形式指定文件名

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringbootApplication.class);
        springApplication.setBanner(new ResourceBanner(new ClassPathResource("icon.txt")));
        springApplication.run();
    }
    

    四、修改模式

    4.1 通过配置文件修改模式

    spring.main.banner-mode=off
    

    4.2 通过代码形式修改模式

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringbootApplication.class);
        springApplication.setBannerMode(Banner.Mode.LOG);
        springApplication.run();
    }
    

    五、Banner 输出原理

    进入 run 方法:发现有个 printBanner 方法:

    public ConfigurableApplicationContext run(String... args) {
    	......
        try{
            ......
            Banner printedBanner = printBanner(environment);
            ......
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);    
            ......    
        }catch (Throwable ex) {
            ......
        }   
        
    }    
    

    我们看下它的实现:

    private Banner printBanner(ConfigurableEnvironment environment) {
        // 判断 banner 模式
    	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);
        // 判断将 banner 输出到日志还是控制台
    	if (this.bannerMode == Mode.LOG) {
    		return bannerPrinter.print(environment, this.mainApplicationClass, logger);
    	}
    	return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
    }
    

    进入 print 方法:

    Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
        // 获取 banner
    	Banner banner = getBanner(environment);
        // 打印 banner
    	banner.printBanner(environment, sourceClass, out);
    	return new PrintedBanner(banner, sourceClass);
    }
    

    进入 getBanner 方法:

    private Banner getBanner(Environment environment) {
    	Banners banners = new Banners();
        // 获取图片 banner
    	banners.addIfNotNull(getImageBanner(environment));
        // 获取文本 banner
    	banners.addIfNotNull(getTextBanner(environment));
        // 判断是否存在一个 banner
    	if (banners.hasAtLeastOneBanner()) {
    		return banners;
    	} 
        // 后备 banner
    	if (this.fallbackBanner != null) {
    		return this.fallbackBanner;
    	}
        // 默认 banner
    	return DEFAULT_BANNER;
    }
    

    查看两个获取 Banne 的方法

    // 默认文件名
    static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
    // 默认图片名
    static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
    
    private Banner getImageBanner(Environment environment) {
    	String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
    	if (StringUtils.hasLength(location)) {
    		Resource resource = this.resourceLoader.getResource(location);
    		return resource.exists() ? new ImageBanner(resource) : null;
    	}
    	for (String ext : IMAGE_EXTENSION) {
    		Resource resource = this.resourceLoader.getResource("banner." + ext);
    		if (resource.exists()) {
    			return new ImageBanner(resource);
    		}
    	}
    	return null;
    }
    
    private Banner getTextBanner(Environment environment) {
    	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;
    }	
    

    图片打印实现类 ImageBanner

    @Override
    public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
    	String headless = System.getProperty("java.awt.headless");
    	try {
    		System.setProperty("java.awt.headless", "true");
    		printBanner(environment, out);
    	}
    	catch (Throwable ex) {
    		logger.warn(LogMessage.format("Image banner not printable: %s (%s: '%s')", this.image, ex.getClass(),
    				ex.getMessage()));
    		logger.debug("Image banner printing failure", ex);
    	}
    	finally {
    		if (headless == null) {
    			System.clearProperty("java.awt.headless");
    		}
    		else {
    			System.setProperty("java.awt.headless", headless);
    		}
    	}
    }
    
    private void printBanner(Environment environment, PrintStream out) throws IOException {
    	int width = getProperty(environment, "width", Integer.class, 76);
    	int height = getProperty(environment, "height", Integer.class, 0);
    	int margin = getProperty(environment, "margin", Integer.class, 2);
    	boolean invert = getProperty(environment, "invert", Boolean.class, false);
    	BitDepth bitDepth = getBitDepthProperty(environment);
    	PixelMode pixelMode = getPixelModeProperty(environment);
    	Frame[] frames = readFrames(width, height);
    	for (int i = 0; i < frames.length; i++) {
    		if (i > 0) {
    			resetCursor(frames[i - 1].getImage(), out);
    		}
    		printBanner(frames[i].getImage(), margin, invert, bitDepth, pixelMode, out);
    		sleep(frames[i].getDelayTime());
    	}
    }
    

    重点关注 readFrames 方法:

    private Frame[] readFrames(int width, int height) throws IOException {
    	try (InputStream inputStream = this.image.getInputStream()) {
    		try (ImageInputStream imageStream = ImageIO.createImageInputStream(inputStream)) {
    			return readFrames(width, height, imageStream);
    		}
    	}
    }
    private Frame[] readFrames(int width, int height, ImageInputStream stream) throws IOException {
    	Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
    	Assert.state(readers.hasNext(), "Unable to read image banner source");
    	ImageReader reader = readers.next();
    	try {
    		ImageReadParam readParam = reader.getDefaultReadParam();
    		reader.setInput(stream);
    		int frameCount = reader.getNumImages(true);
    		Frame[] frames = new Frame[frameCount];
    		for (int i = 0; i < frameCount; i++) {
    			frames[i] = readFrame(width, height, reader, i, readParam);
    		}
    		return frames;
    	}
    	finally {
    		reader.dispose();
    	}
    }	
    

    六、推荐在线制作 banner 的网站

    传送门

    优点:

    • 切换字体以及输入文字的时候, 会自动输出 banner 字样。
    • 在输出框中,是可编辑的,可以自己添加版本号,作者简介信息等。

    缺点:

    • 不能下载 txt。
    • 结果内容只有选中后,手动复制粘贴到 banner.txt 文件中。
  • 相关阅读:
    gcc/g++动态链接库和静态库的链接顺序
    linux文件描述符--转载
    mysql之test表
    linux之eventfd()
    spring data jpa实现多条件查询(分页和不分页)
    List的remove方法里的坑
    启动Spring boot报错:nested exception is java.sql.SQLException: Field 'id' doesn't have a default value
    CentOS下yum安装jdk
    CentOS下yum安装mysql
    Redis有序Set、无序Set的使用经历
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/12508463.html
Copyright © 2011-2022 走看看