当前位置: 首页 > article >正文

Spring源码分析之事件机制——观察者模式(一)

目录

事件基类定义

事件监听器接口

事件发布者接口及实现

事件广播器实现

小小总结


Spring源码分析之事件机制——观察者模式(一)-CSDN博客

Spring源码分析之事件机制——观察者模式(二)-CSDN博客

Spring源码分析之事件机制——观察者模式(三)-CSDN博客

这两篇文章是这个篇章的后篇,感兴趣的读者可以阅读一下,从spring源码分析观察者模式

事件基类定义

public abstract class ApplicationEvent extends EventObject {
    // 事件发生的时间戳
    private final long timestamp;
    
    public ApplicationEvent(Object source) {
        // source表示事件源,即发布事件的对象
        super(source);
        this.timestamp = System.currentTimeMillis();
    }

    // 获取事件发生时间
    public final long getTimestamp() {
        return this.timestamp;
    }
}

ApplicationEvent作为所有Spring事件的基类,继承自Java的EventObject,通过记录时间戳和事件源,为事件提供了基本的元数据信息,使得事件能够携带更多的上下文信息。

事件监听器接口

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    /**
     * 处理应用事件的方法
     * @param event 要响应的事件
     */
    void onApplicationEvent(E event);
}

ApplicationListener接口定义了事件监听器的标准,通过泛型约束限定了具体监听的事件类型,使得监听器能够只关注特定类型的事件,我觉得spring的这种设计既保证了类型安全,又提供了良好的扩展性。

事件发布者接口及实现

@FunctionalInterface
public interface ApplicationEventPublisher {
    /**
     * 发布事件的方法
     * @param event 要发布的事件
     */
    default void publishEvent(ApplicationEvent event) {
        publishEvent((Object) event);
    }

    /**
     * 发布任意对象作为事件
     * @param event 要发布的事件对象
     */
    void publishEvent(Object event);
}

public abstract class AbstractApplicationContext implements ApplicationEventPublisher {
    // 事件广播器
    private ApplicationEventMulticaster applicationEventMulticaster;
    
    // 早期事件缓存,用于存储容器未完全初始化前的事件
    private Set<ApplicationEvent> earlyApplicationEvents;
    
    @Override
    public void publishEvent(Object event) {
        // 确保事件对象是ApplicationEvent类型
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        } else {
            // 将普通对象包装为PayloadApplicationEvent
            applicationEvent = new PayloadApplicationEvent<>(this, event);
        }
        
        // 如果容器还在初始化,则将事件添加到早期事件集合
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        } else {
            // 通过事件广播器发布事件
            getApplicationEventMulticaster().multicastEvent(applicationEvent);
        }
        
        // 如果存在父容器,则同时发布到父容器
        if (this.parent != null) {
            this.parent.publishEvent(event);
        }
    }
    
    // 初始化事件广播器
    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 如果容器中已定义了广播器,则使用已定义的
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster = 
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        } else {
            // 否则创建一个简单的事件广播器
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        }
    }
}

AbstractApplicationContext实现了事件发布的核心逻辑,通过事件广播器将事件分发给所有相关的监听器,同时处理了事件的向上传播和早期事件的缓存。

事件广播器实现

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    // 任务执行器,用于异步事件处理
    @Nullable
    private Executor taskExecutor;
    
    // 错误处理器
    @Nullable
    private ErrorHandler errorHandler;
    
    @Override
    public void multicastEvent(ApplicationEvent event) {
        // 解析事件类型并广播
        multicastEvent(event, resolveDefaultEventType(event));
    }
    
    @Override
    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        // 解析事件类型
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        
        // 获取所有匹配的监听器并执行
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                // 异步执行
                executor.execute(() -> invokeListener(listener, event));
            } else {
                // 同步执行
                invokeListener(listener, event);
            }
        }
    }
    
    protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        ErrorHandler errorHandler = getErrorHandler();
        if (errorHandler != null) {
            try {
                doInvokeListener(listener, event);
            } catch (Throwable err) {
                errorHandler.handleError(err);
            }
        } else {
            doInvokeListener(listener, event);
        }
    }
}

SimpleApplicationEventMulticaster提供了事件广播的具体实现,支持同步和异步两种事件处理方式,并提供了错误处理机制,通过这种设计,使得事件的处理更加灵活和可靠,同时也为性能优化提供了可能。

小小总结

Spring的事件机制通过这些精心设计的组件,构建了一个完整的观察者模式实现,它不仅支持Spring框架内部的事件处理,也为应用程序提供了一个强大的事件驱动架构基础,通过这种方式,可以实现组件间的松耦合通信,提高系统的可维护性和扩展性。整个实现考虑了性能、可靠性和易用性等多个方面,是一个非常典型的观察者模式应用案例。


http://www.kler.cn/a/465715.html

相关文章:

  • 代码随想录算法【Day11】
  • Go语言的 的并发编程(Concurrency)核心知识
  • oscp备考 oscp系列——Kioptix Level 1靶场 古老的 Apache Vuln
  • C++虚函数(八股总结)
  • 数势科技:解锁数据分析 Agent 的智能密码(14/30)
  • 【项目开发】C#环境配置及VScode运行C#教程(学生管理系统)
  • 硬件-射频-PCB-常见天线分类-ESP32实例
  • 855. 考场就座
  • 线性代数自学资源推荐我的个人学习心得
  • Java 代码审计入门-07】SQL关键字
  • HTML5新特性|05 CSS3边框CSS3背景
  • 每天40分玩转Django:Django性能优化
  • wpf 国际化 try catch comboBox
  • C# 设计模式(结构型模式):享元模式
  • 如何在iOS 11 中禁用高效图像格式 (HEIF)
  • 【Vim Masterclass 笔记01】Section 1:Course Overview + Section 2:Vim Quickstart
  • 适用不同业务场景的6种销售预测模型
  • WPF自定义任务栏缩略图
  • CSS进阶和SASS
  • halcon三维点云数据处理(二)
  • 《向量数据库指南》混合检索系统的深度探索与实践:从POC到生产级解决方案的构建
  • 毕设中所学
  • MCA:用于图像识别的深度卷积神经网络中的多维协同注意力
  • MAC录屏QuikTimePlayer工具录屏声音小免费解决方案
  • 机器学习之模型评估——混淆矩阵,交叉验证与数据标准化
  • PyQt下载M3U8文件