Springboot中AbstractApplicationEventMulticaster有什么作用

发布时间:2021-11-17 10:05:38 作者:iii
来源:亿速云 阅读:139
# Spring Boot中AbstractApplicationEventMulticaster有什么作用

## 目录
1. [引言](#引言)  
2. [Spring事件机制概述](#spring事件机制概述)  
   2.1 [观察者模式与Spring事件](#观察者模式与spring事件)  
   2.2 [核心组件组成](#核心组件组成)  
3. [AbstractApplicationEventMulticaster源码解析](#abstractapplicationeventmulticaster源码解析)  
   3.1 [类继承体系](#类继承体系)  
   3.2 [核心字段分析](#核心字段分析)  
   3.3 [关键方法实现](#关键方法实现)  
4. [实际工作流程](#实际工作流程)  
   4.1 [事件广播流程](#事件广播流程)  
   4.2 [监听器匹配机制](#监听器匹配机制)  
5. [扩展与自定义](#扩展与自定义)  
   5.1 [自定义事件广播器](#自定义事件广播器)  
   5.2 [性能优化实践](#性能优化实践)  
6. [与其他组件协作](#与其他组件协作)  
   6.1 [与ApplicationContext的关系](#与applicationcontext的关系)  
   6.2 [与TransactionSynchronization的整合](#与transactionsynchronization的整合)  
7. [常见问题排查](#常见问题排查)  
8. [总结](#总结)  

---

## 引言

在Spring框架的事件驱动模型中,`AbstractApplicationEventMulticaster`作为事件广播器的核心抽象实现,承担着**事件监听器管理**和**事件分发调度**的双重职责。本文将深入剖析其设计原理、工作机制及实践应用场景。

```java
// 典型使用示例
ApplicationEvent event = new MyCustomEvent("event data");
applicationContext.publishEvent(event);

Spring事件机制概述

观察者模式与Spring事件

Spring事件机制基于经典的观察者模式实现: - 事件源ApplicationEvent子类 - 观察者ApplicationListener实现 - 调度中心ApplicationEventMulticaster接口

classDiagram
    class ApplicationEvent
    class ApplicationListener
    class ApplicationEventMulticaster
    
    ApplicationEventMulticaster --> ApplicationListener
    ApplicationEventMulticaster --> ApplicationEvent

核心组件组成

组件类型 代表实现类 职责说明
事件广播器 SimpleApplicationEventMulticaster 同步事件分发
AsyncApplicationEventMulticaster 异步事件分发
事件对象 ContextRefreshedEvent 容器刷新事件
监听器容器 ApplicationListenerBean 托管监听器实例

AbstractApplicationEventMulticaster源码解析

类继承体系

public abstract class AbstractApplicationEventMulticaster 
    implements ApplicationEventMulticaster, BeanClassLoaderAware {
    
    private final DefaultListenerRetriever defaultRetriever = new DefaultListenerRetriever();
    private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
    
    // 核心方法省略...
}

核心字段分析

  1. ListenerRetriever:采用双重检测锁实现线程安全的监听器缓存

    protected class ListenerRetriever {
       public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
       public final Set<String> applicationListenerBeans = new LinkedHashSet<>();
    }
    
  2. retrieverCache:基于事件类型的监听器缓存,提升查找效率

关键方法实现

添加监听器

@Override
public void addApplicationListener(ApplicationListener<?> listener) {
    synchronized (this.defaultRetriever) {
        this.defaultRetriever.applicationListeners.add(listener);
        this.retrieverCache.clear();
    }
}

事件广播核心逻辑

protected Collection<ApplicationListener<?>> getApplicationListeners(
        ApplicationEvent event, ResolvableType eventType) {
    
    Object source = event.getSource();
    Class<?> sourceType = (source != null ? source.getClass() : null);
    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
    
    // 尝试从缓存获取
    ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
    if (retriever != null) {
        return retriever.getApplicationListeners();
    }
    
    // 缓存未命中时的处理流程
    if (this.beanClassLoader == null /* 条件判断省略 */) {
        synchronized (this.defaultRetriever) {
            return retrieveApplicationListeners(eventType, sourceType, retriever);
        }
    }
}

实际工作流程

事件广播流程

  1. 事件发布入口

    // AbstractApplicationContext.publishEvent
    @Override
    public void publishEvent(ApplicationEvent event) {
       getApplicationEventMulticaster().multicastEvent(event);
    }
    
  2. 类型解析与监听器匹配

    ResolvableType type = ResolvableType.forInstance(event);
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
       invokeListener(listener, event);
    }
    

监听器匹配机制

匹配规则包括: - 监听器是否支持该事件类型 - 是否通过@EventListener条件表达式过滤 - 是否满足异步执行条件

protected boolean supportsEvent(
    ApplicationListener<?> listener, ResolvableType eventType, Class<?> sourceType) {
    
    GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
            (GenericApplicationListener) listener :
            new GenericApplicationListenerAdapter(listener));
    
    return smartListener.supportsEventType(eventType);
}

扩展与自定义

自定义事件广播器

实现案例:添加事件分发日志

public class LoggingEventMulticaster extends AbstractApplicationEventMulticaster {
    
    @Override
    public void multicastEvent(ApplicationEvent event) {
        log.debug("Dispatching event: {}", event);
        super.multicastEvent(event);
    }
}

性能优化实践

  1. 缓存优化:重写getApplicationListeners方法

    @Override
    protected Collection<ApplicationListener<?>> getApplicationListeners(
           ApplicationEvent event, ResolvableType eventType) {
    
    
       if (event instanceof StatelessEvent) {
           return Collections.unmodifiableSet(this.defaultRetriever.applicationListeners);
       }
       return super.getApplicationListeners(event, eventType);
    }
    
  2. 并发控制:使用CopyOnWriteArrayList替代默认集合

与其他组件协作

与ApplicationContext的关系

sequenceDiagram
    participant Context as ApplicationContext
    participant Multicaster as EventMulticaster
    participant Listener as ApplicationListener
    
    Context->>Multicaster: publishEvent(event)
    Multicaster->>Listener: onApplicationEvent(event)
    Listener-->>Multicaster: 处理完成
    Multicaster-->>Context: 返回控制

与TransactionSynchronization的整合

事务绑定事件发布示例:

TransactionSynchronizationManager.registerSynchronization(
    new TransactionSynchronization() {
        @Override
        public void afterCommit() {
            eventMulticaster.multicastEvent(new AfterCommitEvent());
        }
    });

常见问题排查

  1. 监听器未生效检查清单:

    • 是否注册到Spring容器
    • 事件类型是否匹配
    • 是否被事务拦截器代理
  2. 内存泄漏场景:

    // 错误示例:匿名监听器导致无法销毁
    applicationContext.addApplicationListener(new ApplicationListener() {
       @Override public void onApplicationEvent(ApplicationEvent event) {}
    });
    

总结

AbstractApplicationEventMulticaster作为Spring事件体系的中枢神经,通过: 1. 提供可扩展的监听器管理架构 2. 实现高效的事件类型匹配算法 3. 支持同步/异步分发模式切换

其设计充分体现了Spring框架对扩展开放、对修改关闭的原则。理解其运作机制有助于我们更好地利用Spring的事件驱动模型构建解耦的应用程序。

最佳实践建议:对于高频事件,建议实现自定义的ListenerCacheKey策略以提升匹配效率;对于耗时操作,应当使用异步广播器避免阻塞主线程。 “`

注:本文实际字数为约2500字,要达到8900字需进一步扩展以下内容: 1. 增加各章节的详细案例分析 2. 补充性能测试数据对比 3. 添加更多自定义实现示例 4. 深入源码分析(如ResolvableType的处理机制) 5. 增加与Spring Cloud事件的集成讨论 需要具体扩展哪部分内容可以告诉我。

推荐阅读:
  1. springboot中junit回滚的作用是什么
  2. springboot框架有哪些作用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring boot

上一篇:如何理解Web前端中的主次和学习优先级

下一篇:jquery如何获取tr里面有几个td

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》