SpringBoot Banner,SpringApplicationRunListener,ApplicationContextInitializer,Runner,StopWatch


 
Banner、SpringApplicationRunListener、Runner是springboot提供的,ApplicationContextInitializer、StopWatch是spring提供的,此处以springboot项目为例介绍它们的使用方式。

 

自定义 Banner

springboot应用启动时会自动打印指定的banner, 支持文字 benner、图片banner。
 

文本banner

resources 下新建 banner.txt
 

可在线生成banner文本的网站

第1个提供的自定义配置项少,后2个提供的自定义配置项多,字体中提供了一些banner专用的字体。

把生成的banner文本复制粘贴到banner.txt中即可。
 

如果文件路径不是 classpath根目录下的banner.txt,需要在yml中指定banner文本文件的路径

spring:
  banner:
    #指定banner文本的位置,默认为 classpath:banner.txt
    location: classpath:static/other/banner.txt

 

banner.txt 示例


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


 

可以指定字体颜色,可以使用 ${ } 获取一些配置值

${AnsiColor.BRIGHT_YELLOW}

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

${AnsiColor.BRIGHT_GREEN}
Application Name: ${application.title}
Application Version: ${application.version}
Spring Boot Version: ${spring-boot.version}

  • ${AnsiColor.XXX} 指定字体颜色
  • ${application.title} 获取应用名称
  • ${application.version} 获取应用版本号,${application.formatted-version} 获取格式化的应用版本号
  • ${spring-boot.version} 获取使用的springboot版本号,${spring-boot.formatted-version} 获取格式化的springboot版本号

 

说明

1、所谓格式化的版本号,其实就是把版本号放在小括号()中,示例

#  mall (v1.2.8-SNAPSHOT)
Application Name: ${application.title}${application.formatted-version}

 
2、${AnsiColor.XXX} 指定字体颜色,需要使用彩色日志、终端支持显示彩色文字,否则显示出来是黑白的。
 

3、取的应用名称、应用版本号是打为jar包后,jar包中的 META-INF/MANIFEST.MF 清单文件中的

Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
#应用名称
Implementation-Title: mall
#应用版本号
Implementation-Version: 1.2.8-SNAPSHOT
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.3.12.RELEASE
Created-By: Maven Jar Plugin 3.2.0
Main-Class: org.springframework.boot.loader.JarLauncher

对应 pom.xml 中指定的应用名称、应用版本号。

在IDE中进行调试直接启动应用时,没有清单文件,打印的应用名称、应用版本号都是空的,打成jar包启动就正常了。

 

图片banner

banner 图片放在 resources 根目录下,图片文件名支持 banner.jpg | png | gif 。

如果文件路径不是classpath根目录下的 banner.jpg | png | gif,需要在yml中指定banner图片的路径

spring:
  banner:
    #指定banner图片的位置,默认为 classpath:banner.gif,实际上 jpg、png 也行
    image:
      location: classpath:static/image/banner.jpg

 

自定义运行监听器 SpringApplicationRunListener

1、自定义的运行监听器类

//实现 SpringApplicationRunListener 接口,根据需要重写方法
//不用加 @Component 之类的注解放到容器中
public class MySpringApplicationRunListener implements SpringApplicationRunListener {

    private SpringApplication application;

    private String[] args;

    public MySpringApplicationRunListener() {
    }

	//必须提供包含 SpringApplication、String[] 这2个参数的构造器,因为是调用这个构造器创建来实例
	//成员变量可以不要这2个参数,方法体中可以不使用这2个参数,但形参中一定要声明这2个参数
    public MySpringApplicationRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;
    }

    @Override
    public void starting() {
        System.out.println("starting...");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        System.out.println("environmentPrepared...");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("contextPrepared...");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("contextLoaded...");
    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("started...");
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("running...");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("failed...");
    }

}

运行监听器用于监听springboot启动的各个阶段,初始化时机比较早,在应用上下文创建之前就需要初始化,使用 spring.factories 进行配置、加载,不放到容器中。

有多个自定义的运行监听器时,可以实现Order接口或使用@Order注解指定它们的执行顺序。
 

