SpringFramework事件与监听机制(泛型事件)

本文详细探讨了Spring Framework的泛型事件发布和监听机制,通过分析`AbstractApplicationContext`的`publishEvent`方法,揭示了`PayloadApplicationEvent`如何通过`ResolvableType`实现泛型事件的灵活匹配。同时,介绍了监听器如何通过`supportsEventType`和`supportsSourceType`判断事件匹配。文章还展示了如何编写监听泛型事件的监听器,并提供了测试案例来发布和监听User类型的泛型事件。
摘要由CSDN通过智能技术生成

SpringBoot版本:2.0.2.RELEASE
SpringFramework版本:5.0.6.RELEASE

实现泛型的机制

前了前面几篇文章的铺陈,这个话题就容易描述了,读者可顾回这几篇文章:

  • 《SpringFramework事件与监听机制(发布器)》
  • 《SpringFramework事件与监听机制(事件)》
  • 《SpringFramework事件与监听机制(监听器)》

泛型事件的发布

AbstractApplicationContext作为ApplicationEventPublisher接口的实现类,它承担起事件发布任务。在重写的publishEvent方法的关键代码如下:

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
   
	....
	// Decorate event as an ApplicationEvent if necessary
	ApplicationEvent applicationEvent;
	if (event instanceof ApplicationEvent) {
   
			applicationEvent = (ApplicationEvent) event;
	}
	else {
   
		applicationEvent = new PayloadApplicationEvent<>(this, event);
		if (eventType == null) {
   
			eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
		}
	}

	// Multicast right now if possible - or lazily once the multicaster is initialized
	if (this.earlyApplicationEvents != null) 
	{
   
this.earlyApplicationEvents.add(applicationEvent);
	}
	else {
   		getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
	}

	....
}

方法在发布事件前,先判断事件是否ApplicationEvent类型,如果不是就封装成PayloadApplicationEvent事件。

public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
   

	private final T payload;


	/**
	 * Create a new PayloadApplicationEvent.
	 * @param source the object on which the event initially occurred (never {@code null})
	 * @param payload the payload object (never {@code null})
	 */
	public PayloadApplicationEvent(Object source, T payload) {
   
		super(source);
		Assert.notNull(payload, "Payload must not be null");
		this.payload = payload;
	}


	@Override
	public ResolvableType getResolvableType() {
   
		return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
	}

	/**
	 * Return the payload of the event.
	 */
	public T getPayload() {
   
		return this.payload;
	}

}

从类的定义上看,PayloadApplicationEvent继承于ApplicationEvent。PayloadApplicationEvent实现ResolvableTypeProvider接口,它定义的方法返回的ResolvableType是将PayloadApplicationEvent的类型以及以payload属性的具体类型作为的泛型揉合在一起的结合物作为事件的类型。它以PayloadApplicationEvent类型为原生类型,以payload属性的具体类型为泛型。在此我们可以想象一下,在类型定义层面,我们为类添加了泛型标记,这样子明确了类是带泛型的,泛型的具体类型是不清楚的,在真正使用到这类型的时候才会指定泛型的真正类型。而Spring Framework封装的ResolvableType在运行时可将两个不同的类型揉合到一起,作用在事件与监听机制的过虑中能起到甄别监听器的作用,这设计摆脱了类定义的固定模式,让类之间的结合变得灵活起来,真是高明。相信在Spring Framework其他方面也会起到类似的作用。
在AbstractApplicationContext#publishEvent方法体里可知,PayloadApplicationEvent以ConfigurableApplicationContext作为事件源,目前还不清楚这样处理的用意何在。

在《SpringFramework事件与监听机制(监听器)》里描述过,SimpleApplicationEventMulticaster在发布事件时,会调用父类的getApplicationListeners方法,该方法会返回与事件相匹配的Listener集合。那么如何甄别事件类型监听器是否匹配,就得看AbstractApplicationEventMulticaster#supportsEvent方法:

protected boolean supportsEvent(
			ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
   

		GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
				(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值