Spring4.x 笔记(11):Ioc 容器高级-容器事件

了解 Spring 容器事件体系

Spring 的 ApplicationContext 能够发布事件并且允许注册相应的事件监听器,其拥有一套完善的事件发布和监听机制。其类结构如下

image

事件类:ApplicationEvent

实现类描述
ApplicationContextEvent容器事件,其有4个子类,分别表示容器启动、刷新、停止、关闭的事件
RequestHandledEvent与Web相关的事件,当一个Http请求被处理后,产生该事件。
PayloadApplicationEvent4.x新的事件。如果事件发布一个Object对象而不是 ApplicationEvent对象,会被包装成 PayloadApplicationEvent 对象

事件监听器接口 ApplicationListener

ApplicationListener 接口只有一个方法,该方法接收 ApplicationEvent 事件对象,在该方法中编写事件响应处理逻辑。

实现描述
SmartApplicationListenerspring3.x 新增两个方法,指定监听器支持哪种类型的容器事件对象。supportsEventType(Class<? extends ApplicationEvent> eventType)、boolean supportsSourceType(Class<?> sourceType)
GenericApplicationListenerspring4.2 新增。增强了对泛型,boolean supportsEventType(ResolvableType eventType); ResolvableType 类是一个简单的泛型操作支持类,通过这个类可以轻易获取泛型的实际类型信息
@EventListenerSpring4.2 实现的事件监听注解实现

事件广播 ApplicationEventMulticaster

当发生容器事件时,容器主控程序将调用事件广播器将事件通知给事件监听器注册表中的事件监听器,事件监听器进行响应

graph TB
A[AbstractApplicationEventMulticaster]-->B[ApplicationEventMulticaster]
C[SimpleApplicationEventMulticaster]-->A

事件发布 ApplicationEventPublisher

Spring 为事件的发布定义了 ApplicationEventPublisher 接口 ,ApplicationContext 上下文实现了该接口。接入接口 ApplicationEventPublisherAware 也被设计实现 ApplicationEventPublisher 功能

ApplicationContext 事件体系的具体实现

Spring 在 ApplicationContext 接口的抽象实现类 AbstractApplicationContext 中完成了事件体系的搭建。AbstractApplicationContext 有一个 ApplicationEventMulticaster 成员变量,提供容器监听器的注册表。在 AbstractApplicationContext 类的容器启动方法 refresh() 中通过3个步骤搭建事件的基础设施,代码清单如下:

// 初始化应用上下文事件广播器
initApplicationEventMulticaster();

// 注册事件监听
registerListeners();

// 完成刷新并发布容器刷新事件,内部 publishEvent(new ContextRefreshedEvent(this));
finishRefresh();
  1. 初始化应用上下文事件广播器
    默认初始化 SimpleApplicationEventMulticaster 作为事件广播器,自己装配自定义(实现 ApplicationEventMulticaster 接口)的事件广播器 Bean,Spring 会通过反射将其注册成容器的事件广播器

  2. 注册事件监听
    Spring 根据反射机制,从 BeanDefinitionRegistry 中找出所有实现了 ApplicationListener 的 Bean ,将它们注册为容器的事件监听器,实际操作是调用 ApplicationEventMulticaster 的addApplicationListener、addApplicationListenerBean 方法,将其添加到事件广播器提供的事件监听器注册表中

  3. 完成刷新并发布容器刷新事件
    容器启动完成,调用事件发布接口先容器中所有的监听器发布事件,在 publishEvent(new ContextRefreshedEvent(this)); 方法内部,Spring 委托 SimpleApplicationEventMulticaster 将事件通知给事件监听器 multicastEvent 方法

简单示例

  1. 自定义事件类
public class EventBean extends ApplicationEvent {

    private String msg;

    public EventBean(Object source, String msg) {
        super(source);
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
  1. 事件监听器,只负责监听 EventBean 事件
public class EventListener implements ApplicationListener<EventBean> {

    @Override
    public void onApplicationEvent(EventBean event) {
        System.out.println("监听到的数据: " + event.getMsg());
    }
}
  1. 事件发布
public class EventPublisher {
    @Autowired
    ApplicationContext applicationContext;

    public void publish(String msg) {
        EventBean eventBean = new EventBean(this, msg);
        applicationContext.publishEvent(eventBean);
    }
}

参考

  1. 源码地址
  2. Spring 4.2框架中注释驱动的事件监听器详解

Fork me on Gitee

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值