2、resources下新建目录 META-INF/spring.factories,指定运行监听器要使用的实现类

org.springframework.boot.SpringApplicationRunListener=\
com.chy.mall.config.MySpringApplicationRunListener1,\
com.chy.mall.config.MySpringApplicationRunListener2

 

说明

自定义的应用上下文初始化器、应用监听器都不建议用 spring.factories 方式进行配置,普通springboot项目可以用 spring.factories 方式配置初始化器、监听器,但构建在springboot基础上的springcloud有2个上下文:bootstrap、application,这2个上下文都会加载 spring.factories,从而出现重复调用初始化器、监听器的情况。

对于spring|springboot提供的可以在spring.factories中添加的扩展配置,尽量spring.factories之外的方式进行配置,比如应用上下文初始化器可以用SpringApplication实例的addInitializers()方法添加,应用监听器可以用addListeners()方法添加或直接用@Component之类的注解标注。

运行监听器也是同理,普通springboot项目可以用,springcloud项目中就不不好用了,但运行监听器没有提供其它配置方式,这就显得很鸡肋了,并不建议使用运行监听器,能使用应用监听器的尽量使用应用监听器代替。

 

自定义应用上下文初始化器 ApplicationContextInitializer

自定义的 ApplicationContextInitializer

/**
 * 自定义的应用上下文初始化器
 * 实现ApplicationContextInitializer<ConfigurableApplicationContext>,重写方法即可
 */
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        //...
    }

}

 
修改引导类的main()方法如下

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        //创建spring容器
        SpringApplication springApplication = new SpringApplication(DemoApplication.class);
        //添加应用上下文的初始化器。此时已经创建了应用上下文实例,初始化器可以对应用上下文做一些自定义的初始化操作
        springApplication.addInitializers(new MyApplicationContextInitializer());
        //启动容器
        springApplication.run(args);
    }

}

 

Runner的使用

  • 实现 ApplicationRunner 或 CommandLineRunner 接口,重写 run() 方法
  • 作为bean放到容器中即可
@Component
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...");
    }

}
@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...");
    }

}

 

StopWatch( 计时器)的使用

普通计时方式:System.currentTimeMillis() 或 new Date() 记录起止时间,求差值,结果需要自行转换时间单位,稍微有些麻烦。

StopWatch 计时器、秒表,watch 表,可统计单个、多个任务的执行耗时,计时功能丰富。

StopWatch 本质是调用native方法获取系统的纳秒级时间戳,求差值,单位支持 s、ms、ns。需要注意的是,小单位转成大单位时,会自动舍弃小数部分,造成结果有一些细微误差,如果对精确度要求高,尽量使用小单位。

 

统计单个任务的耗时

StopWatch stopWatch = new StopWatch();

//启动计时器
stopWatch.start();

//...

//终止当前计时任务
stopWatch.stop();

//任务耗时
System.out.println(stopWatch.getLastTaskTimeMillis());
System.out.println(stopWatch.getLastTaskTimeNanos());

 

统计逐个执行的任务的耗时情况

StopWatch stopWatch = new StopWatch();

//任务1。参数指定任务名称,以任务名称区分当前计时器的各个任务
stopWatch.start("task1");
//...
stopWatch.stop();


//任务2
stopWatch.start("task2");
//...
stopWatch.stop();

//总时间
System.out.println(stopWatch.getTotalTimeMillis());
//各个任务的耗时情况
for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) {
    //任务名称、耗时
    System.out.printf("%s:%d ms\n", taskInfo.getTaskName(), taskInfo.getTimeMillis());
}

//stopWatch中包含了所有的信息,可直接查看 stopWatch,存储的是原始的纳米级时间
System.out.println(stopWatch);

 

同时统计多个任务的耗时

一个计时器同一时刻只能统计一个任务的耗时,如果要在同一个时刻统计多个任务的耗时,需要使用多个计时器

#参数指定计时器id,唯一标识一个计时器实例
StopWatch stopWatch = new StopWatch("1");
StopWatch stopWatch = new StopWatch("2");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值