前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >20-SpringBoot事件监听

20-SpringBoot事件监听

作者头像
Devops海洋的渔夫
发布2022-03-23 16:13:32
2490
发布2022-03-23 16:13:32
举报
文章被收录于专栏:Devops专栏Devops专栏

20-SpringBoot事件监听

SpringBoot事件监听

Java中的事件监听机制定义了以下几个角色:

①事件:Event,继承 java.util.EventObject 类的对象

②事件源:Source ,任意对象Object

③监听器:Listener,实现 java.util.EventListener 接口 的对象

SpringBoot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作。

  • ApplicationContextInitializer、
  • SpringApplicationRunListener、
  • CommandLineRunner、
  • ApplicationRunner

案例

1.创建一个基础项目 springboot-listener

下面我们来编写实现监听器接口。

2.实现监听器接口

  • ApplicationContextInitializer、
  • SpringApplicationRunListener、
  • CommandLineRunner、
  • ApplicationRunner
2.1 实现 ApplicationContextInitializer
代码语言:javascript
复制
package com.lijw.springbootlistener.listener;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer initialize...");
    }
}
2.2 实现 SpringApplicationRunListener
代码语言:javascript
复制
package com.lijw.springbootlistener.listener;

import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;

import java.time.Duration;

@Component
public class MySpringApplicationRunListener implements SpringApplicationRunListener {

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

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

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

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

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

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("SpringApplicationRunListener ready");
    }

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

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("SpringApplicationRunListener failed");
    }
}
2.3 实现 CommandLineRunner
代码语言:javascript
复制
package com.lijw.springbootlistener.listener;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner run");
    }
}
2.4 实现 ApplicationRunner
代码语言:javascript
复制
package com.lijw.springbootlistener.listener;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

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

3.测试验证

也就说明:MyApplicationRunner和MyCommandLineRunner都是当项目启动后执行,一般我们可以将缓存预热之类的操作放到这里执行。

那么另外的两个监听器要怎么才会启动监听呢?这个先不急,我们来看看 MyApplicationRunner和MyCommandLineRunner 的参数怎么用。

4. MyApplicationRunner和MyCommandLineRunner的参数使用

4.1 打印 MyApplicationRunner和MyCommandLineRunner 的 args 参数
代码语言:javascript
复制
// 项目启动后执行
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner run... args: " + Arrays.asList(args));
    }
}
代码语言:javascript
复制
// 项目启动后执行
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner run... args: " + Arrays.asList(args.getSourceArgs()));
    }
}

打印信息如下:

可以看到,现在传递的参数为空数组。

如果需要传递参数,则是可以配置在项目的启动命令上。

4.2 配置项目的启动命令

此时,再启动服务,我们来看看传递的参数如下:

5.配置使用 MyApplicationContextInitializer 和 MySpringApplicationRunListener 的监听器

5.1 需要在 META-INF/spring.factories 配置注册两个实现类
代码语言:javascript
复制
org.springframework.context.ApplicationContextInitializer=com.lijw.springbootlistener.listener.MyApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=com.lijw.springbootlistener.listener.MySpringApplicationRunListener

此时,我们再执行启动服务,可以发现报错如下:

代码语言:javascript
复制
// main方法中出现异常,异常由于接口MySpringApplicationRunListener实现类报错
Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.boot.SpringApplicationRunListener : com.lijw.springbootlistener.listener.MySpringApplicationRunListener
 at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:456)
 at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:438)
 at org.springframework.boot.SpringApplication.getRunListeners(SpringApplication.java:426)
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:293)
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
 at com.lijw.springbootlistener.SpringbootListenerApplication.main(SpringbootListenerApplication.java:10)
// MySpringApplicationRunListener报错的类型为缺少方法,缺少了 <init>(org.springframework.boot.SpringApplication, [Ljava.lang.String;) 也就是缺少了 构造器方法。
Caused by: java.lang.NoSuchMethodException: com.lijw.springbootlistener.listener.MySpringApplicationRunListener.<init>(org.springframework.boot.SpringApplication, [Ljava.lang.String;)
 at java.lang.Class.getConstructor0(Class.java:3082)
 at java.lang.Class.getDeclaredConstructor(Class.java:2178)
 at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:451)
 ... 6 more

Process finished with exit code 1

在查看如何设置构造器的方法上,我们可以查看这个接口的其他实现类:

5.2 MySpringApplicationRunListener的使用要添加构造器
代码语言:javascript
复制
package com.lijw.springbootlistener.listener;

import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import java.time.Duration;

public class MySpringApplicationRunListener implements SpringApplicationRunListener {


    public MySpringApplicationRunListener(SpringApplication application, String[] args){

    }

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

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

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

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

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

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("SpringApplicationRunListener ready");
    }

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

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

执行打印的日志:

代码语言:javascript
复制
SpringApplicationRunListener starting..
SpringApplicationRunListener environmentPrepared..

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

ApplicationContextInitializer initialize...
SpringApplicationRunListener contextPrepared
2022-02-27 08:54:55.785  INFO 15164 --- [           main] c.l.s.SpringbootListenerApplication      : Starting SpringbootListenerApplication using Java 1.8.0_91 on regalli-NB0 with PID 15164 (D:\javaProject\maven-practice01\springboot-listener\target\classes started by lijw in D:\javaProject\maven-practice01)
2022-02-27 08:54:55.785  INFO 15164 --- [           main] c.l.s.SpringbootListenerApplication      : No active profile set, falling back to 1 default profile: "default"
SpringApplicationRunListener contextLoaded
2022-02-27 08:54:56.255  INFO 15164 --- [           main] c.l.s.SpringbootListenerApplication      : Started SpringbootListenerApplication in 0.9 seconds (JVM running for 1.838)
SpringApplicationRunListener started
ApplicationRunner run... args: [name=libai, age=32]
CommandLineRunner run... args: [name=libai, age=32]
SpringApplicationRunListener ready

Process finished with exit code 0
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 20-SpringBoot事件监听
    • SpringBoot事件监听
      • 案例
        • 1.创建一个基础项目 springboot-listener
        • 2.实现监听器接口
        • 3.测试验证
        • 4. MyApplicationRunner和MyCommandLineRunner的参数使用
        • 5.配置使用 MyApplicationContextInitializer 和 MySpringApplicationRunListener 的监听器
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档