@ -153,12 +153,44 @@ public abstract class AbstractApplicationEventMulticaster
@@ -153,12 +153,44 @@ public abstract class AbstractApplicationEventMulticaster
Object source = event . getSource ( ) ;
Class < ? > sourceType = ( source ! = null ? source . getClass ( ) : null ) ;
ListenerCacheKey cacheKey = new ListenerCacheKey ( eventType , sourceType ) ;
// Quick check for existing entry on ConcurrentHashMap...
ListenerRetriever retriever = this . retrieverCache . get ( cacheKey ) ;
if ( retriever ! = null ) {
return retriever . getApplicationListeners ( ) ;
}
else {
if ( this . beanClassLoader = = null | |
( ClassUtils . isCacheSafe ( eventType , this . beanClassLoader ) & &
( sourceType = = null | | ClassUtils . isCacheSafe ( sourceType , this . beanClassLoader ) ) ) ) {
// Fully synchronized building and caching of a ListenerRetriever
synchronized ( this . defaultRetriever ) {
retriever = this . retrieverCache . get ( cacheKey ) ;
if ( retriever ! = null ) {
return retriever . getApplicationListeners ( ) ;
}
retriever = new ListenerRetriever ( true ) ;
Collection < ApplicationListener < ? > > listeners = retrieveApplicationListeners ( event , sourceType , retriever ) ;
this . retrieverCache . put ( cacheKey , retriever ) ;
return listeners ;
}
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners ( event , sourceType , null ) ;
}
}
/ * *
* Actually retrieve the application listeners for the given event and source type .
* @param event the application event
* @param sourceType the event source type
* @param retriever the ListenerRetriever , if supposed to populate one ( for caching purposes )
* @return the pre - filtered list of application listeners for the given event and source type
* /
private Collection < ApplicationListener < ? > > retrieveApplicationListeners (
ApplicationEvent event , Class < ? > sourceType , ListenerRetriever retriever ) {
LinkedList < ApplicationListener < ? > > allListeners = new LinkedList < ApplicationListener < ? > > ( ) ;
Set < ApplicationListener < ? > > listeners ;
Set < String > listenerBeans ;
@ -167,7 +199,7 @@ public abstract class AbstractApplicationEventMulticaster
@@ -167,7 +199,7 @@ public abstract class AbstractApplicationEventMulticaster
listenerBeans = new LinkedHashSet < String > ( this . defaultRetriever . applicationListenerBeans ) ;
}
for ( ApplicationListener < ? > listener : listeners ) {
if ( supportsEvent ( listener , eventType , sourceType ) ) {
if ( supportsEvent ( listener , event . getClass ( ) , sourceType ) ) {
retriever . applicationListeners . add ( listener ) ;
allListeners . add ( listener ) ;
}
@ -180,7 +212,7 @@ public abstract class AbstractApplicationEventMulticaster
@@ -180,7 +212,7 @@ public abstract class AbstractApplicationEventMulticaster
if ( listenerType = = null | | supportsEvent ( listenerType , event ) ) {
ApplicationListener < ? > listener =
beanFactory . getBean ( listenerBeanName , ApplicationListener . class ) ;
if ( ! allListeners . contains ( listener ) & & supportsEvent ( listener , eventType , sourceType ) ) {
if ( ! allListeners . contains ( listener ) & & supportsEvent ( listener , event . getClass ( ) , sourceType ) ) {
retriever . applicationListenerBeans . add ( listenerBeanName ) ;
allListeners . add ( listener ) ;
}
@ -193,14 +225,8 @@ public abstract class AbstractApplicationEventMulticaster
@@ -193,14 +225,8 @@ public abstract class AbstractApplicationEventMulticaster
}
}
OrderComparator . sort ( allListeners ) ;
if ( this . beanClassLoader = = null | |
( ClassUtils . isCacheSafe ( eventType , this . beanClassLoader ) & &
( sourceType = = null | | ClassUtils . isCacheSafe ( sourceType , this . beanClassLoader ) ) ) ) {
this . retrieverCache . put ( cacheKey , retriever ) ;
}
return allListeners ;
}
}
/ * *
* Filter a listener early through checking its generically declared event