我一直在研究Spring中的事件监听器并遇到ApplicationListener接口。例如,哪些eanbles使用泛型:
public class CStopEventHandler
implements ApplicationListener<ContextStoppedEvent>{
public void onApplicationEvent(ContextStoppedEvent event) {
System.out.println("ContextStoppedEvent Received");
}
}
由于泛型类型在运行时被擦除,事件调度程序如何知道运行时ApplicationListener
的类型?它是否使用反射或类似方法检查方法签名?
答案 0 :(得分:2)
你是对的。 Spring(当然还有整个Java)在运行时使用Reflection来确定提供的类中的generic type
。
我的情况是应用程序上下文扫描bean以查找ApplicationListener
个实现并将它们全部存储在列表中。
当您引发ApplicationEvent
时,处理ApplicationListener
列表以确定特定事件类型的侦听器,并将它们存储在缓存中以供将来优化。
但在此之前,ApplicationListener<?>
已被GenericApplicationListenerAdapter
包裹,以使用提供的supportsEventType
中的通用类型调用其ApplicationListener
。
我想你想知道这个方法:
static Class<?> resolveDeclaredEventType(Class<?> listenerType) {
return GenericTypeResolver.resolveTypeArgument(listenerType, ApplicationListener.class);
}
当您需要在运行时知道GenericTypeResolver
时,可以在代码中使用generic type
。
答案 1 :(得分:1)
在大多数代码库中,事件侦听器存储在不同的容器中,例如:
private List<ApplicationListener<ContextStoppedEvent>> contextStoppedEventListeners;
和
private List<ApplicationListener<OtherEvent>> otherEventListeners;
答案 2 :(得分:0)
Spring将使用它SimpleApplicationEventMulticaster
使用从getApplicationListeners(ApplicationEvent event)
继承的AbtractApplicationEventMulticaster
方法来获取事件侦听器。要查看侦听器是否支持给定的事件类型,它通常将侦听器包装在提供GenericApplicationListenerAdapter
的{{1}}中,该方法用于测试侦听器泛型类型是否匹配以及是否支持该事件。