17
17
package org .springframework .beans .factory .support ;
18
18
19
19
import java .util .Collections ;
20
- import java .util .HashMap ;
21
20
import java .util .HashSet ;
22
21
import java .util .Iterator ;
23
22
import java .util .LinkedHashMap ;
27
26
import java .util .concurrent .ConcurrentHashMap ;
28
27
import java .util .concurrent .locks .Lock ;
29
28
import java .util .concurrent .locks .ReentrantLock ;
29
+ import java .util .function .Consumer ;
30
30
31
31
import org .springframework .beans .factory .BeanCreationException ;
32
32
import org .springframework .beans .factory .BeanCreationNotAllowedException ;
@@ -79,8 +79,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
79
79
/** Cache of singleton objects: bean name to bean instance. */
80
80
private final Map <String , Object > singletonObjects = new ConcurrentHashMap <>(256 );
81
81
82
- /** Cache of singleton factories: bean name to ObjectFactory. */
83
- private final Map <String , ObjectFactory <?>> singletonFactories = new HashMap <>(16 );
82
+ /** Creation-time registry of singleton factories: bean name to ObjectFactory. */
83
+ private final Map <String , ObjectFactory <?>> singletonFactories = new ConcurrentHashMap <>(16 );
84
+
85
+ /** Custom callbacks for singleton creation/registration. */
86
+ private final Map <String , Consumer <Object >> singletonCallbacks = new ConcurrentHashMap <>(16 );
84
87
85
88
/** Cache of early singleton objects: bean name to bean instance. */
86
89
private final Map <String , Object > earlySingletonObjects = new ConcurrentHashMap <>(16 );
@@ -133,8 +136,8 @@ public void registerSingleton(String beanName, Object singletonObject) throws Il
133
136
}
134
137
135
138
/**
136
- * Add the given singleton object to the singleton cache of this factory .
137
- * <p>To be called for eager registration of singletons.
139
+ * Add the given singleton object to the singleton registry .
140
+ * <p>To be called for exposure of freshly registered/created singletons.
138
141
* @param beanName the name of the bean
139
142
* @param singletonObject the singleton object
140
143
*/
@@ -147,12 +150,17 @@ protected void addSingleton(String beanName, Object singletonObject) {
147
150
this .singletonFactories .remove (beanName );
148
151
this .earlySingletonObjects .remove (beanName );
149
152
this .registeredSingletons .add (beanName );
153
+
154
+ Consumer <Object > callback = this .singletonCallbacks .get (beanName );
155
+ if (callback != null ) {
156
+ callback .accept (singletonObject );
157
+ }
150
158
}
151
159
152
160
/**
153
161
* Add the given singleton factory for building the specified singleton
154
162
* if necessary.
155
- * <p>To be called for eager registration of singletons , e.g. to be able to
163
+ * <p>To be called for early exposure purposes , e.g. to be able to
156
164
* resolve circular references.
157
165
* @param beanName the name of the bean
158
166
* @param singletonFactory the factory for the singleton object
@@ -164,6 +172,11 @@ protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFa
164
172
this .registeredSingletons .add (beanName );
165
173
}
166
174
175
+ @ Override
176
+ public void addSingletonCallback (String beanName , Consumer <Object > singletonConsumer ) {
177
+ this .singletonCallbacks .put (beanName , singletonConsumer );
178
+ }
179
+
167
180
@ Override
168
181
@ Nullable
169
182
public Object getSingleton (String beanName ) {
@@ -262,6 +275,7 @@ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
262
275
}
263
276
}
264
277
}
278
+
265
279
if (this .singletonsCurrentlyInDestruction ) {
266
280
throw new BeanCreationNotAllowedException (beanName ,
267
281
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
@@ -343,8 +357,8 @@ protected void onSuppressedException(Exception ex) {
343
357
}
344
358
345
359
/**
346
- * Remove the bean with the given name from the singleton cache of this factory,
347
- * to be able to clean up eager registration of a singleton if creation failed.
360
+ * Remove the bean with the given name from the singleton registry, either on
361
+ * regular destruction or on cleanup after early exposure when creation failed.
348
362
* @param beanName the name of the bean
349
363
*/
350
364
protected void removeSingleton (String beanName ) {
0 commit comments