Spring 事件发布与监听

178 阅读2分钟

👉 Java的事件机制

Java中的事件机制一般包括3个部分:EventObject、EventListener 和 Source

  • EventObject:java.util.EventObject是事件状态对象的基类,它封装了事件源对象以及和事件相关的信息。所有java的事件类都需要继承该类
  • EventListener:java.util.EventListener是一个标记接口,就是说该接口内是没有任何方法的。所有事件监听器都需要实现该接口。事件监听器注册在事件源上,当事件源的属性或状态改变的时候,调用相应监听器内的回调方法
  • Source:事件源不需要实现或继承任何接口或类,它是事件最初发生的地方。因为事件源需要注册事件监听器,所以事件源内需要有相应的盛放事件监听器的容器

👉 Spring 的事件

ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。

ApplicationEvent:Spring提供的事件接口

ApplicationListener:Spring提供的事件监听接口,所有的监听器都实现该接口

ApplicationEventPublisher:Spring提供的事件发布接口,ApplicationContext实现了该接口

ApplicationEventMulticaster:Spring事件机制中的事件广播器,

👉 代码实现

  • 事件类
package com.mars.plateform.event;

import org.springframework.context.ApplicationEvent;

/***
 * @project: java-base
 * @package: com.mars.plateform.event
 * @description: 基础事件类
 * @author: kyrie
 * @mail: 18654169290@163.com
 * @createDate: 2022/3/16 09:37
 */
public class BaseEventRegister<T> extends ApplicationEvent {
    /**
     * Create a new {@code ApplicationEvent}.
     *
     * @param source the object on which the event initially occurred or with
     *               which the event is associated (never {@code null})
     */
    public BaseEventRegister(Object source) {
        super(source);
    }
}
  • 事件注册Service:用于发布事件
package com.mars.plateform.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

/***
 * @project: java-base
 * @package: com.mars.plateform.event
 * @description: 执行事件注册及发布事件消息
 * @author: kyrie
 * @mail: 18654169290@163.com
 * @createDate: 2022/3/16 09:41
 */
@Service
public class SendMsgEventPublisher implements ApplicationEventPublisherAware {

    private static ApplicationEventPublisher eventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        if (null == eventPublisher) {
            eventPublisher = applicationEventPublisher;
        }
    }

    public void publishEvent(BaseEventRegister<MqModel> eventRegister) {
        // 发布事件
        eventPublisher.publishEvent(eventRegister);
    }
    
    public void publishMqEvent(String topic, String tag, String message) {
        // 组装消息体
        this.publishEvent(new BaseEventRegister<>(new MqModel(topic, tag, message)));
    }
}
  • controller层注入Service,实现业务逻辑中的事件发布动作
package com.mars.plateform.event;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

/***
 * @project: java-base
 * @package: com.mars.plateform.event
 * @description:
 * @author: kyrie
 * @mail: 18654169290@163.com
 * @createDate: 2022/3/16 09:55
 */
@RestController

public class TestEventController {
    @Resource
    private SendMsgEventPublisher msgEventPublisher;

    @GetMapping("/testEvent")
    public void test() {
        // 主逻辑
        System.out.println("主程序逻辑....");
        // 发布事件
        msgEventPublisher.publishMqEvent("topic", "tag", "testMsg");
    }

}
  • 实体类
package com.mars.plateform.event;
import java.io.Serializable;

/***
 * @project: java-base
 * @package: com.mars.plateform.event
 * @description:
 * @author: kyrie
 * @mail: 18654169290@163.com
 * @createDate: 2022/3/16 09:57
 */

public class MqModel implements Serializable {

    private String topic;

    private String tag;

    private String message;

    public MqModel(String topic, String tag, String message) {

        this.topic = topic;

        this.tag = tag;

        this.message = message;

    }

    public String getTopic() {

        return topic;

    }

    public void setTopic(String topic) {

        this.topic = topic;

    }

    public String getTag() {

        return tag;

    }

    public void setTag(String tag) {

        this.tag = tag;

    }

    public String getMessage() {

        return message;

    }

    public void setMessage(String message) {

        this.message = message;
    }

}
  • 事件监听器,监听事件并自动执行定义的事件
package com.mars.plateform.event;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

/***
 * @project: java-base
 * @package: com.mars.plateform.event
 * @description: 事件监听,监听到事件后,自动执行onApplicationEvent方法
 * @author: kyrie
 * @mail: 18654169290@163.com
 * @createDate: 2022/3/16 09:50
 */
@Component
//方式一(无事务型):public class SendMqEventListener implements ApplicationListener<BaseEventRegister> {
public class SendMqEventListener {

    // 方式二(注解型,同方式一)@EventListener
    // 方式三(事务型)@TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMMIT)
    @TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMMIT)
    public void onApplicationEvent(BaseEventRegister event) {
        // 发邮件
        System.out.println("正在发邮件...");
        // 发短信
        System.out.println("正在发短信...");
    }
}

如上监听类中的代码所示,可以多种方式实现事件的监听,其中事务型中注解解释如下:

  • fallbackException:用于发射事件的地方没有事务时添加的参数,表示如果没有事务运行时,是否处理事件,默认为false
  • phase:表示在事务环境下,什么时候执行事件,共有四个枚举:BEFORE_COMMIT、AFTER_COMMIT、AFTER_ROLLBACK、AFTER_COMPLETION,默认为AFTER_COMMIT