Spring ApplicationContext(八)事件监听机制
Spring ApplicationContext(八)事件监听机制
本节则重点关注的是 Spring 的事件监听机制,主要是第 8 步:多播器注册;第 10 步:事件注册。
public void refresh() throws BeansException, IllegalStateException {
// 8. 注册多播器,事件监听器的管理者
initApplicationEventMulticaster();
// 9. 专门留给子类初始化其它 bean 用,这是一个空的方法
onRefresh();
// 10. 注册监听器
registerListeners();
}
事件定义如下,实现了 JDK 的规范 EventListener
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
// 监听 event 事件
void onApplicationEvent(E event);
}
一、ApplicationListener 实战
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("接收的事件:" + event);
}
}
运行后结果如下:
接收的事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@16eabae: startup date [Sun Jul 29 12:41:42 CST 2018]; root of context hierarchy]
二、ApplicationEventMulticaster 多播器的初始化
ApplicationContext 中 refresh() 第 8 步 initApplicationEventMulticaster() 进行多播器的初始化工作
源代码【AbstractApplicationContext】
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
三、ApplicationListener 注册
ApplicationContext 中 refresh() 第 10 步 registerListeners() 进行事件监听者的注册工作。
源代码【AbstractApplicationContext】
protected void registerListeners() {
// 1. 注册静态指定的侦听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 2. 注册 ApplicationListener
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 3. Publish early application events
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
四、ApplicationEvent 事件发布
源代码【AbstractApplicationContext】
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
public void publishEvent(Object event) {
publishEvent(event, null);
}
protected void publishEvent(Object event, ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// 1. 如果 event 不是 ApplicationEvent,则需要进行封装成 PayloadApplicationEvent
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<Object>(this, event);
if (eventType == null) {
eventType = ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, event.getClass());
}
}
// 2. 发布事件 event,如果多播器懒加载,还没有初始化则将该事件先放到 earlyApplicationEvents 容器中
// 等待多播器创建好了再发布事件 ???
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// 3. 父容器中也需要发布该事件 event
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
每天用心记录一点点。内容也许不重要,但习惯很重要!
Spring ApplicationContext(八)事件监听机制的更多相关文章
- Spring 事件监听机制及原理分析
简介 在JAVA体系中,有支持实现事件监听机制,在Spring 中也专门提供了一套事件机制的接口,方便我们实现.比如我们可以实现当用户注册后,给他发送一封邮件告诉他注册成功的一些信息,比如用户订阅的主 ...
- 7_3.springboot2.x启动配置原理_3.事件监听机制
事件监听机制配置在META-INF/spring.factories ApplicationContextInitializer SpringApplicationRunListenerioc容器中的 ...
- SpringBoot事件监听机制源码分析(上) SpringBoot源码(九)
SpringBoot中文注释项目Github地址: https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE 本篇接 SpringApplicat ...
- Halo 开源项目学习(六):事件监听机制
基本介绍 Halo 项目中,当用户或博主执行某些操作时,服务器会发布相应的事件,例如博主登录管理员后台时发布 "日志记录" 事件,用户浏览文章时发布 "访问文章" ...
- Spring Boot实践——事件监听
借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994 https://blog.csdn.net/ignorewho/arti ...
- SpringBoot事件监听机制及观察者模式/发布订阅模式
目录 本篇要点 什么是观察者模式? 发布订阅模式是什么? Spring事件监听机制概述 SpringBoot事件监听 定义注册事件 注解方式 @EventListener定义监听器 实现Applica ...
- 4.JAVA之GUI编程事件监听机制
事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件. ...
- .NET事件监听机制的局限与扩展
.NET中把“事件”看作一个基本的编程概念,并提供了非常优美的语法支持,对比如下C#和Java代码可以看出两种语言设计思想之间的差异. // C#someButton.Click += OnSomeB ...
- 关于事件监听机制的总结(Listener和Adapter)
记得以前看过事件监听机制背后也是有一种设计模式的.(设计模式的名字记不清了,只记得背后实现的数据结构是数组.) 附上事件监听机制的分析图: 一个事件源可以承载多个事件(只要这个事件源支持这个事件就可以 ...
随机推荐
- NCB之taxonomy系列
1.taxonomy之简介 生物分类学是研究生物系统的一种强有力的组织原则.遗传.共同遗传的同源性以及在确定功能时保护序列和结构,这些都是生物学的中心思想,直接关系到任何一组生物体的进化史.因此,分类 ...
- pip安装插件库
升级:python -m pip install --upgrade pip 读excel:pip install xlrd 写入excel:pip install xlwt
- Mono vs IL2CPP
[Mono vs IL2CPP] 参考:http://blog.csdn.net/gz_huangzl/article/details/52486255
- asp.net之发送邮件2
public void SendMail(string from, string to, List<string> cc, string subject, string body) { M ...
- python lambda 函数
lambda 函数,也叫匿名函数,是一个不需要使用def 关键字定义的小函数.返回一个函数地址. 表达式只能有一个,参数可以有多个. a = lambda x:x*x a(3) 返回的是9
- JMeter一次简单的接口测试(转载)
转载自 http://www.cnblogs.com/yangxia-test 本次接口测试:根据ws查询所有商品的具体的信息.检查商品是否返回成功. 1. 准备测试数据 查询数据库中产品表已上架商 ...
- Kerberos 互信免登陆
第一步:机器加互信 将机器A的Kerberos name加到机器B的~/.k5login中,同时将机器B的Kerberos name加到机器A的~/.k5login中 例如:host/bjm6-193 ...
- spark算子之DataFrame和DataSet
前言 传统的RDD相对于mapreduce和storm提供了丰富强大的算子.在spark慢慢步入DataFrame到DataSet的今天,在算子的类型基本不变的情况下,这两个数据集提供了更为强大的的功 ...
- javac编译带包的java文件需要在命令处加参数
不带包:javac aaa.java 带包:javac -d . aaa.java 带包就是 java文件中含有 package com.aaa;
- 手机端用swiper组件 轮播图设置后右侧出现空白 及 部分手机浏览器打开网页空白
我的方法是设置内容css overflow:hidden;width:100%; ok. 之前搜到一个方法也可以,就是设置css height: auto;overflow-y: scroll; 但是 ...