diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java index 3e7fc52fb0..18aaa23d03 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,6 +81,7 @@ class BeanDefinitionValueResolver { this.typeConverter = typeConverter; } + /** * Given a PropertyValue, return a value, resolving any references to other * beans in the factory if necessary. The value could be: @@ -123,7 +124,9 @@ class BeanDefinitionValueResolver { else if (value instanceof BeanDefinition) { // Resolve plain BeanDefinition, without contained name: use dummy name. BeanDefinition bd = (BeanDefinition) value; - return resolveInnerBean(argName, "(inner bean)", bd); + String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + + ObjectUtils.getIdentityHexString(bd); + return resolveInnerBean(argName, innerBeanName, bd); } else if (value instanceof ManagedArray) { // May need to resolve contained runtime references. @@ -256,20 +259,25 @@ class BeanDefinitionValueResolver { mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition); // Check given bean name whether it is unique. If not already unique, // add counter - increasing the counter until the name is unique. - String actualInnerBeanName = adaptInnerBeanName(innerBeanName); + String actualInnerBeanName = innerBeanName; + if (mbd.isSingleton()) { + actualInnerBeanName = adaptInnerBeanName(innerBeanName); + } this.beanFactory.registerContainedBean(actualInnerBeanName, this.beanName); // Guarantee initialization of beans that the inner bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dependsOnBean : dependsOn) { - this.beanFactory.getBean(dependsOnBean); this.beanFactory.registerDependentBean(dependsOnBean, actualInnerBeanName); + this.beanFactory.getBean(dependsOnBean); } } + // Actually create the inner bean instance now... Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null); if (innerBean instanceof FactoryBean) { boolean synthetic = mbd.isSynthetic(); - return this.beanFactory.getObjectFromFactoryBean((FactoryBean) innerBean, actualInnerBeanName, !synthetic); + return this.beanFactory.getObjectFromFactoryBean( + (FactoryBean) innerBean, actualInnerBeanName, !synthetic); } else { return innerBean; diff --git a/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests-reftypes.xml b/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests-reftypes.xml index f8e3280906..2f369564bf 100644 --- a/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests-reftypes.xml +++ b/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests-reftypes.xml @@ -129,6 +129,15 @@ + + + + inner1 + 6 + + + + hasInner 5 diff --git a/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java b/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java index 80ee4cea68..a095869e3d 100644 --- a/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java @@ -27,8 +27,8 @@ import java.net.URL; import java.util.Map; import org.apache.commons.logging.LogFactory; - import org.junit.Test; +import org.xml.sax.InputSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.AopUtils; @@ -65,7 +65,6 @@ import org.springframework.util.ClassUtils; import org.springframework.util.FileCopyUtils; import org.springframework.util.SerializationTestUtils; import org.springframework.util.StopWatch; -import org.xml.sax.InputSource; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -229,6 +228,20 @@ public final class XmlBeanFactoryTests { assertEquals("inner1", innerForConstructor.getName()); assertEquals(6, innerForConstructor.getAge()); + hasInnerBeansForConstructor = (TestBean) xbf.getBean("hasInnerBeansAsPrototype"); + innerForConstructor = (TestBean) hasInnerBeansForConstructor.getSpouse(); + assertNotNull(innerForConstructor); + assertEquals("innerBean", innerForConstructor.getBeanName()); + assertEquals("inner1", innerForConstructor.getName()); + assertEquals(6, innerForConstructor.getAge()); + + hasInnerBeansForConstructor = (TestBean) xbf.getBean("hasInnerBeansAsPrototype"); + innerForConstructor = (TestBean) hasInnerBeansForConstructor.getSpouse(); + assertNotNull(innerForConstructor); + assertEquals("innerBean", innerForConstructor.getBeanName()); + assertEquals("inner1", innerForConstructor.getName()); + assertEquals(6, innerForConstructor.getAge()); + xbf.destroySingletons(); assertTrue(inner1.wasDestroyed()); assertTrue(inner2.wasDestroyed());