Spring如何过滤ApplicationEvents

时间:2014-04-19 12:23:19

标签: java spring generics

我一直在研究Spring中的事件监听器并遇到ApplicationListener接口。例如,哪些eanbles使用泛型:

public class CStopEventHandler 
   implements ApplicationListener<ContextStoppedEvent>{

   public void onApplicationEvent(ContextStoppedEvent event) {
      System.out.println("ContextStoppedEvent Received");
   }
}

由于泛型类型在运行时被擦除,事件调度程序如何知道运行时ApplicationListener的类型?它是否使用反射或类似方法检查方法签名?

3 个答案:

答案 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}}中,该方法用于测试侦听器泛型类型是否匹配以及是否支持该事件。