Spring源码解析十九

上一篇,我们了解到了spring如果想要控制一个bean的实例化过程,可以通过自定义BeanPostProcessor来实现,当自定义的BeanPostProcessor注册到spring容器后,bean在实例化开始和结束后分别会调用BeanPostProcessor接口中的方法,从而实现介入bean的实例化过程,我们们才可以有机会控制bean的实例化。而且我们可以看到在Spring的高级容器ApplicationContext初始化时,也是将各种BeanPostProcessor注册到spring容器中,BeanPostProcessor接口中的方法调用时机,在后面实例化bean的时候就可以看到了。接下来,我们继续分析下面的代码:
在这里插入图片描述
我们到方法initMessageResource方法中看下:
在这里插入图片描述
可以看到,方法initMessageSource中的逻辑还是比较简单的。
1、首先通过getBeanFactory获取spring容器beanFactory。
2、通过containsLocalBean方法判断spring容器中是否存在名称MESSAGE_SOURCE_BEAN_NAME。那这个MESSAGE_SOURCE_BEAN_NAME是什么呢?我们可以简单看一下:
在这里插入图片描述
可以看到,MESSAGE_SOURCE_BEAN_NAME其实就是一个常量值为:messageSource。这个就意味着,如果我们要在xml中配置MessageSource,id属性的值也得要配置为 messageSource,这样才可以从beanFactory容器中获取。但是如果没有在xml中配置MessageSource,就会走到下面的分支:
在这里插入图片描述
其实就是初始化了一个DelegatingMessageSource类型对象,然后将该对象注册到spring容器中,并且该对象的名称为messageResource。其中,spring的MessageSource就是处理国际化的,那什么是国家化呢?比如一段文字,在不同的国家需要使用不同的语言来表示,如英文、日文、中文等。对应我们的系统而言,就需要根据当前系统选择的国家地区,用相应的文字来显示了。但是在我们的日常开发中使用MessageResource来支持国际化已经很少用了,因为现在很多的前端框架都支持国际化了。
我们接着看refresh 中下一个方法:
在这里插入图片描述
我们到方法initApplicationEventMulticaster中看下:
在这里插入图片描述
和我们上面分析的这个逻辑差不多。先从spring容器中判断是否存在APPLICATION_EVENT_MULTICASTER_BEAN_NAME 也就是名称为applicationEventMulticaster的bean。如果存在的话,直接从容器中获取出来并且赋值给成员变量applicationEventMulticaster,否则直接创建一个SimpleApplicationEventMulticaster类型对象并设置到spring容器beanFactory中。那什么是SimpleApplicationEventMulticaster呢?我们从spring容器中获取这个 对象主要是根据ApplicationEventMulticaster接口获取的,而ApplicationEventMulticaster在spring中被称为是事件的广播器。在spring中和事件广播器ApplicationEventMulticaster相关的另外一个组件就是ApplicationListener。在spring中,广播器ApplicationEventMulticaster中可以注册多个监听器ApplicationListener,当特定的事件ApplicationEvent发送时,就会触发广播器ApplicationEventMulticaster来遍历各个监听器ApplicationListener中的方法,看下到底那个监听器负责的事件发生了,让指定的监听器来处理。

我们先编写一个案例看一下:
我们先自定义一个事件:
在这里插入图片描述
在自定义一个监听器:
在这里插入图片描述

我们把我们定义好的监听器配置到xml文件中:
在这里插入图片描述
测试验证:
在这里插入图片描述
结果:
在这里插入图片描述
可以看到,我们自定义的MyEvent中的event 方法成功被调用了。我们通过一个案例简单体验了一下在spring中,是如何自定义监听器和事件的,但是我们目前对于广播器ApplicationEventMulticaster在这一过程中的作用,还是很模糊。要了解广播器的功能呢,我们还是要看下publishEvent方法作为入口,来看下MyEvent事件是如何发布的:
在这里插入图片描述
我们在跟进到重载方法里面看下:
在这里插入图片描述
可以看到,首先我们传进来的event类型,根据刚才的案例我们知道是ApplicationEvent的实例,因为MyEvent就是继承了ApplicationEvent接口的,所以接下来回将Object对象,转换为ApplicationEvent类型。接着会调用下面这个方法
在这里插入图片描述
getApplicationEventMulticaster方法获取的就是我们前面看到的广播器,而这个类型默认就是这个SimpleApplicationEventMulticaster类型。所以接下来应该是进入到SimpleApplicationEventMulticaster的multicastEvent方法了,我们到这个方法中看一下:
在这里插入图片描述
接着,我们可以看到会通过 getApplicationListeners方法获取spring容器中的所有监听器,然后依次遍历处理这些监听器,从这个我们可以知道,广播器的作用其实就是当一个事件发生时,通知spring容器中的所有注册的监听器,然后让每个监听器决定是否要处理这个事件。在方法multicastEvent 默认是没有设置线程的,所以executor为空。

我们接着invokeListener方法中看下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最终就会调用监听器中的onApplicationEvent方法执行监听器中的逻辑。在我们案例只有我们自定义的监听器才会处理事件MyEvent,所以其他的监听器就算执行了onApplicationEvent方法,也会选择无视这个事件。也就是说广播器接收到一个事件之后,会将事件通知到所有的spring容器中的所有的监听器,并且调用监听器中的onApplicationEvent方法来处理相应的事件。spring这套基于事件驱动的机制,主要是通过广播器ApplicationEventMulticaster和监听器ApplicationListener来实现的,大家也可以理解为是发布-订阅模式,ApplicationEventMulticaster用来广播发布事件,ApplicationListener监听订阅事件,每种监听器负责处理一种或者多种事件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youngerone123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值