diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java
index 995be594f2..cddecfc3b1 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java
@@ -1251,14 +1251,15 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
- mbd.setScope(BeanDefinition.SCOPE_SINGLETON);
+ mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
- // Check for a mismatch between an inner bean's scope and its containing
- // bean's scope: For example, a bean contained in a non-singleton bean
- // cannot be a singleton itself. Let's correct this on the fly here.
- if (containingBd != null && !mbd.isPrototype() && !mbd.getScope().equals(containingBd.getScope())) {
- mbd.setScope(containingBd.isSingleton() ? BeanDefinition.SCOPE_PROTOTYPE : containingBd.getScope());
+ // A bean contained in a non-singleton bean cannot be a singleton itself.
+ // Let's correct this on the fly here, since this might be the result of
+ // parent-child merging for the outer bean, in which case the original inner bean
+ // definition will not have inherited the merged outer bean's singleton status.
+ if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
+ mbd.setScope(containingBd.getScope());
}
// Only cache the merged bean definition if we're already about to create an
diff --git a/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.1.xsd b/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.1.xsd
index 9a9cb52bb1..8dfe6d25f2 100644
--- a/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.1.xsd
+++ b/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.1.xsd
@@ -31,8 +31,8 @@
(or an ancestor factory).
As alternative to bean references, "inner bean definitions" can be used.
- Singleton flags of such inner bean definitions are effectively ignored:
- inner beans are typically anonymous prototypes.
+ Such inner beans do not have an independent lifecycle; they are typically
+ anonymous nested objects that share the scope of their containing bean.
There is also support for lists, sets, maps, and java.util.Properties
as bean property types or constructor argument types.
@@ -113,16 +113,19 @@
@@ -130,7 +133,9 @@
@@ -305,10 +310,10 @@
service objects. Further scopes, such as "request" or "session", might
be supported by extended bean factories (e.g. in a web environment).
- Inner bean definitions inherit the singleton status of their containing
- bean definition, unless explicitly specified: The inner bean will be a
+ Inner bean definitions inherit the scope of their containing bean
+ definition, unless explicitly specified: The inner bean will be a
singleton if the containing bean is a singleton, and a prototype if
- the containing bean has any other scope.
+ the containing bean is a prototype, etc.
]]>
@@ -328,13 +333,15 @@
@@ -344,7 +351,7 @@
Controls whether bean properties are "autowired".
This is an automagical process in which bean references don't need
to be coded explicitly in the XML bean definition file, but rather the
- Spring container works out dependencies.
+ Spring container works out dependencies. The effective default is "no".
There are 4 modes:
@@ -379,7 +386,10 @@
elements, always override autowiring.
Note: This attribute will not be inherited by child bean definitions.
- Hence, it needs to be specified per concrete bean definition.
+ Hence, it needs to be specified per concrete bean definition. It can be
+ shared through the 'default-autowire' attribute at the 'beans' level
+ and potentially inherited from outer 'beans' defaults in case of nested
+ 'beans' sections (e.g. with different profiles).
]]>
diff --git a/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.2.xsd b/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.2.xsd
index c77e0250e1..4064c7bc0d 100644
--- a/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.2.xsd
+++ b/spring-beans/src/main/resources/org/springframework/beans/factory/xml/spring-beans-4.2.xsd
@@ -31,8 +31,8 @@
(or an ancestor factory).
As alternative to bean references, "inner bean definitions" can be used.
- Singleton flags of such inner bean definitions are effectively ignored:
- inner beans are typically anonymous prototypes.
+ Such inner beans do not have an independent lifecycle; they are typically
+ anonymous nested objects that share the scope of their containing bean.
There is also support for lists, sets, maps, and java.util.Properties
as bean property types or constructor argument types.
@@ -310,10 +310,10 @@
service objects. Further scopes, such as "request" or "session", might
be supported by extended bean factories (e.g. in a web environment).
- Inner bean definitions inherit the singleton status of their containing
- bean definition, unless explicitly specified: The inner bean will be a
+ Inner bean definitions inherit the scope of their containing bean
+ definition, unless explicitly specified: The inner bean will be a
singleton if the containing bean is a singleton, and a prototype if
- the containing bean has any other scope.
+ the containing bean is a prototype, etc.
]]>
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
index 14ad5c1488..c7c5876585 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
@@ -2548,39 +2548,6 @@ public class DefaultListableBeanFactoryTests {
assertEquals("Destroy methods invoked", 1, BeanWithDestroyMethod.closeCount);
}
- @Test
- public void testDestroyMethodOnInnerBeanAsCustomScope() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition innerBd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- innerBd.setScope("custom");
- innerBd.setDestroyMethodName("close");
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- bd.setDestroyMethodName("close");
- bd.getPropertyValues().add("inner", innerBd);
- lbf.registerBeanDefinition("test", bd);
- BeanWithDestroyMethod.closeCount = 0;
- lbf.preInstantiateSingletons();
- lbf.destroySingletons();
- assertEquals("Destroy methods not invoked", 1, BeanWithDestroyMethod.closeCount);
- }
-
- @Test
- public void testDestroyMethodOnInnerBeanAsCustomScopeWithinPrototype() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition innerBd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- innerBd.setScope("custom");
- innerBd.setDestroyMethodName("close");
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- bd.setDestroyMethodName("close");
- bd.getPropertyValues().add("inner", innerBd);
- lbf.registerBeanDefinition("test", bd);
- BeanWithDestroyMethod.closeCount = 0;
- Object prototypeInstance = lbf.getBean("test");
- lbf.destroyBean("test", prototypeInstance);
- assertEquals("Destroy methods not invoked", 1, BeanWithDestroyMethod.closeCount);
- }
-
@Test
public void testFindTypeOfSingletonFactoryMethodOnBeanInstance() {
findTypeOfPrototypeFactoryMethodOnBeanInstance(true);
diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc
index caa564f872..6c2a61c157 100644
--- a/src/asciidoc/core-beans.adoc
+++ b/src/asciidoc/core-beans.adoc
@@ -1397,10 +1397,17 @@ so-called __inner bean__.
----
-An inner bean definition does not require a defined id or name; the container ignores
-these values. It also ignores the `scope` flag. Inner beans are __always__ anonymous and
-they are __always__ created with the outer bean. It is __not__ possible to inject inner
-beans into collaborating beans other than into the enclosing bean.
+An inner bean definition does not require a defined id or name; if specified, the container
+does not use such a value as an identifier. The container also ignores the `scope` flag on
+creation: Inner beans are __always__ anonymous and they are __always__ created with the outer
+bean. It is __not__ possible to inject inner beans into collaborating beans other than into
+the enclosing bean or to access them independently.
+
+As a corner case, it is possible to receive destruction callbacks from a custom scope, e.g.
+for a request-scoped inner bean contained within a singleton bean: The creation of the inner
+bean instance will be tied to its containing bean, but destruction callbacks allow it to
+participate in the request scope's lifecycle. This is not a common scenario; inner beans
+typically simply share their containing bean's scope.
[[beans-collection-elements]]