您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

spring监听机制

时间:2022-01-06 10:12:58  来源:  作者:NeverMore

前言

前一段时间,刚刚接手一个项目,项目中看到使用的spring的事件监听机制,加上之前自己看spring源码的时候也对spring listener 有点影像,于是就重新追一追源码,理一理spring 事件监听机制的工作原理

案例

  1. 自定义event
spring监听机制

 

  1. 自定义listener
spring监听机制

 

  1. 测试推送
spring监听机制

 

  1. 测试结果
spring监听机制

 

一个非常简单的案例,通过定义事件,监听,推送实现了简单的事件监听的流程。

原理分析

  1. 推送事件

通过案例可以看到我们通过
ApplicationContext.publishEvent方法来推送事件,实际是其子类 AbstractApplicationContext 实现的发送操作

spring监听机制

 

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}

通过源码可以看到发送事件最终是交个
ApplicationEventMulticaster来推送。

那么
ApplicationEventMulticaster对象是怎么来的呢,它里面具体是如何推送的呢?我们接着往下看。

读过spring源码的同学一定对
AbstractApplicationContext中的refresh方法很熟悉。这是spring源码的核心部分,而在其中有一步

spring监听机制

 

就是来构造
ApplicationEventMulticaster。

spring监听机制

 

参照源码,我们并没有定义和注册
applicationEventMulticaster,所以就会使用SimpleApplicationEventMulticaster。

spring监听机制

 

在multicastEvent中

1,首先是ResolvableType的确认

spring监听机制

 


spring监听机制

 

可以看到最后是通过Event的class对象作为ResolvableType的属性,后面匹配Listener的时候就是使用这个。

2,通过ResolvableType获取适合的Listener

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);
// Potential new retriever to populate
CachedListenerRetriever newRetriever = null;
// Quick check for existing entry on ConcurrentHashMap
CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey);
if (existingRetriever == null) {
// Caching a new ListenerRetriever if possible
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
newRetriever = new CachedListenerRetriever();
existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever);
if (existingRetriever != null) {
newRetriever = null; // no need to populate it in retrieveApplicationListeners
}
}
}
if (existingRetriever != null) {
Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();
if (result != null) {
return result;
}
// If result is null, the existing retriever is not fully populated yet by another thread.
// Proceed like caching wasn't possible for this current local attempt.
}
return retrieveApplicationListeners(eventType, sourceType, newRetriever);
}

这边这种使用缓存机制的代码,可以在spring源码中多次看到,所以大家可以学习这种方式,提高性能。


retrieveApplicationListeners方法比较大,我这边只截取了部分,可以看到是通过eventType

和sourceType来获取适合的listener。

spring监听机制

 

3,接下来就是调用invokeListener方法来实际操作,这边可以看到可以通过Executor

来实现异步操作。当然比较好的方式还是自己配置线程池,这样可以通过前缀区分出业务。

spring监听机制

 


spring监听机制

 

至此可以看到,调用的是对应listener的onApplicationEvent。



Tags:spring   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言前一段时间,刚刚接手一个项目,项目中看到使用的spring的事件监听机制,加上之前自己看spring源码的时候也对spring listener 有点影像,于是就重新追一追源码,理一理spring 事...【详细内容】
2022-01-06  Tags: spring  点击:(0)  评论:(0)  加入收藏
1、什么是YAMLYAML是"YAML Ain&rsquo;t a Markup Language"(YAML不是一种标记语言)的递归缩写。YAML的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。主要强度...【详细内容】
2021-12-29  Tags: spring  点击:(10)  评论:(0)  加入收藏
微信支付API-V3和V2的区别微信支付API-V3和之前V2版本最大的区别,应该就是加密方式的改变了。新版的支付接口,全部使用是SSL双向加密。就是指微信服务器端、商户端各自都有一...【详细内容】
2021-12-29  Tags: spring  点击:(13)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  Tags: spring  点击:(30)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Tags: spring  点击:(20)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  Tags: spring  点击:(23)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  Tags: spring  点击:(28)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  Tags: spring  点击:(64)  评论:(0)  加入收藏
1. 介绍1.1 介绍今天开始我们来学习Java操作MySQL数据库的技巧,Java操作MySQL是借助JdbcTemplate这个对象来实现的。JdbcTemplate是一个多数据库集中解决方案,而我们今天只讲...【详细内容】
2021-11-05  Tags: spring  点击:(32)  评论:(0)  加入收藏
SpringBoot中的Controller注册本篇将会以Servlet为切入点,通过源码来看web容器中的Controller是如何注册到HandlerMapping中。请求来了之后,web容器是如何根据请求路径找到对...【详细内容】
2021-11-04  Tags: spring  点击:(61)  评论:(0)  加入收藏
▌简易百科推荐
前言前一段时间,刚刚接手一个项目,项目中看到使用的spring的事件监听机制,加上之前自己看spring源码的时候也对spring listener 有点影像,于是就重新追一追源码,理一理spring 事...【详细内容】
2022-01-06  NeverMore    Tags:spring   点击:(0)  评论:(0)  加入收藏
byview 是一个自己开发的,用于引导vue组件直接工作在浏览器中而不需要脚手架的一个微框架(启动引擎),使得vue在浏览器中开发体验跟vue-cli相似。无需独立编译资源文件,修改立...【详细内容】
2021-12-30  带码攻城狮    Tags:Vue3   点击:(16)  评论:(0)  加入收藏
什么是微服务如今随着社交媒体的兴起,互联网的快速发展,应用程序变得越来越复杂,需要处理的任务也越来越多。 过去的单体应用程序已经无法满足日益增进的技术需求。因此人们迫...【详细内容】
2021-12-30  梦回故里归来    Tags:微服务   点击:(9)  评论:(0)  加入收藏
为了构建高并发、高可用的系统架构,压测、容量预估必不可少,在发现系统瓶颈后,需要有针对性地扩容、优化。结合楼主的经验和知识,本文做一个简单的总结,欢迎探讨。1、QPS保障目标...【详细内容】
2021-12-27  大数据架构师    Tags:架构   点击:(14)  评论:(0)  加入收藏
前言 单片机开发中,我们往往首先接触裸机系统,然后到RTOS,那么它们的软件架构是什么?这是我们开发人员必须认真考虑的问题。在实际项目中,首先选择软件架构是非常重要的,接下来我...【详细内容】
2021-12-23  正点原子原子哥    Tags:架构   点击:(10)  评论:(0)  加入收藏
现有数据架构难以支撑现代化应用的实现。 随着云计算产业的快速崛起,带动着各行各业开始自己的基于云的业务创新和信息架构现代化,云计算的可靠性、灵活性、按需计费的高性价...【详细内容】
2021-12-22    CSDN  Tags:数据架构   点击:(15)  评论:(0)  加入收藏
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  蜗牛学苑    Tags:微服务   点击:(14)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  青锋爱编程    Tags:后台架构   点击:(30)  评论:(0)  加入收藏
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于TCP/IP协议,数据传输之前,双方通过“三次握手”建立连接,当数据传输完成之后,又通过“四次挥手”释放连接,以下是“三次握手”与“四...【详细内容】
2021-12-14  架构即人生    Tags:连接池   点击:(22)  评论:(0)  加入收藏
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商...【详细内容】
2021-12-08  架构驿站    Tags:分布式系统   点击:(26)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条