关于spring:SpringBoot教程-SpringBoot中ApplicationEvent用法

54次阅读

共计 3472 个字符,预计需要花费 9 分钟才能阅读完成。

前言

咱们后面的文章中解说过 RabbitMQ 的用法,所谓 MQ 就是一种公布订阅模式的音讯模型。在 Spring 中其实自身也为咱们提供了一种公布订阅模式的事件处理形式,就是 ApplicationEvent 和 ApplicationListener,这是一种基于观察者模式实现事件监听性能。也已帮忙咱们实现业务逻辑的解耦,进步程序的扩展性和可维护性。

然而这里要留神 ApplicationEvent 和 MQ 队列尽管实现的性能类似,然而 MQ 还是有其不可替代性的,最实质的区别就是 MQ 能够用于不同零碎之间的音讯公布,而 SpringEvent 这种模式只能在一个零碎中,也就是要求必须是同一个 Spring 容器。

好了接下来咱们就来演练一番。

在这个模型中,有两个重要的类,一个是事件,一个是监听。事件要继承 ApplicationEvent 类,监听要实现 ApplicationListener 接口。

一、开发 ApplicationEvent 事件

事件其实就是咱们要发送的音讯体,这个个别要依据咱们的理论业务进行封装,须要什么类型的数据,就是用什么类型,须要哪些字段就增加哪些字段。咱们来给一个案例。

package com.lsqingfeng.springboot.applicationEvent;
 
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
 
/**
 * @className: MyApplicationEvent
 * @description: 事件封装
 * @author: sh.Liu
 * @date: 2022-03-23 14:41
 */
@Getter
@Setter
@ToString
public class MyApplicationEvent extends ApplicationEvent {
 
    private Integer age;
 
    private String name;
 
    /**
     * 须要重写构造方法
     * @param source
     * @param name
     * @param age
     */
    public MyApplicationEvent(Object source, String name, Integer age) {super(source);
        this.name = name;
        this.age = age;
    }
}

二、开发监听器

监听器就相当于咱们的 MQ 的消费者,当有工夫推送过去的时候,监听器的代码就能够执行。这里通过泛型来设置好咱们的事件类型。

package com.lsqingfeng.springboot.applicationEvent;
 
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
 
/**
 * @className: MyApplicationEventListener
 * @description: 事件监听器
 * @author: sh.Liu
 * @date: 2022-03-23 14:50
 */
@Component
public class MyApplicationEventListener implements ApplicationListener<MyApplicationEvent> {
 
    @Override
    public void onApplicationEvent(MyApplicationEvent event) {System.out.println("收到音讯:" + event);
    }
}

三、推送事件

推送事件须要应用 ApplicationEventPublisher。这个对象在 Spring 容器加载的时候就曾经在容器中了。所以咱们能够间接注入应用, 也能够应用 ApplicationContext, 因为 ApplicationContext 自身就继承了 ApplicationEventPublisher。咱们通过一个 Controller 来验证一下。

package com.lsqingfeng.springboot.controller;
 
import com.lsqingfeng.springboot.applicationEvent.MyApplicationEvent;
import com.lsqingfeng.springboot.base.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
/**
 * @className: ApplicationEventController
 * @description:
 * @author: sh.Liu
 * @date: 2022-03-23 15:21
 */
@RestController
@RequestMapping("event")
public class ApplicationEventController {
 
    @Autowired
    private ApplicationContext applicationContext;
 
    @RequestMapping("/push")
    public Result pushEvent(){MyApplicationEvent myApplicationEvent = new MyApplicationEvent(this,"zhangsan", 10);
        applicationContext.publishEvent(myApplicationEvent);
        return Result.success();}
 
    @RequestMapping("/push2")
    public Result pushEvent2(){applicationContext.publishEvent("大家好");
        return Result.success();}
}

咱们定义两个推送的办法。一个推送咱们的 MyApplicationEvent 类型,还有一个办法推送一个字符串。

当咱们调用第一个办法的时候,控制台能够打印出咱们推送的数据信息。

调用推送字符串的时候,咱们的监听器不会执行,起因是咱们的拦截器里曾经加了泛型 MyApplicationEvent,也就是只会监听 MyApplicationEvent 类型的音讯。其余类型的音讯不会被监听到。

那如果咱们把泛型去掉会有什么成果呢,咱们来试试。

每次推送都会发送两条(可能有什么外部机制,不论了),然而两个都打印了,阐明如果不加泛型,不论谁推,这边都能收到音讯。

四、注解形式实现监听器

除了下面的通过实现接口的形式开发监听器,咱们还能够通过注解的形式来实现,具体代码如下。

package com.lsqingfeng.springboot.applicationEvent;
 
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
/**
 * @className: MyApplicationEventListener2
 * @description: 注解实现监听器
 * @author: sh.Liu
 * @date: 2022-03-23 15:56
 */
@Component
public class MyApplicationEventListener2 {
 
    @EventListener
    public void onEvent(MyApplicationEvent event){System.out.println("收到音讯 2:" + event);
    }
 
 
}

这里退出了 @EventListener 注解代表了这是一个监听器。办法名随便,办法里的参数代表监听的事件类型。

再次调用 push 办法:

发现两个监听器的数据都会打印。这一特点大家要留神一下。

好了,对于 Spring 中的 ApplicationEvent 和 ApplicationListener 咱们就介绍这么多。

正文完
 0