Scope annotation in class hierarchies vs XML bean definition inheritance

Issue: SPR-16602
This commit is contained in:
Juergen Hoeller 2018-03-16 18:49:00 +01:00
parent b31d55dfce
commit 914b2470dc
3 changed files with 41 additions and 16 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,6 +35,12 @@ import org.springframework.core.annotation.AliasFor;
* {@link Bean @Bean}, {@code @Scope} indicates the name of a scope to use * {@link Bean @Bean}, {@code @Scope} indicates the name of a scope to use
* for the instance returned from the method. * for the instance returned from the method.
* *
* <p><b>NOTE:</b> {@code @Scope} annotations are only introspected on the
* concrete bean class (for annotated components) or the factory method
* (for {@code @Bean} methods). In contrast to XML bean definitions,
* there is no notion of bean definition inheritance, and inheritance
* hierarchies at the class level are irrelevant for metadata purposes.
*
* <p>In this context, <em>scope</em> means the lifecycle of an instance, * <p>In this context, <em>scope</em> means the lifecycle of an instance,
* such as {@code singleton}, {@code prototype}, and so forth. Scopes * such as {@code singleton}, {@code prototype}, and so forth. Scopes
* provided out of the box in Spring may be referred to using the * provided out of the box in Spring may be referred to using the

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -1391,9 +1391,19 @@ public class XmlBeanFactoryTests {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
reader.loadBeanDefinitions(OVERRIDES_CONTEXT); reader.loadBeanDefinitions(OVERRIDES_CONTEXT);
TestBean jenny = (TestBean) xbf.getBean("jennyChild");
assertEquals(1, jenny.getFriends().size()); TestBean jenny1 = (TestBean) xbf.getBean("jennyChild");
assertTrue(jenny.getFriends().iterator().next() instanceof TestBean); assertEquals(1, jenny1.getFriends().size());
Object friend1 = jenny1.getFriends().iterator().next();
assertTrue(friend1 instanceof TestBean);
TestBean jenny2 = (TestBean) xbf.getBean("jennyChild");
assertEquals(1, jenny2.getFriends().size());
Object friend2 = jenny2.getFriends().iterator().next();
assertTrue(friend2 instanceof TestBean);
assertNotSame(jenny1, jenny2);
assertNotSame(friend1, friend2);
} }
@Test @Test

View File

@ -5710,10 +5710,10 @@ Spring stereotype annotation (`@Component`, `@Repository`, `@Service`, and
`@Controller`) that contains a _name_ `value` will thereby provide that name to the `@Controller`) that contains a _name_ `value` will thereby provide that name to the
corresponding bean definition. corresponding bean definition.
If such an annotation contains no _name_ `value` or for any other detected component (such If such an annotation contains no _name_ `value` or for any other detected component
as those discovered by custom filters), the default bean name generator returns the (such as those discovered by custom filters), the default bean name generator returns
uncapitalized non-qualified class name. For example, if the following two components the uncapitalized non-qualified class name. For example, if the following component
were detected, the names would be `myMovieLister` and `movieFinderImpl`: classes were detected, the names would be `myMovieLister` and `movieFinderImpl`:
[source,java,indent=0] [source,java,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
@ -5772,8 +5772,8 @@ auto-generated names are adequate whenever the container is responsible for wiri
As with Spring-managed components in general, the default and most common scope for As with Spring-managed components in general, the default and most common scope for
autodetected components is `singleton`. However, sometimes you need a different scope autodetected components is `singleton`. However, sometimes you need a different scope
which can be specified via the `@Scope` annotation. Simply provide the name of the scope which can be specified via the `@Scope` annotation. Simply provide the name of the
within the annotation: scope within the annotation:
[source,java,indent=0] [source,java,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
@ -5785,8 +5785,19 @@ within the annotation:
} }
---- ----
For details on web-specific scopes, see <<beans-factory-scopes-other>>. [NOTE]
====
`@Scope` annotations are only introspected on the concrete bean class (for annotated
components) or the factory method (for `@Bean` methods). In contrast to XML bean
definitions, there is no notion of bean definition inheritance, and inheritance
hierarchies at the class level are irrelevant for metadata purposes.
====
For details on web-specific scopes such as "request"/"session" in a Spring context,
see <<beans-factory-scopes-other>>. Like the pre-built annotations for those scopes,
you may also compose your own scoping annotations using Spring's meta-annotation
approach: e.g. a custom annotation meta-annotated with `@Scope("prototype")`,
possibly also declaring a custom scoped-proxy mode.
[NOTE] [NOTE]
==== ====
@ -5811,8 +5822,7 @@ fully-qualified class name when configuring the scanner:
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
<beans> <beans>
<context:component-scan base-package="org.example" <context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver"/>
scope-resolver="org.example.MyScopeResolver" />
</beans> </beans>
---- ----
@ -5836,8 +5846,7 @@ the following configuration will result in standard JDK dynamic proxies:
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
<beans> <beans>
<context:component-scan base-package="org.example" <context:component-scan base-package="org.example" scoped-proxy="interfaces"/>
scoped-proxy="interfaces" />
</beans> </beans>
---- ----