@@ -278,79 +278,85 @@ protected <T> T doGetBean(
278
278
markBeanAsCreated (beanName );
279
279
}
280
280
281
- final RootBeanDefinition mbd = getMergedLocalBeanDefinition (beanName );
282
- checkMergedBeanDefinition (mbd , beanName , args );
283
-
284
- // Guarantee initialization of beans that the current bean depends on.
285
- String [] dependsOn = mbd .getDependsOn ();
286
- if (dependsOn != null ) {
287
- for (String dependsOnBean : dependsOn ) {
288
- getBean (dependsOnBean );
289
- registerDependentBean (dependsOnBean , beanName );
290
- }
291
- }
292
-
293
- // Create bean instance.
294
- if (mbd .isSingleton ()) {
295
- sharedInstance = getSingleton (beanName , new ObjectFactory <Object >() {
296
- @ Override
297
- public Object getObject () throws BeansException {
298
- try {
299
- return createBean (beanName , mbd , args );
300
- }
301
- catch (BeansException ex ) {
302
- // Explicitly remove instance from singleton cache: It might have been put there
303
- // eagerly by the creation process, to allow for circular reference resolution.
304
- // Also remove any beans that received a temporary reference to the bean.
305
- destroySingleton (beanName );
306
- throw ex ;
307
- }
281
+ try {
282
+ final RootBeanDefinition mbd = getMergedLocalBeanDefinition (beanName );
283
+ checkMergedBeanDefinition (mbd , beanName , args );
284
+
285
+ // Guarantee initialization of beans that the current bean depends on.
286
+ String [] dependsOn = mbd .getDependsOn ();
287
+ if (dependsOn != null ) {
288
+ for (String dependsOnBean : dependsOn ) {
289
+ getBean (dependsOnBean );
290
+ registerDependentBean (dependsOnBean , beanName );
308
291
}
309
- });
310
- bean = getObjectForBeanInstance (sharedInstance , name , beanName , mbd );
311
- }
312
-
313
- else if (mbd .isPrototype ()) {
314
- // It's a prototype -> create a new instance.
315
- Object prototypeInstance = null ;
316
- try {
317
- beforePrototypeCreation (beanName );
318
- prototypeInstance = createBean (beanName , mbd , args );
319
- }
320
- finally {
321
- afterPrototypeCreation (beanName );
322
292
}
323
- bean = getObjectForBeanInstance (prototypeInstance , name , beanName , mbd );
324
- }
325
293
326
- else {
327
- String scopeName = mbd .getScope ();
328
- final Scope scope = this .scopes .get (scopeName );
329
- if (scope == null ) {
330
- throw new IllegalStateException ("No Scope registered for scope '" + scopeName + "'" );
331
- }
332
- try {
333
- Object scopedInstance = scope .get (beanName , new ObjectFactory <Object >() {
294
+ // Create bean instance.
295
+ if (mbd .isSingleton ()) {
296
+ sharedInstance = getSingleton (beanName , new ObjectFactory <Object >() {
334
297
@ Override
335
298
public Object getObject () throws BeansException {
336
- beforePrototypeCreation (beanName );
337
299
try {
338
300
return createBean (beanName , mbd , args );
339
301
}
340
- finally {
341
- afterPrototypeCreation (beanName );
302
+ catch (BeansException ex ) {
303
+ // Explicitly remove instance from singleton cache: It might have been put there
304
+ // eagerly by the creation process, to allow for circular reference resolution.
305
+ // Also remove any beans that received a temporary reference to the bean.
306
+ destroySingleton (beanName );
307
+ throw ex ;
342
308
}
343
309
}
344
310
});
345
- bean = getObjectForBeanInstance (scopedInstance , name , beanName , mbd );
311
+ bean = getObjectForBeanInstance (sharedInstance , name , beanName , mbd );
346
312
}
347
- catch (IllegalStateException ex ) {
348
- throw new BeanCreationException (beanName ,
349
- "Scope '" + scopeName + "' is not active for the current thread; " +
350
- "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton" ,
351
- ex );
313
+
314
+ else if (mbd .isPrototype ()) {
315
+ // It's a prototype -> create a new instance.
316
+ Object prototypeInstance = null ;
317
+ try {
318
+ beforePrototypeCreation (beanName );
319
+ prototypeInstance = createBean (beanName , mbd , args );
320
+ }
321
+ finally {
322
+ afterPrototypeCreation (beanName );
323
+ }
324
+ bean = getObjectForBeanInstance (prototypeInstance , name , beanName , mbd );
325
+ }
326
+
327
+ else {
328
+ String scopeName = mbd .getScope ();
329
+ final Scope scope = this .scopes .get (scopeName );
330
+ if (scope == null ) {
331
+ throw new IllegalStateException ("No Scope registered for scope '" + scopeName + "'" );
332
+ }
333
+ try {
334
+ Object scopedInstance = scope .get (beanName , new ObjectFactory <Object >() {
335
+ @ Override
336
+ public Object getObject () throws BeansException {
337
+ beforePrototypeCreation (beanName );
338
+ try {
339
+ return createBean (beanName , mbd , args );
340
+ }
341
+ finally {
342
+ afterPrototypeCreation (beanName );
343
+ }
344
+ }
345
+ });
346
+ bean = getObjectForBeanInstance (scopedInstance , name , beanName , mbd );
347
+ }
348
+ catch (IllegalStateException ex ) {
349
+ throw new BeanCreationException (beanName ,
350
+ "Scope '" + scopeName + "' is not active for the current thread; " +
351
+ "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton" ,
352
+ ex );
353
+ }
352
354
}
353
355
}
356
+ catch (BeansException ex ) {
357
+ cleanupAfterBeanCreationFailure (beanName );
358
+ throw ex ;
359
+ }
354
360
}
355
361
356
362
// Check if required type matches the type of the actual bean instance.
@@ -1430,6 +1436,14 @@ protected void markBeanAsCreated(String beanName) {
1430
1436
this .alreadyCreated .add (beanName );
1431
1437
}
1432
1438
1439
+ /**
1440
+ * Perform appropriate cleanup of cached metadata after bean creation failed.
1441
+ * @param beanName the name of the bean
1442
+ */
1443
+ protected void cleanupAfterBeanCreationFailure (String beanName ) {
1444
+ this .alreadyCreated .remove (beanName );
1445
+ }
1446
+
1433
1447
/**
1434
1448
* Determine whether the specified bean is eligible for having
1435
1449
* its bean definition metadata cached.
0 commit comments