diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java b/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java
index 9d04a9df26..8369957f59 100644
--- a/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java
+++ b/spring-context/src/main/java/org/springframework/context/annotation/Lazy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2021 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.
@@ -47,6 +47,11 @@ import java.lang.annotation.Target;
* or {@link javax.inject.Inject}: In that context, it leads to the creation of a
* lazy-resolution proxy for all affected dependencies, as an alternative to using
* {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}.
+ * Please note that such a lazy-resolution proxy will always be injected; if the target
+ * dependency does not exist, you will only be able to find out through an exception on
+ * invocation. As a consequence, such an injection point results in unintuitive behavior
+ * for optional dependencies. For a programmatic equivalent, allowing for lazy references
+ * with more sophistication, consider {@link org.springframework.beans.factory.ObjectProvider}.
*
* @author Chris Beams
* @author Juergen Hoeller
diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc
index f02e860c00..4dc5c4a93b 100644
--- a/src/docs/asciidoc/core/core-beans.adoc
+++ b/src/docs/asciidoc/core/core-beans.adoc
@@ -1024,7 +1024,7 @@ by type without help. Consider the following class:
class ExampleBean(
private val years: Int, // Number of years to calculate the Ultimate Answer
- private val ultimateAnswer: String// The Answer to Life, the Universe, and Everything
+ private val ultimateAnswer: String // The Answer to Life, the Universe, and Everything
)
----
@@ -1608,7 +1608,7 @@ listings shows how to use the `parent` attribute:
----
-
+
----
@@ -1690,7 +1690,7 @@ respectively. The following example shows how to use them:
@@ -1834,7 +1834,7 @@ class SomeClass {
When the `accounts` property of the `something` bean is prepared for injection, the generics
information about the element type of the strongly-typed `Map` is
available by reflection. Thus, Spring's type conversion infrastructure recognizes the
-various value elements as being of type `Float`, and the string values (`9.99, 2.75`, and
+various value elements as being of type `Float`, and the string values (`9.99`, `2.75`, and
`3.99`) are converted into an actual `Float` type.
@@ -2028,7 +2028,7 @@ not commonly used since the plain order of declaration is usually sufficient the
In practice, the constructor resolution
<> is quite efficient in matching
arguments, so unless you really need to, we recommend using the name notation
-through-out your configuration.
+throughout your configuration.
[[beans-compound-property-names]]
@@ -2503,13 +2503,13 @@ declared return type of the lookup method:
public abstract class CommandManager {
public Object process(Object commandState) {
- MyCommand command = createCommand();
+ Command command = createCommand();
command.setState(commandState);
return command.execute();
}
@Lookup
- protected abstract MyCommand createCommand();
+ protected abstract Command createCommand();
}
----
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
@@ -2604,9 +2604,9 @@ interface provides the new method definition, as the following example shows:
.Kotlin
----
/**
- * meant to be used to override the existing computeValue(String)
- * implementation in MyValueCalculator
- */
+ * meant to be used to override the existing computeValue(String)
+ * implementation in MyValueCalculator
+ */
class ReplacementComputeValue : MethodReplacer {
override fun reimplement(obj: Any, method: Method, args: Array): Any {
@@ -2806,7 +2806,7 @@ prototype-scoped bean repeatedly at runtime. You cannot dependency-inject a
prototype-scoped bean into your singleton bean, because that injection occurs only
once, when the Spring container instantiates the singleton bean and resolves
and injects its dependencies. If you need a new instance of a prototype bean at
-runtime more than once, see <>
+runtime more than once, see <>.
@@ -2984,7 +2984,7 @@ The Spring container creates a new instance of the `AppPreferences` bean by usin
`appPreferences` bean is scoped at the `ServletContext` level and stored as a regular
`ServletContext` attribute. This is somewhat similar to a Spring singleton bean but
differs in two important ways: It is a singleton per `ServletContext`, not per Spring
-'ApplicationContext' (for which there may be several in any given web application),
+`ApplicationContext` (for which there may be several in any given web application),
and it is actually exposed and therefore visible as a `ServletContext` attribute.
When using annotation-driven components or Java configuration, you can use the
@@ -3039,7 +3039,7 @@ constructor or setter argument or autowired field) as `ObjectFactory`, which delivers
+As an extended variant, you may declare `ObjectProvider` which delivers
several additional access variants, including `getIfAvailable` and `getIfUnique`.
The JSR-330 variant of this is called `Provider` and is used with a `Provider`
@@ -3100,7 +3100,7 @@ to the HTTP `Session`-scoped bean (`userPreferences`). The salient point here is
`userManager` bean is a singleton: it is instantiated exactly once per
container, and its dependencies (in this case only one, the `userPreferences` bean) are
also injected only once. This means that the `userManager` bean operates only on the
-exact same `userPreferences` object (that is, the one with which it was originally injected.
+exact same `userPreferences` object (that is, the one with which it was originally injected).
This is not the behavior you want when injecting a shorter-lived scoped bean into a
longer-lived scoped bean (for example, injecting an HTTP `Session`-scoped collaborating
@@ -3350,8 +3350,9 @@ of the scope. You can also do the `Scope` registration declaratively, by using t
----
-NOTE: When you place `` in a `FactoryBean` implementation, it is the factory
-bean itself that is scoped, not the object returned from `getObject()`.
+NOTE: When you place `` within a `` declaration for a
+`FactoryBean` implementation, it is the factory bean itself that is scoped, not the object
+returned from `getObject()`.
@@ -3927,7 +3928,7 @@ shows the definition of the BeanNameAware interface:
----
The callback is invoked after population of normal bean properties but before an
-initialization callback such as `InitializingBean`, `afterPropertiesSet`, or a custom
+initialization callback such as `InitializingBean.afterPropertiesSet()` or a custom
init-method.
@@ -3959,7 +3960,7 @@ dependency type. The following table summarizes the most important `Aware` inter
| `BeanFactoryAware`
| Declaring `BeanFactory`.
-| <>
+| <>
| `BeanNameAware`
| Name of the declaring bean.
@@ -4146,7 +4147,7 @@ or it may wrap a bean with a proxy. Some Spring AOP infrastructure classes are
implemented as bean post-processors in order to provide proxy-wrapping logic.
An `ApplicationContext` automatically detects any beans that are defined in the
-configuration metadata that implements the `BeanPostProcessor` interface. The
+configuration metadata that implement the `BeanPostProcessor` interface. The
`ApplicationContext` registers these beans as post-processors so that they can be called
later, upon bean creation. Bean post-processors can be deployed in the container in the
same fashion as any other beans.
@@ -4544,22 +4545,22 @@ Java as opposed to a (potentially) verbose amount of XML, you can create your ow
`FactoryBean`, write the complex initialization inside that class, and then plug your
custom `FactoryBean` into the container.
-The `FactoryBean` interface provides three methods:
+The `FactoryBean` interface provides three methods:
-* `Object getObject()`: Returns an instance of the object this factory creates. The
+* `T getObject()`: Returns an instance of the object this factory creates. The
instance can possibly be shared, depending on whether this factory returns singletons
or prototypes.
* `boolean isSingleton()`: Returns `true` if this `FactoryBean` returns singletons or
- `false` otherwise.
-* `Class getObjectType()`: Returns the object type returned by the `getObject()` method
+ `false` otherwise. The default implementation of this method returns `true`.
+* `Class> getObjectType()`: Returns the object type returned by the `getObject()` method
or `null` if the type is not known in advance.
-The `FactoryBean` concept and interface is used in a number of places within the Spring
+The `FactoryBean` concept and interface are used in a number of places within the Spring
Framework. More than 50 implementations of the `FactoryBean` interface ship with Spring
itself.
When you need to ask a container for an actual `FactoryBean` instance itself instead of
-the bean it produces, preface the bean's `id` with the ampersand symbol (`&`) when
+the bean it produces, prefix the bean's `id` with the ampersand symbol (`&`) when
calling the `getBean()` method of the `ApplicationContext`. So, for a given `FactoryBean`
with an `id` of `myBean`, invoking `getBean("myBean")` on the container returns the
product of the `FactoryBean`, whereas invoking `getBean("&myBean")` returns the
@@ -4677,11 +4678,11 @@ example:
----
class SimpleMovieLister {
- @Required
- lateinit var movieFinder: MovieFinder
+ @Required
+ lateinit var movieFinder: MovieFinder
- // ...
-}
+ // ...
+ }
----
This annotation indicates that the affected bean property must be populated at
@@ -5377,7 +5378,7 @@ Letting qualifier values select against target bean names, within the type-match
candidates, does not require a `@Qualifier` annotation at the injection point.
If there is no other resolution indicator (such as a qualifier or a primary marker),
for a non-unique dependency situation, Spring matches the injection point name
-(that is, the field name or parameter name) against the target bean names and choose the
+(that is, the field name or parameter name) against the target bean names and chooses the
same-named candidate, if any.
====
@@ -5392,7 +5393,7 @@ matching an `account` qualifier against beans marked with the same qualifier lab
For beans that are themselves defined as a collection, `Map`, or array type, `@Resource`
is a fine solution, referring to the specific collection or array bean by unique name.
-That said, as of 4.3, collection, you can match `Map`, and array types through Spring's
+That said, as of 4.3, you can match collection, `Map`, and array types through Spring's
`@Autowired` type matching algorithm as well, as long as the element type information
is preserved in `@Bean` return type signatures or collection inheritance hierarchies.
In this case, you can use qualifier values to select among same-typed collections,
@@ -6046,14 +6047,14 @@ example shows:
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
.Java
----
- @Configuration
- public class AppConfig {
+ @Configuration
+ public class AppConfig {
- @Bean
- public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
- return new PropertySourcesPlaceholderConfigurer();
- }
- }
+ @Bean
+ public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
+ return new PropertySourcesPlaceholderConfigurer();
+ }
+ }
----
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
.Kotlin
@@ -6079,7 +6080,7 @@ will get properties from `application.properties` and `application.yml` files.
Built-in converter support provided by Spring allows simple type conversion (to `Integer`
or `int` for example) to be automatically handled. Multiple comma-separated values can be
-automatically converted to String array without extra effort.
+automatically converted to `String` array without extra effort.
It is possible to provide a default value as following:
@@ -6103,8 +6104,8 @@ It is possible to provide a default value as following:
class MovieRecommender(@Value("\${catalog.name:defaultCatalog}") private val catalog: String)
----
-A Spring `BeanPostProcessor` uses a `ConversionService` behind the scene to handle the
-process for converting the String value in `@Value` to the target type. If you want to
+A Spring `BeanPostProcessor` uses a `ConversionService` behind the scenes to handle the
+process for converting the `String` value in `@Value` to the target type. If you want to
provide conversion support for your own custom type, you can provide your own
`ConversionService` bean instance as the following example shows:
@@ -6130,7 +6131,7 @@ provide conversion support for your own custom type, you can provide your own
@Bean
fun conversionService(): ConversionService {
- return DefaultFormattingConversionService().apply {
+ return DefaultFormattingConversionService().apply {
addConverter(MyCustomConverter())
}
}
@@ -6319,7 +6320,7 @@ is meta-annotated with `@Component`, as the following example shows:
// ...
}
----
-<1> The `Component` causes `@Service` to be treated in the same way as `@Component`.
+<1> The `@Component` causes `@Service` to be treated in the same way as `@Component`.
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
.Kotlin
@@ -6333,7 +6334,7 @@ is meta-annotated with `@Component`, as the following example shows:
// ...
}
----
-<1> The `Component` causes `@Service` to be treated in the same way as `@Component`.
+<1> The `@Component` causes `@Service` to be treated in the same way as `@Component`.
You can also combine meta-annotations to create "`composed annotations`". For example,
the `@RestController` annotation from Spring MVC is composed of `@Controller` and
@@ -6595,7 +6596,7 @@ and using "`stub`" repositories instead:
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
public class AppConfig {
- ...
+ // ...
}
----
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
@@ -6679,9 +6680,11 @@ factory method and other bean definition properties, such as a qualifier value t
the `@Qualifier` annotation. Other method-level annotations that can be specified are
`@Scope`, `@Lazy`, and custom qualifier annotations.
-TIP: In addition to its role for component initialization, you can also place the `@Lazy` annotation
-on injection points marked with `@Autowired` or `@Inject`. In this context, it
-leads to the injection of a lazy-resolution proxy.
+TIP: In addition to its role for component initialization, you can also place the `@Lazy`
+annotation on injection points marked with `@Autowired` or `@Inject`. In this context,
+it leads to the injection of a lazy-resolution proxy. However, such a proxy approach
+is rather limited. For sophisticated lazy interactions, in particular in combination
+with optional dependencies, we recommend `ObjectProvider` instead.
Autowired fields and methods are supported, as previously discussed, with additional
support for autowiring of `@Bean` methods. The following example shows how to do so:
@@ -7161,7 +7164,7 @@ configuration, as shown in the following example:
With Gradle 4.6 and later, the dependency should be declared in the `annotationProcessor`
configuration, as shown in the following example:
-[source,groovy,indent=0subs="verbatim,quotes,attributes"]
+[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
----
dependencies {
annotationProcessor "org.springframework:spring-context-indexer:{spring-version}"
@@ -7179,8 +7182,8 @@ TIP: The index is enabled automatically when a `META-INF/spring.components` file
on the classpath. If an index is partially available for some libraries (or use cases)
but could not be built for the whole application, you can fall back to a regular classpath
arrangement (as though no index were present at all) by setting `spring.index.ignore` to
-`true`, either as a JVM system property or in a `spring.properties` file at the root of
-the classpath.
+`true`, either as a JVM system property or via the
+<> mechanism.
@@ -7635,7 +7638,7 @@ to reduce subtle bugs that can be hard to track down when operating in "`lite`"
****
The `@Bean` and `@Configuration` annotations are discussed in depth in the following sections.
-First, however, we cover the various ways of creating a spring container using by
+First, however, we cover the various ways of creating a spring container by using
Java-based configuration.
@@ -7762,7 +7765,7 @@ To enable component scanning, you can annotate your `@Configuration` class as fo
@Configuration
@ComponentScan(basePackages = "com.acme") // <1>
public class AppConfig {
- ...
+ // ...
}
----
<1> This annotation enables component scanning.
@@ -7896,6 +7899,7 @@ init-param):
`@Bean` is a method-level annotation and a direct analog of the XML `` element.
The annotation supports some of the attributes offered by ``, such as:
+
* <>
* <>
* <>
@@ -7984,7 +7988,7 @@ return type, as the following example shows:
However, this limits the visibility for advance type prediction to the specified
interface type (`TransferService`). Then, with the full type (`TransferServiceImpl`)
-known to the container only once, the affected singleton bean has been instantiated.
+known to the container only once the affected singleton bean has been instantiated.
Non-lazy singleton beans get instantiated according to their declaration order,
so you may see different type matching results depending on when another component
tries to match by a non-declared type (such as `@Autowired TransferServiceImpl`,
@@ -8242,8 +8246,10 @@ Spring offers a convenient way of working with scoped dependencies through
<>. The easiest way to create
such a proxy when using the XML configuration is the `` element.
Configuring your beans in Java with a `@Scope` annotation offers equivalent support
-with the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`),
-but you can specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`.
+with the `proxyMode` attribute. The default is `ScopedProxyMode.DEFAULT`, which
+typically indicates that no scoped proxy should be created unless a different default
+has been configured at the component-scan instruction level. You can specify
+`ScopedProxyMode.TARGET_CLASS`, `ScopedProxyMode.INTERFACES` or `ScopedProxyMode.NO`.
If you port the scoped proxy example from the XML reference documentation (see
<>) to our `@Bean` using Java,
@@ -8297,7 +8303,7 @@ as the following example shows:
@Configuration
public class AppConfig {
- @Bean(name = "myThing")
+ @Bean("myThing")
public Thing thing() {
return new Thing();
}
@@ -8390,7 +8396,7 @@ annotation, as the following example shows:
=== Using the `@Configuration` annotation
`@Configuration` is a class-level annotation indicating that an object is a source of
-bean definitions. `@Configuration` classes declare beans through public `@Bean` annotated
+bean definitions. `@Configuration` classes declare beans through `@Bean`-annotated
methods. Calls to `@Bean` methods on `@Configuration` classes can also be used to define
inter-bean dependencies. See <> for a general introduction.
@@ -9139,7 +9145,7 @@ method that returns `true` or `false`. For example, the following listing shows
val attrs = metadata.getAllAnnotationAttributes(Profile::class.java.name)
if (attrs != null) {
for (value in attrs["value"]!!) {
- if (context.environment.acceptsProfiles(Profiles .of(*value as Array))) {
+ if (context.environment.acceptsProfiles(Profiles.of(*value as Array))) {
return true
}
}
@@ -9903,7 +9909,7 @@ as a way to provide a default definition for one or more beans. If any
profile is enabled, the default profile does not apply.
You can change the name of the default profile by using `setDefaultProfiles()` on
-the `Environment` or ,declaratively, by using the `spring.profiles.default` property.
+the `Environment` or, declaratively, by using the `spring.profiles.default` property.
@@ -10222,8 +10228,8 @@ bean with the same name. If it does, it uses that bean as the `MessageSource`. I
`DelegatingMessageSource` is instantiated in order to be able to accept calls to the
methods defined above.
-Spring provides two `MessageSource` implementations, `ResourceBundleMessageSource` and
-`StaticMessageSource`. Both implement `HierarchicalMessageSource` in order to do nested
+Spring provides three `MessageSource` implementations, `ResourceBundleMessageSource`, `ReloadableResourceBundleMessageSource`
+and `StaticMessageSource`. All of them implement `HierarchicalMessageSource` in order to do nested
messaging. The `StaticMessageSource` is rarely used but provides programmatic ways to
add messages to the source. The following example shows `ResourceBundleMessageSource`:
@@ -10408,6 +10414,10 @@ You can also use the `MessageSourceAware` interface to acquire a reference to an
`ApplicationContext` that implements the `MessageSourceAware` interface is injected with
the application context's `MessageSource` when the bean is created and configured.
+NOTE: Because Spring's `MessageSource` is based on Java's `ResourceBundle`, it does not merge
+bundles with the same base name, but will only use the first bundle found.
+Subsequent message bundles with the same base name are ignored.
+
NOTE: As an alternative to `ResourceBundleMessageSource`, Spring provides a
`ReloadableResourceBundleMessageSource` class. This variant supports the same bundle
file format but is more flexible than the standard JDK based
@@ -10718,7 +10728,7 @@ following example shows how to do so:
----
It is also possible to add additional runtime filtering by using the `condition` attribute
-of the annotation that defines a <> , which should match
+of the annotation that defines a <>, which should match
to actually invoke the method for a particular event.
The following example shows how our notifier can be rewritten to be invoked only if the
@@ -10830,10 +10840,12 @@ The following example shows how to do so:
Be aware of the following limitations when using asynchronous events:
* If an asynchronous event listener throws an `Exception`, it is not propagated to the
- caller. See `AsyncUncaughtExceptionHandler` for more details.
+ caller. See
+ {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]
+ for more details.
* Asynchronous event listener methods cannot publish a subsequent event by returning a
value. If you need to publish another event as the result of the processing, inject an
- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`ApplicationEventPublisher`]
+ {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]
to publish the event manually.
@@ -11021,8 +11033,8 @@ For a simple deployment of a Spring ApplicationContext as a Java EE RAR file:
. Package
all application classes into a RAR file (which is a standard JAR file with a different
file extension).
-.Add all required library JARs into the root of the RAR archive.
-.Add a
+. Add all required library JARs into the root of the RAR archive.
+. Add a
`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])
and the corresponding Spring XML bean definition file(s) (typically
`META-INF/applicationContext.xml`).
@@ -11116,7 +11128,7 @@ The following table lists features provided by the `BeanFactory` and
| No
| Yes
-| Convenient `MessageSource` access (for internalization)
+| Convenient `MessageSource` access (for internationalization)
| No
| Yes