【一】相关源代码类

(1)spring的事件发布监听机制的核心管理类:org.springframework.context.event.SimpleApplicationEventMulticaster.

  =>该类的初始化是放在项目加载时,在ioc容器xml配置文件解析加载完毕后,注册bean创建前后置处理实现类(BeanPostProcessor 接口实现),beanFactory配置处理(BeanFactoryPostProcessor接口实现)后,初始化该事件发布监听机制的核心类。

public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // 解析xml配置文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try {
// 注册未来bean实例化的前后置处理的PostProcessor接口实现
postProcessBeanFactory(beanFactory); //执行所有实现BeanFactoryPostProcessor接口实现,对beanFactory进行处理
invokeBeanFactoryPostProcessors(beanFactory); // 注册未来bean实例化的前后置处理的PostProcessor接口实现
registerBeanPostProcessors(beanFactory); // 注册未来bean实例化的前后置处理的PostProcessor接口实现
initMessageSource(); // 实例化spring事件发布监听机制的核心类,SimpleApplicationEventMulticaster
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
onRefresh(); // 注册事件监听器
registerListeners(); // 实例化非懒加载的bean,完成ioc容器中bean的实例化和反转依赖,并在内部实现动态代理相关的操作
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex); // Destroy already created singletons to avoid dangling resources.
destroyBeans(); // Reset 'active' flag.
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
}
}
}

(2)spring的事件发布监听机制的监听器类的接口:org.springframework.context.ApplicationListener<E extends ApplicationEvent>

  =>监听器的定义必须实现该接口。

  =>所监听的事件也必须继承org.springframework.context.ApplicationEvent的抽象类

  =>在初始化管理类后,会注册监听器。会从beanFactory里得到所有实现ApplicationListener接口的bean的名字,并注册到ListenerRetriever的属性applicationListenerBeans集合中。

(3)spring的事件发布监听机制的事件的基础类:org.springframework.context.ApplicationEvent

  =>事件的事件类必须继承该基类

  =>定义监听器的同时,必须定义相关的事件类。

(4)spring的事件发布监听机制的存储事件监听的类:org.springframework.context.event.AbstractApplicationEventMulticaster.ListenerRetriever

    =>该类内部存储了一个n个事件对应的多个监听器

    =>属性Set<ApplicationListener<?>> applicationListeners  存储的是事件监听器的实例

    =>属性Set<String> applicationListenerBeans  存储的事件监听器在ioc容器中的beanNames

(5)spring的事件发布监听机制的存储事件体的类:org.springframework.context.event.AbstractApplicationEventMulticaster.ListenerCacheKey

    =>一个事件体的class类型+事件源(事件体内存储的数据)的class类型决定由那些监听监听器处理该事件

    =>属性Class<?> eventType 存储的事件体的class类型

    =>属性Class<?> sourceType 存储的事件源的class类型(事件体内数据)

【二】设计思想

(1)通过事件体,拿到事件类的cls1类型,和事件源(事件体内部存储的数据类)的cls类型

(2)然后在IOC容器中所有实现ApplicationListener接口的事件监听器中进行匹配。找到所有适合该事件的事件监听器集合。将事件监听集合形成ListenerRetriever对象。

  =>从IOC容器中的一个个事件监听器实现类的范型填充类的类型(也就是事件体的 类型)cls2

  =>Listener可能是代理对象(因为@Async注解),Listenner的ioc在实例化阶段,会被spring创建成代理对象。spring内部也会做处理,得到代理对象代理的targetClass,也就是Listenner的真实类型。

  =>看当前事件体的类型cls1是否是事件监听器的范型填充类的类型cls2的子类或本身。如果是,则表示这个事件监听器匹配该事件。

(3)将该事件体,的事件类的cls1类型+事件源的cls类型。形成ListenerCacheKey对象,以此为key,以事件监听集合ListenerRetriever对象作为value,存储在AbstractApplicationEventMulticaster类中private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);属性中作为cache,方便下次匹配,不再从ioc容器中重新匹配。

【三】事件缓冲,扩展。hasMap中以对象作为key。需要重写hasCode方法,equals方法

private static class ListenerCacheKey {

        private final Class<?> eventType;

        private final Class<?> sourceType;

        public ListenerCacheKey(Class<?> eventType, Class<?> sourceType) {
this.eventType = eventType;
this.sourceType = sourceType;
} @Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
ListenerCacheKey otherKey = (ListenerCacheKey) other;
return ObjectUtils.nullSafeEquals(this.eventType, otherKey.eventType) &&
ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType);
} @Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType);
}
}

