ApplicationListener和@EventListener

前言

    在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,那就是事件监听,事件监听也是设计模式中 发布-订阅模式、观察者模式的一种实现。

    观察者模式:简单的来讲就是你在做事情的时候身边有人在盯着你,当你做的某一件事情是旁边观察的人感兴趣的事情的时候,他会根据这个事情做一些其他的事,但是盯着你看的人必须要到你这里来登记,否则你无法通知到他(或者说他没有资格来盯着你做事情)。

    对于 Spring 容器的一些事件,可以监听并且触发相应的方法。通常的方法有 2 种: ApplicationListener 接口和**@EventListener** 注解。一个作用在类上,一个作用在方法上。

概念:

    要想顺利的创建监听器,并起作用,这个过程中需要这样几个角色:

  •     1、事件(event)可以封装和传递监听器中要处理的参数,如对象或字符串,并作为监听器中监听的目标。
  •     2、监听器(listener)具体根据事件发生的业务处理模块,这里可以接收处理事件中封装的对象或字符串。
  •     3、事件发布者(publisher)事件发生的触发者。

实现ApplicationListener 接口

原生事件

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
 
@Override
public void onApplicationEvent(ApplicationEvent event) {
  System.out.println("事件触发:"+event.getClass().getName());
}
@SpringBootApplication
public class ApplicationListenerDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationListenerDemoApplication.class, args);
    }
}
事件触发:org.springframework.context.event.ContextRefreshedEvent
2021-01-24 22:09:20.113  INFO 9228 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
事件触发:org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent
2021-01-24 22:09:20.116  INFO 9228 --- [           main] c.n.ApplicationListenerDemoApplication   : Started ApplicationListenerDemoApplication in 1.221 seconds (JVM running for 1.903)
事件触发:org.springframework.boot.context.event.ApplicationStartedEvent
事件触发:org.springframework.boot.context.event.ApplicationReadyEvent

自定义事件

事件

public class MyTestEvent extends ApplicationEvent{
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private String msg ;

    public MyTestEvent(Object source,String msg) {
        super(source);
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

监听器

@Component
public class MyNoAnnotationListener implements ApplicationListener<MyTestEvent> {

    @Override
    public void onApplicationEvent(MyTestEvent event) {
        System.out.println("非注解监听器:" + event.getMsg());
    }

}

事件发布

@Component
public class MyTestEventPubLisher {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     *  事件发布方法
      */
    public void pushListener(String msg) {
        applicationEventPublisher.publishEvent(new MyTestEvent(this, msg));
    }

}

测试:

@RestController
public class TestEventListenerController {

    @Autowired
    private MyTestEventPubLisher publisher;

    @RequestMapping(value = "/test/testPublishEvent1" )
    public void testPublishEvent(){
        publisher.pushListener("我来了!");
    }
}

输出:

事件触发:com.njit.personal.unannotation.MyTestEvent
非注解监听器:我来了!

@EventListener 注解

原生事件

@Configuration
public class Config {
    @EventListener(classes = {ApplicationEvent.class})
    public void listen(ApplicationEvent event) {
        System.out.println("事件触发:" + event.getClass().getName());
    }
}

启动项目:

事件触发:org.springframework.context.event.ContextRefreshedEvent
2021-01-24 22:39:13.647  INFO 16072 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
事件触发:org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent
2021-01-24 22:39:13.650  INFO 16072 --- [           main] c.n.ApplicationListenerDemoApplication   : Started ApplicationListenerDemoApplication in 1.316 seconds (JVM running for 2.504)
事件触发:org.springframework.boot.context.event.ApplicationStartedEvent
事件触发:org.springframework.boot.context.event.ApplicationReadyEvent

自定义事件

监听器

//事件和发布还是使用上边的
@Component
public class MyAnnotationListener {

    @EventListener
    public void listener1(MyTestEvent event) {
        System.out.println("注解监听器1:" + event.getMsg());
    }
}
事件触发:com.njit.personal.unannotation.MyTestEvent
注解监听器1:我来了!
非注解监听器:我来了!

项目常用

@EventListener(AvailabilityChangeEvent.class)
public void init(AvailabilityChangeEvent<ReadinessState> event) {
   //项目启动会触发监听器,下面写一些业务逻辑
   ....
}

或者

@Component
public class MyApplicationListener implements ApplicationListener<AvailabilityChangeEvent> {
 
@Override
public void onApplicationEvent(ApplicationEvent event) {
   //项目启动会触发监听器,下面写一些业务逻辑
   ....
}

猜你喜欢

转载自blog.csdn.net/qq_16504067/article/details/131550315