Spring事件机制

一、引言

在分布式场景下,实现同步转异步的方式有三种方式:

  1. 异步线程池执行;比如借助@Async注解,放到Spring自带的线程池中去执行,或者其他方式的异步线程去执行
  2. 放到消息队列中,在消费者的代码中异步的消费,执行相关的逻辑
  3. 基于Spring的事件机制,触发事件,在监听器里实现相关逻辑

二、概要

Spring事件发送监听涉及3个部分

  • 事件源: 对应具体的事件。
  • 事件监听器:,负责接收具体的事件源。
  • 事件广播器(发送器):, 负责发布事件源。
    相应的处理逻辑为:事件监听器会注册具体的事件源,当事件广播器广播具体的事件源后,事件监听器能接到该事件的发布消息,然后处理相关事件。

1.事件源

事件源
在这里插入图片描述

2.事件广播

在这里插入图片描述
Spring提供了ApplicationEventPublisher接口作为事件发布者,并且ApplicationContext接口继承了该接口,担当着事件发布者的角色。但ApplicationContext接口的具体实现各有差异。Spring提供了ApplicationEventMulticaster接口,负责管理ApplicationListener和发布ApplicationEventApplicationContext接口会把事件的相关工作委托ApplicationEventMulticaster的实现类处理。发布事件context.publishEvent(event); 实际上是由ApplicationContext的实现AbstractApplicationContext执行发布事件的行为
在这里插入图片描述
执行SimpleApplicationEventMulticaster中的multicastEvent方法,调用事件监听器的onApplicationEvent()方法
在这里插入图片描述

3.事件监听器

事件监听器

三、Spring事件机制的使用

1.使用步骤

  • 事件源extends ApplicationEvent
  • 事件监听器implements ApplicationListener<事件源>并声明其为spring组件

声明组件这里要注意一点,在 Spring 中,有一些事件是在创建
ApplicationContext 之前触发的,比如 ApplicationStartingEvent 和
ApplicationEnvironmentPreparedEvent 等事件。这些事件是在 SpringBoot 启动过程的早期阶段触发的,因此您不能将这些事件上的侦听器注册@Bean。
为了解决早期事件注册侦听器的问题,SpringBoot提供了SpringApplication.addListeners()

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringApplication.class);
    app.addListeners(new NotifyListener());
    app.run(args);
}

或者,src/main/resources/META-INF/spring.factories文件中声明:

org.springframework.context.ApplicationListener=com.xmc.event.NotifyListener

然而,普通事件上的侦听器采用 @EventListener,或者直接添加 @Component

@Configuration
public class NotifyListenerConfig {

    @EventListener(NotifyEvent.class)
    public void onApplicationStartedEvent(NotifyEvent event) {
        System.out.println("配置方式:"+event.getContent());
        System.out.println("配置方式:"+event.getEmail());
    }
}
  • 发布事件://发布事件context.publishEvent(event);

2.代码示例

事件源

public class NotifyEvent extends ApplicationEvent {
    private String email;
    private String content;

    public NotifyEvent(Object source) {
        super(source);
    }
    public NotifyEvent(Object source, String email, String content) {
        super(source);
        this.email = email;
        this.content = content;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

事件监听器

@Component
public class NotifyListener implements ApplicationListener<NotifyEvent> {
    @Override
    public void onApplicationEvent(NotifyEvent event) {
        System.out.println(event.getContent());
        System.out.println(event.getEmail());
    }
}

事件发布

@SpringBootTest
public class ListenerTest {
    @Autowired
    private WebApplicationContext webApplicationContext;
    @Test
    public void testListener() {
        NotifyEvent event = new NotifyEvent("object", "abc@qq.com", "This is the content");
        webApplicationContext.publishEvent(event);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值