16
16
17
17
package org .springframework .beans .factory .support ;
18
18
19
- import java .util .Collections ;
20
19
import java .util .HashMap ;
21
- import java .util .HashSet ;
22
20
import java .util .Iterator ;
23
21
import java .util .LinkedHashMap ;
24
22
import java .util .LinkedHashSet ;
@@ -94,11 +92,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
94
92
/** Set of registered singletons, containing the bean names in registration order */
95
93
private final Set <String > registeredSingletons = new LinkedHashSet <String >(16 );
96
94
97
- /** Names of beans that are currently in creation */
98
- private final Set <String > singletonsCurrentlyInCreation = Collections . synchronizedSet ( new HashSet <String >() );
95
+ /** Names of beans that are currently in creation (using a ConcurrentHashMap as a Set) */
96
+ private final Map <String , Boolean > singletonsCurrentlyInCreation = new ConcurrentHashMap <String , Boolean >( );
99
97
100
- /** Names of beans currently excluded from in creation checks */
101
- private final Set <String > inCreationCheckExclusions = new HashSet <String >();
98
+ /** Names of beans currently excluded from in creation checks (using a ConcurrentHashMap as a Set) */
99
+ private final Map <String , Boolean > inCreationCheckExclusions = new ConcurrentHashMap <String , Boolean >();
102
100
103
101
/** List of suppressed Exceptions, available for associating related causes */
104
102
private Set <Exception > suppressedExceptions ;
@@ -166,7 +164,7 @@ protected void addSingletonFactory(String beanName, ObjectFactory singletonFacto
166
164
}
167
165
168
166
public Object getSingleton (String beanName ) {
169
- return getSingleton (beanName , isSingletonCurrentlyInCreation ( beanName ) );
167
+ return getSingleton (beanName , true );
170
168
}
171
169
172
170
/**
@@ -179,10 +177,10 @@ public Object getSingleton(String beanName) {
179
177
*/
180
178
protected Object getSingleton (String beanName , boolean allowEarlyReference ) {
181
179
Object singletonObject = this .singletonObjects .get (beanName );
182
- if (singletonObject == null && allowEarlyReference ) {
180
+ if (singletonObject == null && isSingletonCurrentlyInCreation ( beanName ) ) {
183
181
synchronized (this .singletonObjects ) {
184
182
singletonObject = this .earlySingletonObjects .get (beanName );
185
- if (singletonObject == null ) {
183
+ if (singletonObject == null && allowEarlyReference ) {
186
184
ObjectFactory singletonFactory = this .singletonFactories .get (beanName );
187
185
if (singletonFactory != null ) {
188
186
singletonObject = singletonFactory .getObject ();
@@ -289,14 +287,43 @@ public int getSingletonCount() {
289
287
}
290
288
291
289
290
+ public void setCurrentlyInCreation (String beanName , boolean inCreation ) {
291
+ Assert .notNull (beanName , "Bean name must not be null" );
292
+ if (!inCreation ) {
293
+ this .inCreationCheckExclusions .put (beanName , Boolean .TRUE );
294
+ }
295
+ else {
296
+ this .inCreationCheckExclusions .remove (beanName );
297
+ }
298
+ }
299
+
300
+ public boolean isCurrentlyInCreation (String beanName ) {
301
+ Assert .notNull (beanName , "Bean name must not be null" );
302
+ return (!this .inCreationCheckExclusions .containsKey (beanName ) && isActuallyInCreation (beanName ));
303
+ }
304
+
305
+ protected boolean isActuallyInCreation (String beanName ) {
306
+ return isSingletonCurrentlyInCreation (beanName );
307
+ }
308
+
309
+ /**
310
+ * Return whether the specified singleton bean is currently in creation
311
+ * (within the entire factory).
312
+ * @param beanName the name of the bean
313
+ */
314
+ public boolean isSingletonCurrentlyInCreation (String beanName ) {
315
+ return this .singletonsCurrentlyInCreation .containsKey (beanName );
316
+ }
317
+
292
318
/**
293
319
* Callback before singleton creation.
294
320
* <p>Default implementation register the singleton as currently in creation.
295
321
* @param beanName the name of the singleton about to be created
296
322
* @see #isSingletonCurrentlyInCreation
297
323
*/
298
324
protected void beforeSingletonCreation (String beanName ) {
299
- if (!this .inCreationCheckExclusions .contains (beanName ) && !this .singletonsCurrentlyInCreation .add (beanName )) {
325
+ if (!this .inCreationCheckExclusions .containsKey (beanName ) &&
326
+ this .singletonsCurrentlyInCreation .put (beanName , Boolean .TRUE ) != null ) {
300
327
throw new BeanCurrentlyInCreationException (beanName );
301
328
}
302
329
}
@@ -308,29 +335,12 @@ protected void beforeSingletonCreation(String beanName) {
308
335
* @see #isSingletonCurrentlyInCreation
309
336
*/
310
337
protected void afterSingletonCreation (String beanName ) {
311
- if (!this .inCreationCheckExclusions .contains (beanName ) && !this .singletonsCurrentlyInCreation .remove (beanName )) {
338
+ if (!this .inCreationCheckExclusions .containsKey (beanName ) &&
339
+ !this .singletonsCurrentlyInCreation .remove (beanName )) {
312
340
throw new IllegalStateException ("Singleton '" + beanName + "' isn't currently in creation" );
313
341
}
314
342
}
315
343
316
- public final void setCurrentlyInCreation (String beanName , boolean inCreation ) {
317
- if (!inCreation ) {
318
- this .inCreationCheckExclusions .add (beanName );
319
- }
320
- else {
321
- this .inCreationCheckExclusions .remove (beanName );
322
- }
323
- }
324
-
325
- /**
326
- * Return whether the specified singleton bean is currently in creation
327
- * (within the entire factory).
328
- * @param beanName the name of the bean
329
- */
330
- public final boolean isSingletonCurrentlyInCreation (String beanName ) {
331
- return this .singletonsCurrentlyInCreation .contains (beanName );
332
- }
333
-
334
344
335
345
/**
336
346
* Add the given bean to the list of disposable beans in this registry.
0 commit comments