SpringBoot源码(八): 打印banner

介绍

接着prepareEnvironment之后继续介绍springBoot启动流程的代码,接下来看看banner的打印。

 

源码

	private Banner printBanner(ConfigurableEnvironment environment) {
        // banner模式,如果为off则不打印
		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);
		}
        // 控制台直接输出
		return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
	}

上面代码就可以看到,对于如果banner.mode设置为空的话,则不会去打印banner。但是很多小伙伴不知道这个是什么设置的。其实是在prepareEnvironment方法里,bindToSpringApplication方法去设置的。当然也可以启动时候new SpringApplication自己设置。bindToSpringApplication中会对spring.main的设置绑定到SpringApplication上去。这边需要讲到Binder这个类,由于不是主流程,后面会进行说到。这边先说下如果关闭banner打印的几种方法。

  • 在配置文件中设置spring.main.banner-mode="off",这边yml需要加引号,不然会被解析成false。
  • 在启动参数中设置--spring.main.banner-mode=off
  • // 创建启动类时候设置
    SpringApplication app 
        = new SpringApplication(Application.class);
    application.setBannerMode(Banner.Mode.OFF);
    app.run(args);

     

接着向下看,直接看控制台输出的源码,因为其实都差不多,主要就是找到banner的位置,然后打印。

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

上面看逻辑很清晰,找到banner,然后打印就可以了。接着看如何寻找banner

    // 文本banner位置
	static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";

    // 图片banner位置
	static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";

    // 默认文本banner位置
	static final String DEFAULT_BANNER_LOCATION = "banner.txt";
    
    // 默认图片支持格式
	static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };

	private static final Banner DEFAULT_BANNER = new SpringBootBanner();

	private Banner getBanner(Environment environment) {
        // banner的一个列表集成
		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;
		}
        // 没有就返回默认banner,springBoot自带的banner
		return DEFAULT_BANNER;
	}
    
    // 寻找文本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
	private Banner getImageBanner(Environment environment) {
		String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
        // 从配置中拿到图片banner位置信息
		if (StringUtils.hasLength(location)) {
			Resource resource = this.resourceLoader.getResource(location);
			return (resource.exists() ? new ImageBanner(resource) : null);
		}
        // 配置中没有,分别查询后缀名是"gif", "jpg", "png"的banner
		for (String ext : IMAGE_EXTENSION) {
			Resource resource = this.resourceLoader.getResource("banner." + ext);
			if (resource.exists()) {
				return new ImageBanner(resource);
			}
		}
		return null;
	}

寻找banner的代码比较长,但是逻辑也比较清晰。 springBoot支持文本的banner和图片的banner,这边就是分别去查询文本的banner和图片的banner。

springBoot支持我们配置banner的位置,默认都是去从classpath中寻找。也就是在classpath中查找banner.txt,banner.jpg,banner.gif,banner.png。如果我们自定义一个文本banner,可以直接在resource下面加一个banner.txt就行了,如果是图片的话,就加一个banner.jpg或者banner.gif或者banner.png,图片和文本都加的话,也都可以去打印的。

如:

        

可以看到,这边打印了图片,下面还有一个Banner的文本也被打印了出来。

如果我不想把banner放在默认的resource中怎么办呢?

这就需要代码中说到的spring.banner.location和spring.banner.image.location了。

假设我想把文本banner放在resource中的config的文件夹下,那么就在配置文件中配置spring.banner.location=/config/banner.txt就可以了。同样图片位置就设置spring.banner.image.location。这里需要注意下,在自定义图片位置的时候,图片的格式不再局限于,gif,png,jpg三种了。例如我现在改成jpeg,配置文件中设置spring.banner.image.location=/config/banner.jpeg:

可以看到此时图片格式设置成jpeg一样可以打印。

当然如果不想放在resources中,放到磁盘位置也是可以的。比如现在我想设置从d盘去读取。在配置文件中配置spring.banner.location=file:d:\test\banner1.txt;file:协议前缀一定要带上。因为spring中ResourceLoader解析对于没有带协议的,先尝试通过url去获取资源,获取不到从classpath中获取。所以不加file协议的话,直接认为是url资源去获取,获取不到就从classpath获取,源码在DefaultResourceLoader中,就不展开说了(主要url构造那段我也看不懂[😂])。

上面介绍完了自定义设置banner以及banner路径的配置,如果我们什么都不设置的话,那就会调用到springBoot自己的banner了,也就是SpringBootBanner

class SpringBootBanner implements Banner {

	private static final String[] BANNER = { "",
			"  .   ____          _            __ _ _",
			" /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\",
			"( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
			" \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )",
			"  '  |____| .__|_| |_|_| |_\\__, | / / / /",
			" =========|_|==============|___/=/_/_/_/" };

	private static final String SPRING_BOOT = " :: Spring Boot :: ";

	private static final int STRAP_LINE_SIZE = 42;

	@Override
	public void printBanner(Environment environment, Class<?> sourceClass,
			PrintStream printStream) {
		for (String line : BANNER) {
			printStream.println(line);
		}
		String version = SpringBootVersion.getVersion();
		version = (version == null ? "" : " (v" + version + ")");
		String padding = "";
		while (padding.length() < STRAP_LINE_SIZE
				- (version.length() + SPRING_BOOT.length())) {
			padding += " ";
		}

		printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT,
				AnsiColor.DEFAULT, padding, AnsiStyle.FAINT, version));
		printStream.println();
	}

}

这里就能看到我们熟悉的banner了,就是什么都不设置的时候打印的springBoot自带的banner。

总结

这边对于springBoot的banner打印就说完了,springBoot支持文本和图片两种banner。不配置就打印springBoot自带的banner。

简单配置的话就直接在resources中放置banner.txt,banner.png,banner.gif,banner.jpg就可以了。

也可以配置spring.banner.location和spring.banner.image.location之后,就从配置的地方读取banner了。

需要注意的是图片在没有配置spring.banner.image.location时候支持png,gig,jpg三种格式。配置之后就不会限制图片格式了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值