Spring源码讲解(七)Spring中的事件广播机制(Event)

Spring关于Event的相关文档

准备工作

在spring容器初始化时会做两件事(参考AbstractApplicationContext#refresh方法):

1.初始化一个事件广播器

AbstractApplicationContext#initApplicationEventMulticaster

事件广播器对象主要是用来发布事件的,从上面的源码可以看出来,spring默认注册一个SimpleApplicationEventMulticaster类型的广播器对象,且bean的名字固定是applicationEventMulticaster,我们可以自定义一个来覆盖spring默认的配置,当然,名字必须是applicationEventMulticaster。

2.扫描事件监听器

事件监听器是用来监听广播出来的的事件的,Spring中有两种方式来定义一个事件监听器:

1.实现ApplicationListener接口

2.在一个bean上加@EventListener注解

相对应的,其扫描方式也分为了两个:

针对实现ApplicationListener接口的,是在Spring实例化所有bean之后,扫描得到所有实现了ApplicationListener接口的bean的名称,放到SimpleApplicationEventMulticaster中的一个Set集合中,参考AbstractApplicationContext#registerListeners:

针对加了加@EventListener注解的,spring是通过一个EventListenerMethodProcessor类来处理的,查看源码可以发现,其是实现了SmartInitializingSingleton接口,这个接口之前分析spring源码的时候也说过,是在bean初始化完成之后回调的,可以理解为和InitializingBean差不多的功能。

spring首先会将这个bean加到容器中,当其实例化出来之后就会回调SmartInitializingSingleton接口的afterSingletonsInstantiated方法,在这方法里面扫描出所有加了@EventListener注解的bean:

 

广播一个事件

初始化做完之后,我们该怎么广播一个事件呢?这个就要借助于SimpleApplicationEventMulticaster的multicastEvent方法了,这个方法会要求传入一个ApplicationEvent对象或者其子类对象,代表要广播出去的事件类型。大概的原理就是遍历之前容器初始化时扫描到的事件监听器,找到监听该事件的所有监听器,然后触发:

最终就调用到了该事件监听器的onApplicationEvent方法:

 

最后一个问题,如何去取这个事件广播器

针对这个问题,从上面的源码中可以看到,spring初始化时是将广播器对象放到容器中的,所以一般只要利用注解注入就行了。这里之所以要单独拎出来是因为spring还提供了一种特殊的方式,就是实现ApplicationEventPublisherAware接口。

注意这里的参数是一个ApplicationEventPublisher对象,划重点:

***Aware接口的用途很明确了,实现了该接口,spring自动为你注入事件广播器对象,其源码在ApplicationContextAwareProcessor这个后置处理器中(之前的spring源码中有讲过,属于spring第七次后置处理器执行逻辑):

有没有发现这里注入的是一个spring容器上下文对象,事实上确实如此,AnnotationConfigApplicationContext对象间接实现了ApplicationEventPublisher接口,也就实现了publishEvent方法,该方法就中能广播事件了。

为什么能广播?因为AnnotationConfigApplicationContext在spring容器初始化时就已经将SimpleApplicationEventMulticaster对象赋值到了其成员变量applicationEventMulticaster,参考上面的初始化事件广播器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架是一个开源的Java应用程序框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的方式来管理Java对象的生命周期和依赖关系,从而简化了应用程序的开发和维护过程。下面是对Spring框架源码的简要讲解: 1. 核心容器(Core Container):Spring框架的核心是其IoC容器(Inversion of Control)。它通过IoC容器来管理和组织应用程序的Bean对象。在IoC容器Spring使用`BeanFactory`接口和其实现类`DefaultListableBeanFactory`来加载、配置和管理Bean对象。 2. 上下文(Context):Spring还提供了更高级的上下文功能,如`ApplicationContext`接口和其实现类`AnnotationConfigApplicationContext`、`XmlWebApplicationContext`等。上下文扩展了`BeanFactory`的功能,提供了更多的企业级特性,如国际化、事件传播、资源加载等。 3. AOP(Aspect-Oriented Programming):Spring框架实现了AOP的支持,用于将横切关注点(cross-cutting concerns)从核心业务逻辑分离出来。Spring AOP基于代理模式和动态代理技术,通过面向切面编程来实现横切关注点的模块化。 4. 数据访问(Data Access):Spring框架提供了对各种数据访问技术的支持,包括JDBC、ORM(如Hibernate、MyBatis)和事务管理。它通过抽象出数据访问层的公共接口,使得应用程序可以更容易地切换和集成不同的数据访问技术。 5. Web支持:Spring框架还提供了对Web应用程序开发的支持,包括Web MVC、RESTful服务、WebSocket等。它通过`DispatcherServlet`和一系列的处理器(Handler)来处理Web请求,并提供了一套强大的机制来实现灵活的Web应用程序开发。 6. 测试支持:Spring框架还提供了对单元测试和集成测试的支持,如`JUnit`和`TestNG`的集成、模拟对象(Mock Objects)的支持等。这使得开发人员可以更方便地编写和执行各种测试用例。 需要注意的是,Spring框架是一个非常庞大而复杂的项目,其源代码具有很高的复杂性和技术难度。如果您有兴趣深入了解Spring框架的源码,建议您从官方网站下载源代码并阅读相关文档,或者参考一些专门讲解Spring源码的书籍和教程。同时,熟悉Java编程、设计模式和IoC、AOP等基本概念也是理解和阅读Spring源码的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值