Skip to content

Commit e213561

Browse files
jhoellerunknown
authored and
unknown
committed
AbstractBeanFactory removes alreadyCreated entry after bean creation failure
Issue: SPR-10896
1 parent 0ee910c commit e213561

File tree

1 file changed

+73
-59
lines changed

1 file changed

+73
-59
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java

Lines changed: 73 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -278,79 +278,85 @@ protected <T> T doGetBean(
278278
markBeanAsCreated(beanName);
279279
}
280280

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);
308291
}
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);
322292
}
323-
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
324-
}
325293

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>() {
334297
@Override
335298
public Object getObject() throws BeansException {
336-
beforePrototypeCreation(beanName);
337299
try {
338300
return createBean(beanName, mbd, args);
339301
}
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;
342308
}
343309
}
344310
});
345-
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
311+
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
346312
}
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+
}
352354
}
353355
}
356+
catch (BeansException ex) {
357+
cleanupAfterBeanCreationFailure(beanName);
358+
throw ex;
359+
}
354360
}
355361

356362
// Check if required type matches the type of the actual bean instance.
@@ -1430,6 +1436,14 @@ protected void markBeanAsCreated(String beanName) {
14301436
this.alreadyCreated.add(beanName);
14311437
}
14321438

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+
14331447
/**
14341448
* Determine whether the specified bean is eligible for having
14351449
* its bean definition metadata cached.

0 commit comments

Comments
 (0)