Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement the monitoring of springboot application service startup events

2025-02-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "how to realize the monitoring of springboot application service startup events". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let Xiaobian take you to learn "how to realize the monitoring of springboot application service startup events"!

I. Introduction

Spring Boot provides two interfaces: CommandLineRunner and ApplicationRunner, which are used to do special processing when launching applications. These codes will be executed before the run() method of SpringApplication completes. Relative to the Spring ApplicationListener interface custom listener introduced in the previous chapter, Servlet ContextListener listener. The advantage of using both is that you can easily use application startup parameters to do different initialization operations according to different parameters.

II. Introduction to Common Scenes

Implement CommandLineRunner and ApplicationRunner interfaces. Usually used for special code execution before application startup, such as:

Load data commonly used by the system into memory

Apply last run garbage cleanup

Send notification after successful system startup, etc.

As shown in the figure below, I implemented the CommandLineRunner interface, and the commonly used configuration data in the system will be stored when the application is started. Load from the database to memory. When using the data in the future, you only need to call the getSysConfigList method. You don't need to load the database every time you use the data. Save system resources and reduce data loading time.

二、代码小实验 通过@Component定义方式实现

CommandLineRunner:参数是字符串数组

@Slf4j@Componentpublic class CommandLineStartupRunner implements CommandLineRunner { @Override public void run(String... args){ log.info("CommandLineRunner传入参数:{}", Arrays.toString(args)); }}

ApplicationRunner:参数被放入ApplicationArguments,通过getOptionNames()、getOptionValues()、getSourceArgs()获取参数

@Slf4j@Componentpublic class AppStartupRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { log.info("ApplicationRunner参数名称: {}", args.getOptionNames()); log.info("ApplicationRunner参数值: {}", args.getOptionValues("age")); log.info("ApplicationRunner参数: {}", Arrays.toString(args.getSourceArgs())); }}通过@Bean定义方式实现

这种方式可以指定执行顺序,注意前两个Bean是CommandLineRunner,最后一个Bean是ApplicationRunner 。

@Configurationpublic class BeanRunner { @Bean @Order(1) public CommandLineRunner runner1(){ return new CommandLineRunner() { @Override public void run(String... args){ System.out.println("BeanCommandLineRunner run1()" + Arrays.toString(args)); } }; } @Bean @Order(2) public CommandLineRunner runner2(){ return new CommandLineRunner() { @Override public void run(String... args){ System.out.println("BeanCommandLineRunner run2()" + Arrays.toString(args)); } }; } @Bean @Order(3) public ApplicationRunner runner3(){ return new ApplicationRunner() { @Override public void run(ApplicationArguments args){ System.out.println("BeanApplicationRunner run3()" + Arrays.toString(args.getSourceArgs())); } }; }}

可以通过@Order设置执行顺序

三、执行测试

在IDEA Springboot启动配置中加入如下参数,保存后启动应用

测试输出结果:

c.z.boot.launch.config.AppStartupRunner : ApplicationRunner参数名称: [name, age]

c.z.boot.launch.config.AppStartupRunner : ApplicationRunner参数值: [18]

c.z.boot.launch.config.AppStartupRunner : ApplicationRunner参数: [--name=zimug, --age=18]

BeanApplicationRunner run3()[--name=zimug, --age=18]

c.z.b.l.config.CommandLineStartupRunner : CommandLineRunner传入参数:[--name=zimug, --age=18]

BeanCommandLineRunner run1()[--name=zimug, --age=18]

e=18]

BeanCommandLineRunner run2()[--name=zimug, --age=18]

从测试结果上看(笔者目前不敢确定这个优先级顺序是不是常态,但从我的多次测试效果,顺序一直是这样的):

ApplicationRunner执行优先级高于CommandLineRunner

以Bean的形式运行的Runner优先级要低于Component注解加implements Runner接口的方式

Order注解只能保证同类的CommandLineRunner或ApplicationRunner的执行顺序,不能跨类保证顺序

四、总结

CommandLineRunner、ApplicationRunner的核心用法是一致的,就是用于应用启动前的特殊代码执行。ApplicationRunner的执行顺序先于CommandLineRunner;ApplicationRunner将参数封装成了对象,提供了获取参数名、参数值等方法,操作上会方便一些。

五、问题总结

这是笔者在实践中真实遇到的问题,就是我定义了多个CommandLineRunner的实现。出现奇怪的问题是:当你定义多个CommandLineRunner的实现的时候,其中一个或者几个将不会执行。

分析一下:下面的代码是SpringBootApplication启动项目之后会执行的代码,大家看代码中通过一个遍历来启动CommandLineRunner或者ApplicationRunner。也就是说,只有上一个CommandLineRunner执行完成之后,才会执行下一个CommandLineRunner,是同步执行的。

private void callRunners(ApplicationContext context, ApplicationArguments args) { List runners = new ArrayList(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); for (Object runner : new LinkedHashSet(runners)) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } } }

所以,如果在CommandLineRunner某个实现run 方法体中调用了同步阻塞的API或者是一个 while(true) 循环,在遍历中处于该CommandLineRunner之后的其他实现将不会被执行。

到此,相信大家对"springboot应用服务启动事件的监听怎么实现"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report