2014-04-19 47 views
0

我一直在研究Spring中的事件監聽器,並遇到ApplicationListener接口。這eanbles使用泛型例如像這樣:Spring過濾器ApplicationEvents

public class CStopEventHandler 
    implements ApplicationListener<ContextStoppedEvent>{ 

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

由於泛型類型是在運行時被擦除怎樣事件分派知道ApplicationListener在運行時類型?它是否使用反射或類似的東西檢查方法簽名?

回答

0

在大多數代碼庫的事件監聽器存儲在不同的容器中,例如:

private List<ApplicationListener<ContextStoppedEvent>> contextStoppedEventListeners; 

private List<ApplicationListener<OtherEvent>> otherEventListeners; 
0

Spring將使用它的SimpleApplicationEventMulticaster使用繼承了getApplicationListeners(ApplicationEvent event)方法,以獲取事件監聽器從AbtractApplicationEventMulticaster。要查看偵聽器是否支持給定的事件類型,它通常會將偵聽器包裝在GenericApplicationListenerAdapter中,該偵聽器提供了supportsEventType(Class<? extends ApplicationEvent> eventType),該方法用於測試偵聽器泛型類型是否匹配並支持該事件。

0

你說得對。 Spring(當然還有整個Java)在運行時使用Reflection從提供的類中確定generic type

我們的案例應用程序上下文掃描bean的ApplicationListener實現並將它們全部存儲在列表中。

當您提出ApplicationEvent時,將處理ApplicationListener的列表以確定特定事件類型的偵聽器,並將它們存儲在緩存中以備將來優化。

但在此之前,您的ApplicationListener<?>被包裝到GenericApplicationListenerAdapter以使用來自提供的ApplicationListener的泛型類型調用其supportsEventType

我想你想知道這個方法:

static Class<?> resolveDeclaredEventType(Class<?> listenerType) { 
     return GenericTypeResolver.resolveTypeArgument(listenerType, ApplicationListener.class); 
    } 

並使用GenericTypeResolver從你的代碼的任何地方,當你需要知道generic type在運行時。

相關問題