如何为所欲为的自定义SpringBoot Banner图?

用过SpringBoot的同学都知道,在SpringBoot项目启动时,会默认打印一个"Spring"的字符,如下图所示


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

这个被称为SpringBoot框架的banner,项目启动时会出现在很醒目的位置上,我们在开发过程中每启动一次项目,就会出现这个banner图,那么我们能不能自定义这个banner图呢?答案是可以的,下面我们一起从源码的角度看一下如何自定义这个banner

源码分析

想要了解banner的自定义规则,我们就要从程序启动的入口开始,SpringBoot一般是从如下的Main函数来启动的

@SpringBootApplication
public class Main {
    public static void main(String[] args){
        SpringApplication.run(Main.class, args);
    }
}

可以看到main方法调用了SpringApplication的run方法用来引导启动项目,那么我们肯定要从这个run方法入手

跟源码最后可以看到在SpringApplication类中有一个可变参数的run方法

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;
	}

从源码中可以看出来,SpringBoot是专门写了一个方法用来打印Banner的,如下一行代码就是用来打印banner的

	Banner printedBanner = printBanner(environment);
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);
		//通过参数来控制是打印在log中,还是打印在控制台		
		if (this.bannerMode == Mode.LOG) {
			return bannerPrinter.print(environment, this.mainApplicationClass, logger);
		}
		return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
	}

从源码中可以看到,可以通过参数来控制不打印Banner,默认是打印的。也可以控制banner是打印在log中还是打印在控制台

下面来看一下Banner获取规则

public Banner print(Environment environment, Class<?> sourceClass, Log logger) {
		Banner banner = getBanner(environment);
		try {
			logger.info(createStringFromBanner(banner, environment, sourceClass));
		}
		catch (UnsupportedEncodingException ex) {
			logger.warn("Failed to create String for banner", ex);
		}
		return new PrintedBanner(banner, sourceClass);
	}
	
	private Banner getBanner(Environment environment) {
		Banners banners = new Banners();
		//获取图片banner
		banners.addIfNotNull(getImageBanner(environment));
		//获取文本banner
		banners.addIfNotNull(getTextBanner(environment));
		if (banners.hasAtLeastOneBanner()) {
			return banners;
		}
		if (this.fallbackBanner != null) {
			return this.fallbackBanner;
		}
		return DEFAULT_BANNER;
	}

先获取图片banner,再获取文本banner,两个可以同时配置

同时配置时会先打印图片banner,再打印文本banner


static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };

//获取图片banner
private Banner getImageBanner(Environment environment) {
        //优先从spring.banner.image.location配置对应的地址获取banner
		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;
		}
		//没有配置则从根目录下依次获取banner.gif、banner.jpg、banner.png
		for (String ext : IMAGE_EXTENSION) {
			Resource resource = this.resourceLoader.getResource("banner." + ext);
			if (resource.exists()) {
				return new ImageBanner(resource);
			}
		}
		return null;
	}

static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
static final String DEFAULT_BANNER_LOCATION = "banner.txt";


//获取文本banner
private Banner getTextBanner(Environment environment) {
        //优先获取spring.banner.location配置对应的目录中的banner,没有配置则获取默认的banner.txt
		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;
	}

上面的代码显示了获取图片banner和文本banner的规则,可以自定义图片或文本

以上就是自定义banner的规则,知道了规则之后,我们就可以根据规则来自定义一个banner

有很多可以生成自定义banner的网站,比如https://www.bootschool.net/ascii/


                                .::::.
                              .::::::::.
                              :::::::::::
                              ':::::::::::..
                               :::::::::::::::'
                                ':::::::::::.
                                  .::::::::::::::'
                                .:::::::::::...
                               ::::::::::::::''
                   .:::.       '::::::::''::::
                 .::::::::.      ':::::'  '::::
                .::::':::::::.    :::::    '::::.
              .:::::' ':::::::::. :::::      ':::.
            .:::::'     ':::::::::.:::::       '::.
          .::::''         '::::::::::::::       '::.
         .::''              '::::::::::::         :::...
      ..::::                  ':::::::::'        .:' ''''
   ..''''':'                    ':::::.'

在项目根目录下新建banner.txt,将以上字符贴进去,重新启动项目,就可以在控制台看到你自定义的banner~

如果感觉对你有些帮忙,请收藏好,你的关注和点赞是对我最大的鼓励!
如果想跟我一起学习,坚信技术改变世界,请关注【Java天堂】公众号,我会定期分享自己的学习成果,第一时间推送给您

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/pzjtian/article/details/107968559