Spring事件监听机制
时间:2019-09-17
本文章向大家介绍Spring事件监听机制,主要包括Spring事件监听机制使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言
Spring中的事件机制其实就是设计模式中的观察者模式,主要由以下角色构成:
- 事件
- 事件监听器(监听并处理事件)
- 事件发布者(发布事件)
首先看一下监听器和发布者的接口定义
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
void publishEvent(Object event);
}
事件流转流程
初始化事件广播器
看一下这个方法AbstractApplicationContext.refresh
,在IOC源码解析那篇文章已经把这个方法分析完了,所以直接关注事件广播器和事件发布相关的逻辑即可
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// 初始化事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 发布事件
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;
}
}
}
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);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
可以看到如果没有自定义的事件广播器,默认是使用SimpleApplicationEventMulticaster
的
发布事件
发布事件是在bean的初始化之后的
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// 发布事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
//1. 获取到事件广播器,发布事件
getApplicationEventMulticaster().multicastEvent(event);
//2. 如果存在父容器,父容器也将发布事件
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
具体的发布逻辑在multicastEvent
方法中
public void multicastEvent(final ApplicationEvent event) {
//遍历执行listener,getApplicationListeners调用AbstractApplicationEventMulticaster父类方法
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
listener.onApplicationEvent(event);
}
});
}
else {
listener.onApplicationEvent(event);
}
}
}
可以看到也没啥特殊的,无非就是起个线程池去调用这些监听器的方法
而监听器的处理就看各个监听器的具体实现了
原文地址:https://www.cnblogs.com/zhixiang-org-cn/p/11531633.html
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- springboot解决前后端数据跨域问题
- 单细胞数据中到底应该如何处理线粒体基因
- Seurat小提琴图为什么有的只有点儿?
- Layui解决table日期的格式化问题
- Telegraf+Influxdb+Grafana 轻量级监控系统部署
- 国产开源文档管理系统——Wizard
- 力扣 1519——子树中标签相同的节点数
- PythonforResearch | 1_文件操作
- 你应该知道关于Python的这几个技巧!
- Pytest之fixture
- JAVA|Java的Scanner类初级使用
- systemd设置nginx开机自启动
- C盘爆满,如何移除软件~
- Microsoft PowerToys
- MagicEXIF(元数据编辑器)