11/*
2- * Copyright 2002-2014 the original author or authors.
2+ * Copyright 2002-2015 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2727import org .springframework .beans .factory .BeanFactory ;
2828import org .springframework .beans .factory .BeanFactoryAware ;
2929import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
30+ import org .springframework .beans .factory .support .AbstractBeanFactory ;
3031import org .springframework .context .ApplicationEvent ;
3132import org .springframework .context .ApplicationListener ;
3233import org .springframework .core .OrderComparator ;
@@ -64,70 +65,76 @@ public abstract class AbstractApplicationEventMulticaster
6465
6566 private BeanFactory beanFactory ;
6667
68+ private Object retrievalMutex = this .defaultRetriever ;
69+
70+
71+ public void setBeanClassLoader (ClassLoader classLoader ) {
72+ this .beanClassLoader = classLoader ;
73+ }
74+
75+ public void setBeanFactory (BeanFactory beanFactory ) {
76+ this .beanFactory = beanFactory ;
77+ if (this .beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory ) {
78+ this .beanClassLoader = ((ConfigurableBeanFactory ) beanFactory ).getBeanClassLoader ();
79+ }
80+ if (beanFactory instanceof AbstractBeanFactory ) {
81+ this .retrievalMutex = ((AbstractBeanFactory ) beanFactory ).getSingletonMutex ();
82+ }
83+ }
84+
85+ private BeanFactory getBeanFactory () {
86+ if (this .beanFactory == null ) {
87+ throw new IllegalStateException ("ApplicationEventMulticaster cannot retrieve listener beans " +
88+ "because it is not associated with a BeanFactory" );
89+ }
90+ return this .beanFactory ;
91+ }
92+
6793
6894 public void addApplicationListener (ApplicationListener listener ) {
69- synchronized (this .defaultRetriever ) {
95+ synchronized (this .retrievalMutex ) {
7096 this .defaultRetriever .applicationListeners .add (listener );
7197 this .retrieverCache .clear ();
7298 }
7399 }
74100
75101 public void addApplicationListenerBean (String listenerBeanName ) {
76- synchronized (this .defaultRetriever ) {
102+ synchronized (this .retrievalMutex ) {
77103 this .defaultRetriever .applicationListenerBeans .add (listenerBeanName );
78104 this .retrieverCache .clear ();
79105 }
80106 }
81107
82108 public void removeApplicationListener (ApplicationListener listener ) {
83- synchronized (this .defaultRetriever ) {
109+ synchronized (this .retrievalMutex ) {
84110 this .defaultRetriever .applicationListeners .remove (listener );
85111 this .retrieverCache .clear ();
86112 }
87113 }
88114
89115 public void removeApplicationListenerBean (String listenerBeanName ) {
90- synchronized (this .defaultRetriever ) {
116+ synchronized (this .retrievalMutex ) {
91117 this .defaultRetriever .applicationListenerBeans .remove (listenerBeanName );
92118 this .retrieverCache .clear ();
93119 }
94120 }
95121
96122 public void removeAllListeners () {
97- synchronized (this .defaultRetriever ) {
123+ synchronized (this .retrievalMutex ) {
98124 this .defaultRetriever .applicationListeners .clear ();
99125 this .defaultRetriever .applicationListenerBeans .clear ();
100126 this .retrieverCache .clear ();
101127 }
102128 }
103129
104- public void setBeanClassLoader (ClassLoader classLoader ) {
105- this .beanClassLoader = classLoader ;
106- }
107-
108- public void setBeanFactory (BeanFactory beanFactory ) {
109- this .beanFactory = beanFactory ;
110- if (this .beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory ) {
111- this .beanClassLoader = ((ConfigurableBeanFactory ) beanFactory ).getBeanClassLoader ();
112- }
113- }
114-
115- private BeanFactory getBeanFactory () {
116- if (this .beanFactory == null ) {
117- throw new IllegalStateException ("ApplicationEventMulticaster cannot retrieve listener beans " +
118- "because it is not associated with a BeanFactory" );
119- }
120- return this .beanFactory ;
121- }
122-
123130
124131 /**
125132 * Return a Collection containing all ApplicationListeners.
126133 * @return a Collection of ApplicationListeners
127134 * @see org.springframework.context.ApplicationListener
128135 */
129136 protected Collection <ApplicationListener > getApplicationListeners () {
130- synchronized (this .defaultRetriever ) {
137+ synchronized (this .retrievalMutex ) {
131138 return this .defaultRetriever .getApplicationListeners ();
132139 }
133140 }
@@ -156,13 +163,14 @@ protected Collection<ApplicationListener> getApplicationListeners(ApplicationEve
156163 (ClassUtils .isCacheSafe (eventType , this .beanClassLoader ) &&
157164 (sourceType == null || ClassUtils .isCacheSafe (sourceType , this .beanClassLoader )))) {
158165 // Fully synchronized building and caching of a ListenerRetriever
159- synchronized (this .defaultRetriever ) {
166+ synchronized (this .retrievalMutex ) {
160167 retriever = this .retrieverCache .get (cacheKey );
161168 if (retriever != null ) {
162169 return retriever .getApplicationListeners ();
163170 }
164171 retriever = new ListenerRetriever (true );
165- Collection <ApplicationListener > listeners = retrieveApplicationListeners (eventType , sourceType , retriever );
172+ Collection <ApplicationListener > listeners =
173+ retrieveApplicationListeners (eventType , sourceType , retriever );
166174 this .retrieverCache .put (cacheKey , retriever );
167175 return listeners ;
168176 }
@@ -186,7 +194,7 @@ private Collection<ApplicationListener> retrieveApplicationListeners(
186194 LinkedList <ApplicationListener > allListeners = new LinkedList <ApplicationListener >();
187195 Set <ApplicationListener > listeners ;
188196 Set <String > listenerBeans ;
189- synchronized (this .defaultRetriever ) {
197+ synchronized (this .retrievalMutex ) {
190198 listeners = new LinkedHashSet <ApplicationListener >(this .defaultRetriever .applicationListeners );
191199 listenerBeans = new LinkedHashSet <String >(this .defaultRetriever .applicationListenerBeans );
192200 }
0 commit comments