Spring系列17:Spring事件发布详解

本文详细介绍了Spring的事件发布机制,包括实现原理、编程式自定义事件、基于注解的事件监听,如监听单个事件、多个事件、监听方法结果作为新事件发布等。同时,讲解了异步事件处理、使用@Order定义监听器顺序、泛型化事件结构以及发布任意对象的事件。文章提供了丰富的示例代码,帮助读者深入理解Spring事件系统。
摘要由CSDN通过智能技术生成

本文内容

  1. 实现原理和标准事件
  2. 编程式实现自定义事件
  3. 基于注解的自定义事件
  4. 通用事件

实现原理和标准事件

Spring中的事件发布本质上是标准的观察者设计模式。ApplicationContext 中的事件处理是通过 ApplicationEvent 类和 ApplicationListener 接口提供的。如果将实现 ApplicationListener 接口的bean部署到上下文中,则每次将 ApplicationEvent 发布到 ApplicationContext 时,该bean都会得到通知。

public abstract class ApplicationEvent extends EventObject {

    // 事件源
    public ApplicationEvent(Object source) {
        super(source);
        this.timestamp = System.currentTimeMillis();
    }

    public final long getTimestamp() {
        return this.timestamp;
    }

}
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    // 处理事件
    void onApplicationEvent(E event);

}

下表描述了 Spring 提供的标准事件:

事件 解释
ContextRefreshedEvent 在初始化或刷新时发布ApplicationContext(例如,通过使用接口refresh()上的方法ConfigurableApplicationContext)。这里,“初始化”意味着所有 bean 都已加载,后处理器 bean 被检测并激活,单例被预先实例化,并且ApplicationContext对象已准备好使用。只要上下文没有关闭,就可以多次触发刷新,前提是所选择的ApplicationContext实际支持这种“热”刷新。例如,XmlWebApplicationContext支持热刷新,但 GenericApplicationContext不支持。
ContextStartedEvent 使用接口上的方法 ApplicationContext启动时发布。在这里,“已启动”意味着所有 bean 都接收到一个明确的启动信号。通常,此信号用于在显式停止后重新启动 bean,但它也可用于启动尚未配置为自动启动的组件(例如,尚未在初始化时启动的组件)。start()``ConfigurableApplicationContext``Lifecycle
ContextStoppedEvent 使用接口上的方法 ApplicationContext停止时发布。在这里,“停止”意味着所有 的 bean 都会收到一个明确的停止信号。可以通过 调用重新启动已停止的上下文。stop()``ConfigurableApplicationContext``Lifecycle``start()
ContextClosedEvent ApplicationContext使用接口close()上的方法ConfigurableApplicationContext或通过 JVM 关闭挂钩关闭时发布。在这里,“关闭”意味着所有的单例 bean 都将被销毁。一旦上下文关闭,它就到了生命的尽头,无法刷新或重新启动。
RequestHandledEvent 一个特定于 Web 的事件,告诉所有 bean 一个 HTTP 请求已得到服务。此事件在请求完成后发布。此事件仅适用于使用 Spring 的 Web 应用程序DispatcherServlet
ServletRequestHandledEvent 它的子类RequestHandledEvent添加了 Servlet 特定的上下文信息。

编程式实现自定义事件

  1. 定义事件继承 ApplicationEvent

    public class BlockedListEvent extends ApplicationEvent {
    
        private final String address;
        private final String content;
    
        public BlockedListEvent(Object source, String address, String content) {
            super(source);
            this.address = address;
            this.content = content;
        }
    
        public String getAddress() {
            return address;
        }
    
        public String getContent() {
            return content;
        }
    }
  2. 定义事件监听器实现 ApplicationListener

    @Component
    public class BlockedListListener implements ApplicationListener<BlockedListEvent> {
        // @Async
        @Override
        public void onApplicationEvent(BlockedListEvent event) {
            System.out.println("收到邮件禁用发送通知,地址: " + event.getAddress() + "  内容: " + event.getContent());
    
        }
    }
  3. 业务类注入 ApplicationEventPublisher 用于发布事件

    @Component
    public class EmailSendService {
        @Autowired
        private ApplicationEventPublisher publisher;
        // 邮件黑名单
        private List<String> blockedList;
    
    
   public void sendEmail(String address, Strin
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值