【spring源码学习】spring的事件发布监听机制源码解析的更多相关文章

  1. 深入理解Spring的容器内事件发布监听机制

    目录 1. 什么是事件监听机制 2. JDK中对事件监听机制的支持 2.1 基于JDK实现对任务执行结果的监听 3.Spring容器对事件监听机制的支持 3.1 基于Spring实现对任务执行结果的监 ...

  2. Spring事件监听机制源码解析

    Spring事件监听器使用 1.Spring事件监听体系包括三个组件:事件.事件监听器,事件广播器. 事件:定义事件类型和事件源,需要继承ApplicationEvent. package com.y ...

  3. Spring Boot(六)自定义事件及监听

    事件及监听并不是SpringBoot的新功能,Spring框架早已提供了完善的事件监听机制,在Spring框架中实现事件监听的流程如下: 自定义事件,继承org.springframework.con ...

  4. SpringBoot事件监听机制源码分析(上) SpringBoot源码(九)

    SpringBoot中文注释项目Github地址: https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE 本篇接 SpringApplicat ...

  5. Spring笔记(7) - Spring的事件和监听机制

    一.背景 事件机制作为一种编程机制,在很多开发语言中都提供了支持,同时许多开源框架的设计中都使用了事件机制,比如SpringFramework. 在 Java 语言中,Java 的事件机制参与者有3种 ...

  6. 【cocos2d-js官方文档】事件分发监听机制(摘录)

    简介 游戏开发中一个很重要的功能就是交互,如果没有与用户的交互,那么游戏将变成动画,而处理用户交互就需要使用事件监听器了. 总概: 事件监听器(cc.EventListener) 封装用户的事件处理逻 ...

  7. jsonp和事件发布监听

    模拟jsonp var id = 0; function JSONP(url,param,cb){ var callbackName = "json_" + id++; var a ...

  8. Spring知识点回顾(07)事件发布和监听

    Spring知识点回顾(07)事件发布和监听 1.DemoEvent extends ApplicationEvent { public DemoEvent(Object source, String ...

  9. Spring事件发布与监听机制

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 目录 ...

随机推荐

  1. HTML5 SVG世界地图

    在线演示 本地下载

  2. 2018-2019-2 20165114《网络对抗技术》Exp3 免杀原理与实践

    Exp3 免杀原理与实践 目录 一.实验内容 二.基础问题回答 (1)杀软是如何检测出恶意代码的? (2)免杀是做什么? (3)免杀的基本方法有哪些? 三.实践过程记录 正确使用msf编码器,msfv ...

  3. 华为交换机S5700系列配置镜像端口(1:1)

    配置本地镜像口(1:1) 组网需求 如图一所示,某公司行政部通过Switch与外部Internet通信,监控设备Server与Switch直连. 现在希望通过Server对行政部访问Internet的 ...

  4. COS-5资源分配与调度

    操作系统是用户和计算机的接口,同时也是计算机硬件和其他软件的接口.操作系统的功能包括管理计算机系统的硬件.软件及数据资源,控制程序运行,改善人机界面,为其它应用软件提供支持,让计算机系统所有资源最大限 ...

  5. Spring Boot 中全局异常处理器

    Spring Boot 中全局异常处理器,就是把错误异常统一处理的方法.等价于Springmvc中的异常处理器. 步骤一:基于前面的springBoot入门小demo修改 步骤二:修改HelloCon ...

  6. hibernate配置文件的详解

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-configurati ...

  7. java官网下载

    安装版 http://javadl.oracle.com/webapps/download/AutoDL?BundleId=234471_96a7b8442fe848ef90c96a2fad6ed6d ...

  8. LeetCode第[26]题(Java):Remove Duplicates from Sorted Array 标签:Array

    题目难度:Easy 题目: Given a sorted array, remove the duplicates in-place such that each element appear onl ...

  9. Mac环境下Android Studio配置Git以及最基本使用

    Git是分布式版本管理工具,现在使用十分广泛,相对于SVN,GIT的使用更加方便,在离线环境下,仍然可以进行版本控制工作.且速度十分快.在Windows下,先需要自行安装Git程序,网址git-scm ...

  10. Device Drivers Should Not Do Power Management

    有人对现有的电源管理提出了意见,认为驱动程序不应该做电源管理,paper地址在这里: http://www.ruf.rice.edu/~mobile/publications/xu2014apsys. ...