Spring 事件发布机制

目录

 

1、重要角色

2、ApplicationEvent

3、ApplicationListener

4、ApplicationEventMulticaster

5、疑问:ApplicationEventMulticaster何时初始化?监听器又是何时添加到defaultRetriever里的?

6、ApplicationEventPublisher(实际上就是AbstractApplicationContext)


1、重要角色

(1)ApplicationEvent:发布的事件

(2)ApplicationListener:事件监听器,处理发布的事件

(3)ApplicationEventMulticaster:事件发布者;维护所有已注册的监听器、缓存事件->监听器的映射,让监听器监听并处理对应的事件;multicast可以理解为事件统一在这里发布

(4)ApplicationEventPublisher:发布事件的时候,一般不会直接使用ApplicationEventMulticaster,而是通过ApplicationEventPublisher.publishEvent,再调用ApplicationEventMulticaster发布事件;ApplicationContext就是它的子接口

2、ApplicationEvent

/**
 * 一个抽象类,自定义的事件必须继承它
 * 继承了EventObject,JDK事件规范的类
 */
public abstract class ApplicationEvent extends EventObject {

 /** System time when the event happened */
 //事件何时发生
 private final long timestamp;

 /**
  * Create a new ApplicationEvent.
  * source:事件源,即事件发生在哪个对象
  * @param source the object on which the event initially occurred (never {@code null})
  */
 public ApplicationEvent(Object source) {
  super(source);
  this.timestamp = System.currentTimeMillis();
 }

}

3、ApplicationListener

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

 /**
  * Handle an application event.
  * 处理一个事件
  * @param event the event to respond to
  */
 void onApplicationEvent(E event);

}

4、ApplicationEventMulticaster

(1)AbstractApplicationEventMulticaster

//实现了基本的监听器注册功能,最关键的multicastEvent方法留给子类实现
public abstract class AbstractApplicationEventMulticaster
  implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {

 //ListenerRetriever是定义的一个内部类,可以理解为封装多个监听器的集合
 //维护着所有已添加的监听器
 private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);

 //ListenerCacheKey是定义的一个内部类,是通过事件+事件源(EventType+SourceType)得出的一个key
 //缓存了事件->监听器的1对多映射
 final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
   new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);

 //同步操作时的互斥锁
 private Object retrievalMutex = this.defaultRetriever;

 /**
  * 获取指定事件匹配的监听器
  * 1、从缓存获取
  * 2、缓存没有,遍历defaultRetriever获取并缓存
  */
 protected Collection<ApplicationListener<?>> getApplicationListeners(
   ApplicationEvent event, ResolvableType eventType) {

  Object source = event.getSource();
  Class<?> sourceType = (source != null ? source.getClass() : null);
  //根据事件类型和事件源类型构建出key
  ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

  // Quick check for existing entry on ConcurrentHashMap...
  //根据key先从缓存查对应的监听器
  ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
  if (retriever != null) {
   return retriever.getApplicationListeners();
  }

  if (this.beanClassLoader == null ||
    (ClassUtils.isCacheSafe(event.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值