1
1
/*
2
- * Copyright 2002-2014 the original author or authors.
2
+ * Copyright 2002-2015 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
27
27
import org .springframework .beans .factory .BeanFactory ;
28
28
import org .springframework .beans .factory .BeanFactoryAware ;
29
29
import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
30
+ import org .springframework .beans .factory .support .AbstractBeanFactory ;
30
31
import org .springframework .context .ApplicationEvent ;
31
32
import org .springframework .context .ApplicationListener ;
32
33
import org .springframework .core .OrderComparator ;
@@ -64,70 +65,76 @@ public abstract class AbstractApplicationEventMulticaster
64
65
65
66
private BeanFactory beanFactory ;
66
67
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
+
67
93
68
94
public void addApplicationListener (ApplicationListener listener ) {
69
- synchronized (this .defaultRetriever ) {
95
+ synchronized (this .retrievalMutex ) {
70
96
this .defaultRetriever .applicationListeners .add (listener );
71
97
this .retrieverCache .clear ();
72
98
}
73
99
}
74
100
75
101
public void addApplicationListenerBean (String listenerBeanName ) {
76
- synchronized (this .defaultRetriever ) {
102
+ synchronized (this .retrievalMutex ) {
77
103
this .defaultRetriever .applicationListenerBeans .add (listenerBeanName );
78
104
this .retrieverCache .clear ();
79
105
}
80
106
}
81
107
82
108
public void removeApplicationListener (ApplicationListener listener ) {
83
- synchronized (this .defaultRetriever ) {
109
+ synchronized (this .retrievalMutex ) {
84
110
this .defaultRetriever .applicationListeners .remove (listener );
85
111
this .retrieverCache .clear ();
86
112
}
87
113
}
88
114
89
115
public void removeApplicationListenerBean (String listenerBeanName ) {
90
- synchronized (this .defaultRetriever ) {
116
+ synchronized (this .retrievalMutex ) {
91
117
this .defaultRetriever .applicationListenerBeans .remove (listenerBeanName );
92
118
this .retrieverCache .clear ();
93
119
}
94
120
}
95
121
96
122
public void removeAllListeners () {
97
- synchronized (this .defaultRetriever ) {
123
+ synchronized (this .retrievalMutex ) {
98
124
this .defaultRetriever .applicationListeners .clear ();
99
125
this .defaultRetriever .applicationListenerBeans .clear ();
100
126
this .retrieverCache .clear ();
101
127
}
102
128
}
103
129
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
-
123
130
124
131
/**
125
132
* Return a Collection containing all ApplicationListeners.
126
133
* @return a Collection of ApplicationListeners
127
134
* @see org.springframework.context.ApplicationListener
128
135
*/
129
136
protected Collection <ApplicationListener > getApplicationListeners () {
130
- synchronized (this .defaultRetriever ) {
137
+ synchronized (this .retrievalMutex ) {
131
138
return this .defaultRetriever .getApplicationListeners ();
132
139
}
133
140
}
@@ -156,13 +163,14 @@ protected Collection<ApplicationListener> getApplicationListeners(ApplicationEve
156
163
(ClassUtils .isCacheSafe (eventType , this .beanClassLoader ) &&
157
164
(sourceType == null || ClassUtils .isCacheSafe (sourceType , this .beanClassLoader )))) {
158
165
// Fully synchronized building and caching of a ListenerRetriever
159
- synchronized (this .defaultRetriever ) {
166
+ synchronized (this .retrievalMutex ) {
160
167
retriever = this .retrieverCache .get (cacheKey );
161
168
if (retriever != null ) {
162
169
return retriever .getApplicationListeners ();
163
170
}
164
171
retriever = new ListenerRetriever (true );
165
- Collection <ApplicationListener > listeners = retrieveApplicationListeners (eventType , sourceType , retriever );
172
+ Collection <ApplicationListener > listeners =
173
+ retrieveApplicationListeners (eventType , sourceType , retriever );
166
174
this .retrieverCache .put (cacheKey , retriever );
167
175
return listeners ;
168
176
}
@@ -186,7 +194,7 @@ private Collection<ApplicationListener> retrieveApplicationListeners(
186
194
LinkedList <ApplicationListener > allListeners = new LinkedList <ApplicationListener >();
187
195
Set <ApplicationListener > listeners ;
188
196
Set <String > listenerBeans ;
189
- synchronized (this .defaultRetriever ) {
197
+ synchronized (this .retrievalMutex ) {
190
198
listeners = new LinkedHashSet <ApplicationListener >(this .defaultRetriever .applicationListeners );
191
199
listenerBeans = new LinkedHashSet <String >(this .defaultRetriever .applicationListenerBeans );
192
200
}
0 commit comments