("petStore")
+
+ // use configured instance
+ var userList = service.getUsernameList()
+----
+======
+
+With Groovy configuration, bootstrapping looks very similar. It has a different context
+implementation class which is Groovy-aware (but also understands XML bean definitions).
+The following example shows Groovy configuration:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+val context = GenericGroovyApplicationContext("services.groovy", "daos.groovy")
+----
+======
+
+The most flexible variant is `GenericApplicationContext` in combination with reader
+delegates -- for example, with `XmlBeanDefinitionReader` for XML files, as the following
+example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ GenericApplicationContext context = new GenericApplicationContext();
+ new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
+ context.refresh();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val context = GenericApplicationContext()
+ XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml")
+ context.refresh()
+----
+======
+
+You can also use the `GroovyBeanDefinitionReader` for Groovy files, as the following
+example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ GenericApplicationContext context = new GenericApplicationContext();
+ new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
+ context.refresh();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val context = GenericApplicationContext()
+ GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy")
+ context.refresh()
+----
+======
+
+You can mix and match such reader delegates on the same `ApplicationContext`,
+reading bean definitions from diverse configuration sources.
+
+You can then use `getBean` to retrieve instances of your beans. The `ApplicationContext`
+interface has a few other methods for retrieving beans, but, ideally, your application
+code should never use them. Indeed, your application code should have no calls to the
+`getBean()` method at all and thus have no dependency on Spring APIs at all. For example,
+Spring's integration with web frameworks provides dependency injection for various web
+framework components such as controllers and JSF-managed beans, letting you declare
+a dependency on a specific bean through metadata (such as an autowiring annotation).
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/beanfactory.adoc b/framework-docs/modules/ROOT/pages/core/beans/beanfactory.adoc
new file mode 100644
index 000000000000..32837957748c
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/beanfactory.adoc
@@ -0,0 +1,171 @@
+[[beans-beanfactory]]
+= The `BeanFactory` API
+
+The `BeanFactory` API provides the underlying basis for Spring's IoC functionality.
+Its specific contracts are mostly used in integration with other parts of Spring and
+related third-party frameworks, and its `DefaultListableBeanFactory` implementation
+is a key delegate within the higher-level `GenericApplicationContext` container.
+
+`BeanFactory` and related interfaces (such as `BeanFactoryAware`, `InitializingBean`,
+`DisposableBean`) are important integration points for other framework components.
+By not requiring any annotations or even reflection, they allow for very efficient
+interaction between the container and its components. Application-level beans may
+use the same callback interfaces but typically prefer declarative dependency
+injection instead, either through annotations or through programmatic configuration.
+
+Note that the core `BeanFactory` API level and its `DefaultListableBeanFactory`
+implementation do not make assumptions about the configuration format or any
+component annotations to be used. All of these flavors come in through extensions
+(such as `XmlBeanDefinitionReader` and `AutowiredAnnotationBeanPostProcessor`) and
+operate on shared `BeanDefinition` objects as a core metadata representation.
+This is the essence of what makes Spring's container so flexible and extensible.
+
+
+
+[[context-introduction-ctx-vs-beanfactory]]
+== `BeanFactory` or `ApplicationContext`?
+
+This section explains the differences between the `BeanFactory` and
+`ApplicationContext` container levels and the implications on bootstrapping.
+
+You should use an `ApplicationContext` unless you have a good reason for not doing so, with
+`GenericApplicationContext` and its subclass `AnnotationConfigApplicationContext`
+as the common implementations for custom bootstrapping. These are the primary entry
+points to Spring's core container for all common purposes: loading of configuration
+files, triggering a classpath scan, programmatically registering bean definitions
+and annotated classes, and (as of 5.0) registering functional bean definitions.
+
+Because an `ApplicationContext` includes all the functionality of a `BeanFactory`, it is
+generally recommended over a plain `BeanFactory`, except for scenarios where full
+control over bean processing is needed. Within an `ApplicationContext` (such as the
+`GenericApplicationContext` implementation), several kinds of beans are detected
+by convention (that is, by bean name or by bean type -- in particular, post-processors),
+while a plain `DefaultListableBeanFactory` is agnostic about any special beans.
+
+For many extended container features, such as annotation processing and AOP proxying,
+the xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp[`BeanPostProcessor` extension point] is essential.
+If you use only a plain `DefaultListableBeanFactory`, such post-processors do not
+get detected and activated by default. This situation could be confusing, because
+nothing is actually wrong with your bean configuration. Rather, in such a scenario,
+the container needs to be fully bootstrapped through additional setup.
+
+The following table lists features provided by the `BeanFactory` and
+`ApplicationContext` interfaces and implementations.
+
+[[context-introduction-ctx-vs-beanfactory-feature-matrix]]
+.Feature Matrix
+[cols="50%,25%,25%"]
+|===
+| Feature | `BeanFactory` | `ApplicationContext`
+
+| Bean instantiation/wiring
+| Yes
+| Yes
+
+| Integrated lifecycle management
+| No
+| Yes
+
+| Automatic `BeanPostProcessor` registration
+| No
+| Yes
+
+| Automatic `BeanFactoryPostProcessor` registration
+| No
+| Yes
+
+| Convenient `MessageSource` access (for internationalization)
+| No
+| Yes
+
+| Built-in `ApplicationEvent` publication mechanism
+| No
+| Yes
+|===
+
+To explicitly register a bean post-processor with a `DefaultListableBeanFactory`,
+you need to programmatically call `addBeanPostProcessor`, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
+ // populate the factory with bean definitions
+
+ // now register any needed BeanPostProcessor instances
+ factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
+ factory.addBeanPostProcessor(new MyBeanPostProcessor());
+
+ // now start using the factory
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val factory = DefaultListableBeanFactory()
+ // populate the factory with bean definitions
+
+ // now register any needed BeanPostProcessor instances
+ factory.addBeanPostProcessor(AutowiredAnnotationBeanPostProcessor())
+ factory.addBeanPostProcessor(MyBeanPostProcessor())
+
+ // now start using the factory
+----
+======
+
+To apply a `BeanFactoryPostProcessor` to a plain `DefaultListableBeanFactory`,
+you need to call its `postProcessBeanFactory` method, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
+ XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
+ reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
+
+ // bring in some property values from a Properties file
+ PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
+ cfg.setLocation(new FileSystemResource("jdbc.properties"));
+
+ // now actually do the replacement
+ cfg.postProcessBeanFactory(factory);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val factory = DefaultListableBeanFactory()
+ val reader = XmlBeanDefinitionReader(factory)
+ reader.loadBeanDefinitions(FileSystemResource("beans.xml"))
+
+ // bring in some property values from a Properties file
+ val cfg = PropertySourcesPlaceholderConfigurer()
+ cfg.setLocation(FileSystemResource("jdbc.properties"))
+
+ // now actually do the replacement
+ cfg.postProcessBeanFactory(factory)
+----
+======
+
+In both cases, the explicit registration steps are inconvenient, which is
+why the various `ApplicationContext` variants are preferred over a plain
+`DefaultListableBeanFactory` in Spring-backed applications, especially when
+relying on `BeanFactoryPostProcessor` and `BeanPostProcessor` instances for extended
+container functionality in a typical enterprise setup.
+
+[NOTE]
+====
+An `AnnotationConfigApplicationContext` has all common annotation post-processors
+registered and may bring in additional processors underneath the
+covers through configuration annotations, such as `@EnableTransactionManagement`.
+At the abstraction level of Spring's annotation-based configuration model,
+the notion of bean post-processors becomes a mere internal container detail.
+====
diff --git a/framework-docs/modules/ROOT/pages/core/beans/child-bean-definitions.adoc b/framework-docs/modules/ROOT/pages/core/beans/child-bean-definitions.adoc
new file mode 100644
index 000000000000..2c4d287a08f4
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/child-bean-definitions.adoc
@@ -0,0 +1,84 @@
+[[beans-child-bean-definitions]]
+= Bean Definition Inheritance
+
+A bean definition can contain a lot of configuration information, including constructor
+arguments, property values, and container-specific information, such as the initialization
+method, a static factory method name, and so on. A child bean definition inherits
+configuration data from a parent definition. The child definition can override some
+values or add others as needed. Using parent and child bean definitions can save a lot
+of typing. Effectively, this is a form of templating.
+
+If you work with an `ApplicationContext` interface programmatically, child bean
+definitions are represented by the `ChildBeanDefinition` class. Most users do not work
+with them on this level. Instead, they configure bean definitions declaratively in a class
+such as the `ClassPathXmlApplicationContext`. When you use XML-based configuration
+metadata, you can indicate a child bean definition by using the `parent` attribute,
+specifying the parent bean as the value of this attribute. The following example shows how
+to do so:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+ <1>
+
+
+
+----
+<1> Note the `parent` attribute.
+
+A child bean definition uses the bean class from the parent definition if none is
+specified but can also override it. In the latter case, the child bean class must be
+compatible with the parent (that is, it must accept the parent's property values).
+
+A child bean definition inherits scope, constructor argument values, property values, and
+method overrides from the parent, with the option to add new values. Any scope, initialization
+method, destroy method, or `static` factory method settings that you specify
+override the corresponding parent settings.
+
+The remaining settings are always taken from the child definition: depends on,
+autowire mode, dependency check, singleton, and lazy init.
+
+The preceding example explicitly marks the parent bean definition as abstract by using
+the `abstract` attribute. If the parent definition does not specify a class, explicitly
+marking the parent bean definition as `abstract` is required, as the following example
+shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+----
+
+The parent bean cannot be instantiated on its own because it is incomplete, and it is
+also explicitly marked as `abstract`. When a definition is `abstract`, it is
+usable only as a pure template bean definition that serves as a parent definition for
+child definitions. Trying to use such an `abstract` parent bean on its own, by referring
+to it as a ref property of another bean or doing an explicit `getBean()` call with the
+parent bean ID returns an error. Similarly, the container's internal
+`preInstantiateSingletons()` method ignores bean definitions that are defined as
+abstract.
+
+NOTE: `ApplicationContext` pre-instantiates all singletons by default. Therefore, it is
+important (at least for singleton beans) that if you have a (parent) bean definition
+which you intend to use only as a template, and this definition specifies a class, you
+must make sure to set the __abstract__ attribute to __true__, otherwise the application
+context will actually (attempt to) pre-instantiate the `abstract` bean.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc
new file mode 100644
index 000000000000..e3f792392237
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc
@@ -0,0 +1,1055 @@
+[[beans-classpath-scanning]]
+= Classpath Scanning and Managed Components
+
+Most examples in this chapter use XML to specify the configuration metadata that produces
+each `BeanDefinition` within the Spring container. The previous section
+(xref:core/beans/annotation-config.adoc[Annotation-based Container Configuration]) demonstrates how to provide a lot of the configuration
+metadata through source-level annotations. Even in those examples, however, the "base"
+bean definitions are explicitly defined in the XML file, while the annotations drive only
+the dependency injection. This section describes an option for implicitly detecting the
+candidate components by scanning the classpath. Candidate components are classes that
+match against a filter criteria and have a corresponding bean definition registered with
+the container. This removes the need to use XML to perform bean registration. Instead, you
+can use annotations (for example, `@Component`), AspectJ type expressions, or your own
+custom filter criteria to select which classes have bean definitions registered with
+the container.
+
+[NOTE]
+====
+You can define beans using Java rather than using XML files. Take a look at the
+`@Configuration`, `@Bean`, `@Import`, and `@DependsOn` annotations for examples of how to
+use these features.
+====
+
+
+
+[[beans-stereotype-annotations]]
+== `@Component` and Further Stereotype Annotations
+
+The `@Repository` annotation is a marker for any class that fulfills the role or
+stereotype of a repository (also known as Data Access Object or DAO). Among the uses
+of this marker is the automatic translation of exceptions, as described in
+xref:data-access/orm/general.adoc#orm-exception-translation[Exception Translation].
+
+Spring provides further stereotype annotations: `@Component`, `@Service`, and
+`@Controller`. `@Component` is a generic stereotype for any Spring-managed component.
+`@Repository`, `@Service`, and `@Controller` are specializations of `@Component` for
+more specific use cases (in the persistence, service, and presentation
+layers, respectively). Therefore, you can annotate your component classes with
+`@Component`, but, by annotating them with `@Repository`, `@Service`, or `@Controller`
+instead, your classes are more properly suited for processing by tools or associating
+with aspects. For example, these stereotype annotations make ideal targets for
+pointcuts. `@Repository`, `@Service`, and `@Controller` can also
+carry additional semantics in future releases of the Spring Framework. Thus, if you are
+choosing between using `@Component` or `@Service` for your service layer, `@Service` is
+clearly the better choice. Similarly, as stated earlier, `@Repository` is already
+supported as a marker for automatic exception translation in your persistence layer.
+
+
+
+[[beans-meta-annotations]]
+== Using Meta-annotations and Composed Annotations
+
+Many of the annotations provided by Spring can be used as meta-annotations in your
+own code. A meta-annotation is an annotation that can be applied to another annotation.
+For example, the `@Service` annotation mentioned xref:core/beans/classpath-scanning.adoc#beans-stereotype-annotations[earlier]
+is meta-annotated with `@Component`, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Target(ElementType.TYPE)
+ @Retention(RetentionPolicy.RUNTIME)
+ @Documented
+ @Component // <1>
+ public @interface Service {
+
+ // ...
+ }
+----
+======
+<1> The `@Component` causes `@Service` to be treated in the same way as `@Component`.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ @Target(AnnotationTarget.TYPE)
+ @Retention(AnnotationRetention.RUNTIME)
+ @MustBeDocumented
+ @Component // <1>
+ annotation class Service {
+
+ // ...
+ }
+----
+<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
+`@ResponseBody`.
+
+In addition, composed annotations can optionally redeclare attributes from
+meta-annotations to allow customization. This can be particularly useful when you
+want to only expose a subset of the meta-annotation's attributes. For example, Spring's
+`@SessionScope` annotation hard codes the scope name to `session` but still allows
+customization of the `proxyMode`. The following listing shows the definition of the
+`SessionScope` annotation:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Target({ElementType.TYPE, ElementType.METHOD})
+ @Retention(RetentionPolicy.RUNTIME)
+ @Documented
+ @Scope(WebApplicationContext.SCOPE_SESSION)
+ public @interface SessionScope {
+
+ /**
+ * Alias for {@link Scope#proxyMode}.
+ * Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
+ */
+ @AliasFor(annotation = Scope.class)
+ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
+
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Target(AnnotationTarget.TYPE, AnnotationTarget.FUNCTION)
+ @Retention(AnnotationRetention.RUNTIME)
+ @MustBeDocumented
+ @Scope(WebApplicationContext.SCOPE_SESSION)
+ annotation class SessionScope(
+ @get:AliasFor(annotation = Scope::class)
+ val proxyMode: ScopedProxyMode = ScopedProxyMode.TARGET_CLASS
+ )
+----
+======
+
+You can then use `@SessionScope` without declaring the `proxyMode` as follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Service
+ @SessionScope
+ public class SessionScopedService {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Service
+ @SessionScope
+ class SessionScopedService {
+ // ...
+ }
+----
+======
+
+You can also override the value for the `proxyMode`, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Service
+ @SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
+ public class SessionScopedUserService implements UserService {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Service
+ @SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
+ class SessionScopedUserService : UserService {
+ // ...
+ }
+----
+======
+
+For further details, see the
+https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]
+wiki page.
+
+
+
+[[beans-scanning-autodetection]]
+== Automatically Detecting Classes and Registering Bean Definitions
+
+Spring can automatically detect stereotyped classes and register corresponding
+`BeanDefinition` instances with the `ApplicationContext`. For example, the following two classes
+are eligible for such autodetection:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Service
+ public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ public SimpleMovieLister(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Service
+ class SimpleMovieLister(private val movieFinder: MovieFinder)
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Repository
+ public class JpaMovieFinder implements MovieFinder {
+ // implementation elided for clarity
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Repository
+ class JpaMovieFinder : MovieFinder {
+ // implementation elided for clarity
+ }
+----
+======
+
+
+To autodetect these classes and register the corresponding beans, you need to add
+`@ComponentScan` to your `@Configuration` class, where the `basePackages` attribute
+is a common parent package for the two classes. (Alternatively, you can specify a
+comma- or semicolon- or space-separated list that includes the parent package of each class.)
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "org.example")
+ public class AppConfig {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = ["org.example"])
+ class AppConfig {
+ // ...
+ }
+----
+======
+
+NOTE: For brevity, the preceding example could have used the `value` attribute of the
+annotation (that is, `@ComponentScan("org.example")`).
+
+The following alternative uses XML:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+----
+
+TIP: The use of `` implicitly enables the functionality of
+``. There is usually no need to include the
+`` element when using ``.
+
+[NOTE]
+====
+The scanning of classpath packages requires the presence of corresponding directory
+entries in the classpath. When you build JARs with Ant, make sure that you do not
+activate the files-only switch of the JAR task. Also, classpath directories may not be
+exposed based on security policies in some environments -- for example, standalone apps on
+JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see
+https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).
+
+On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.
+However, make sure that your component classes are exported in your `module-info`
+descriptors. If you expect Spring to invoke non-public members of your classes, make
+sure that they are 'opened' (that is, that they use an `opens` declaration instead of an
+`exports` declaration in your `module-info` descriptor).
+====
+
+Furthermore, the `AutowiredAnnotationBeanPostProcessor` and
+`CommonAnnotationBeanPostProcessor` are both implicitly included when you use the
+component-scan element. That means that the two components are autodetected and
+wired together -- all without any bean configuration metadata provided in XML.
+
+NOTE: You can disable the registration of `AutowiredAnnotationBeanPostProcessor` and
+`CommonAnnotationBeanPostProcessor` by including the `annotation-config` attribute
+with a value of `false`.
+
+
+
+[[beans-scanning-filters]]
+== Using Filters to Customize Scanning
+
+By default, classes annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,
+`@Configuration`, or a custom annotation that itself is annotated with `@Component` are
+the only detected candidate components. However, you can modify and extend this behavior
+by applying custom filters. Add them as `includeFilters` or `excludeFilters` attributes of
+the `@ComponentScan` annotation (or as `` or
+`` child elements of the `` element in
+XML configuration). Each filter element requires the `type` and `expression` attributes.
+The following table describes the filtering options:
+
+[[beans-scanning-filters-tbl]]
+.Filter Types
+|===
+| Filter Type| Example Expression| Description
+
+| annotation (default)
+| `org.example.SomeAnnotation`
+| An annotation to be _present_ or _meta-present_ at the type level in target components.
+
+| assignable
+| `org.example.SomeClass`
+| A class (or interface) that the target components are assignable to (extend or implement).
+
+| aspectj
+| `org.example..*Service+`
+| An AspectJ type expression to be matched by the target components.
+
+| regex
+| `org\.example\.Default.*`
+| A regex expression to be matched by the target components' class names.
+
+| custom
+| `org.example.MyTypeFilter`
+| A custom implementation of the `org.springframework.core.type.TypeFilter` interface.
+|===
+
+The following example shows the configuration ignoring all `@Repository` annotations
+and using "`stub`" repositories instead:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "org.example",
+ includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
+ excludeFilters = @Filter(Repository.class))
+ public class AppConfig {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = ["org.example"],
+ includeFilters = [Filter(type = FilterType.REGEX, pattern = [".*Stub.*Repository"])],
+ excludeFilters = [Filter(Repository::class)])
+ class AppConfig {
+ // ...
+ }
+----
+======
+
+The following listing shows the equivalent XML:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+----
+
+NOTE: You can also disable the default filters by setting `useDefaultFilters=false` on the
+annotation or by providing `use-default-filters="false"` as an attribute of the
+`` element. This effectively disables automatic detection of classes
+annotated or meta-annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,
+`@RestController`, or `@Configuration`.
+
+
+
+[[beans-factorybeans-annotations]]
+== Defining Bean Metadata within Components
+
+Spring components can also contribute bean definition metadata to the container. You can do
+this with the same `@Bean` annotation used to define bean metadata within `@Configuration`
+annotated classes. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Component
+ public class FactoryMethodComponent {
+
+ @Bean
+ @Qualifier("public")
+ public TestBean publicInstance() {
+ return new TestBean("publicInstance");
+ }
+
+ public void doWork() {
+ // Component method implementation omitted
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Component
+ class FactoryMethodComponent {
+
+ @Bean
+ @Qualifier("public")
+ fun publicInstance() = TestBean("publicInstance")
+
+ fun doWork() {
+ // Component method implementation omitted
+ }
+ }
+----
+======
+
+The preceding class is a Spring component that has application-specific code in its
+`doWork()` method. However, it also contributes a bean definition that has a factory
+method referring to the method `publicInstance()`. The `@Bean` annotation identifies the
+factory method and other bean definition properties, such as a qualifier value through
+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. 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:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Component
+ public class FactoryMethodComponent {
+
+ private static int i;
+
+ @Bean
+ @Qualifier("public")
+ public TestBean publicInstance() {
+ return new TestBean("publicInstance");
+ }
+
+ // use of a custom qualifier and autowiring of method parameters
+ @Bean
+ protected TestBean protectedInstance(
+ @Qualifier("public") TestBean spouse,
+ @Value("#{privateInstance.age}") String country) {
+ TestBean tb = new TestBean("protectedInstance", 1);
+ tb.setSpouse(spouse);
+ tb.setCountry(country);
+ return tb;
+ }
+
+ @Bean
+ private TestBean privateInstance() {
+ return new TestBean("privateInstance", i++);
+ }
+
+ @Bean
+ @RequestScope
+ public TestBean requestScopedInstance() {
+ return new TestBean("requestScopedInstance", 3);
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Component
+ class FactoryMethodComponent {
+
+ companion object {
+ private var i: Int = 0
+ }
+
+ @Bean
+ @Qualifier("public")
+ fun publicInstance() = TestBean("publicInstance")
+
+ // use of a custom qualifier and autowiring of method parameters
+ @Bean
+ protected fun protectedInstance(
+ @Qualifier("public") spouse: TestBean,
+ @Value("#{privateInstance.age}") country: String) = TestBean("protectedInstance", 1).apply {
+ this.spouse = spouse
+ this.country = country
+ }
+
+ @Bean
+ private fun privateInstance() = TestBean("privateInstance", i++)
+
+ @Bean
+ @RequestScope
+ fun requestScopedInstance() = TestBean("requestScopedInstance", 3)
+ }
+----
+======
+
+The example autowires the `String` method parameter `country` to the value of the `age`
+property on another bean named `privateInstance`. A Spring Expression Language element
+defines the value of the property through the notation `#{ }`. For `@Value`
+annotations, an expression resolver is preconfigured to look for bean names when
+resolving expression text.
+
+As of Spring Framework 4.3, you may also declare a factory method parameter of type
+`InjectionPoint` (or its more specific subclass: `DependencyDescriptor`) to
+access the requesting injection point that triggers the creation of the current bean.
+Note that this applies only to the actual creation of bean instances, not to the
+injection of existing instances. As a consequence, this feature makes most sense for
+beans of prototype scope. For other scopes, the factory method only ever sees the
+injection point that triggered the creation of a new bean instance in the given scope
+(for example, the dependency that triggered the creation of a lazy singleton bean).
+You can use the provided injection point metadata with semantic care in such scenarios.
+The following example shows how to use `InjectionPoint`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Component
+ public class FactoryMethodComponent {
+
+ @Bean @Scope("prototype")
+ public TestBean prototypeInstance(InjectionPoint injectionPoint) {
+ return new TestBean("prototypeInstance for " + injectionPoint.getMember());
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Component
+ class FactoryMethodComponent {
+
+ @Bean
+ @Scope("prototype")
+ fun prototypeInstance(injectionPoint: InjectionPoint) =
+ TestBean("prototypeInstance for ${injectionPoint.member}")
+ }
+----
+======
+
+The `@Bean` methods in a regular Spring component are processed differently than their
+counterparts inside a Spring `@Configuration` class. The difference is that `@Component`
+classes are not enhanced with CGLIB to intercept the invocation of methods and fields.
+CGLIB proxying is the means by which invoking methods or fields within `@Bean` methods
+in `@Configuration` classes creates bean metadata references to collaborating objects.
+Such methods are not invoked with normal Java semantics but rather go through the
+container in order to provide the usual lifecycle management and proxying of Spring
+beans, even when referring to other beans through programmatic calls to `@Bean` methods.
+In contrast, invoking a method or field in a `@Bean` method within a plain `@Component`
+class has standard Java semantics, with no special CGLIB processing or other
+constraints applying.
+
+[NOTE]
+====
+You may declare `@Bean` methods as `static`, allowing for them to be called without
+creating their containing configuration class as an instance. This makes particular
+sense when defining post-processor beans (for example, of type `BeanFactoryPostProcessor`
+or `BeanPostProcessor`), since such beans get initialized early in the container
+lifecycle and should avoid triggering other parts of the configuration at that point.
+
+Calls to static `@Bean` methods never get intercepted by the container, not even within
+`@Configuration` classes (as described earlier in this section), due to technical
+limitations: CGLIB subclassing can override only non-static methods. As a consequence,
+a direct call to another `@Bean` method has standard Java semantics, resulting
+in an independent instance being returned straight from the factory method itself.
+
+The Java language visibility of `@Bean` methods does not have an immediate impact on
+the resulting bean definition in Spring's container. You can freely declare your
+factory methods as you see fit in non-`@Configuration` classes and also for static
+methods anywhere. However, regular `@Bean` methods in `@Configuration` classes need
+to be overridable -- that is, they must not be declared as `private` or `final`.
+
+`@Bean` methods are also discovered on base classes of a given component or
+configuration class, as well as on Java 8 default methods declared in interfaces
+implemented by the component or configuration class. This allows for a lot of
+flexibility in composing complex configuration arrangements, with even multiple
+inheritance being possible through Java 8 default methods as of Spring 4.2.
+
+Finally, a single class may hold multiple `@Bean` methods for the same
+bean, as an arrangement of multiple factory methods to use depending on available
+dependencies at runtime. This is the same algorithm as for choosing the "`greediest`"
+constructor or factory method in other configuration scenarios: The variant with
+the largest number of satisfiable dependencies is picked at construction time,
+analogous to how the container selects between multiple `@Autowired` constructors.
+====
+
+
+
+[[beans-scanning-name-generator]]
+== Naming Autodetected Components
+
+When a component is autodetected as part of the scanning process, its bean name is
+generated by the `BeanNameGenerator` strategy known to that scanner. By default, any
+Spring stereotype annotation (`@Component`, `@Repository`, `@Service`, and
+`@Controller`) that contains a name `value` thereby provides that name to the
+corresponding bean definition.
+
+If such an annotation contains no name `value` or for any other detected component
+(such as those discovered by custom filters), the default bean name generator returns
+the uncapitalized non-qualified class name. For example, if the following component
+classes were detected, the names would be `myMovieLister` and `movieFinderImpl`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Service("myMovieLister")
+ public class SimpleMovieLister {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Service("myMovieLister")
+ class SimpleMovieLister {
+ // ...
+ }
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Repository
+ public class MovieFinderImpl implements MovieFinder {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Repository
+ class MovieFinderImpl : MovieFinder {
+ // ...
+ }
+----
+======
+
+If you do not want to rely on the default bean-naming strategy, you can provide a custom
+bean-naming strategy. First, implement the
+{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]
+interface, and be sure to include a default no-arg constructor. Then, provide the fully
+qualified class name when configuring the scanner, as the following example annotation
+and bean definition show.
+
+TIP: If you run into naming conflicts due to multiple autodetected components having the
+same non-qualified class name (i.e., classes with identical names but residing in
+different packages), you may need to configure a `BeanNameGenerator` that defaults to the
+fully qualified class name for the generated bean name. As of Spring Framework 5.2.3, the
+`FullyQualifiedAnnotationBeanNameGenerator` located in package
+`org.springframework.context.annotation` can be used for such purposes.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
+ public class AppConfig {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = ["org.example"], nameGenerator = MyNameGenerator::class)
+ class AppConfig {
+ // ...
+ }
+----
+======
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+As a general rule, consider specifying the name with the annotation whenever other
+components may be making explicit references to it. On the other hand, the
+auto-generated names are adequate whenever the container is responsible for wiring.
+
+
+
+[[beans-scanning-scope-resolver]]
+== Providing a Scope for Autodetected Components
+
+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
+that can be specified by the `@Scope` annotation. You can provide the name of the
+scope within the annotation, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Scope("prototype")
+ @Repository
+ public class MovieFinderImpl implements MovieFinder {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Scope("prototype")
+ @Repository
+ class MovieFinderImpl : MovieFinder {
+ // ...
+ }
+----
+======
+
+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`" or "`session`" in a Spring context,
+see xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other[Request, Session, Application, and WebSocket Scopes]. As with the pre-built annotations for those scopes,
+you may also compose your own scoping annotations by using Spring's meta-annotation
+approach: for example, a custom annotation meta-annotated with `@Scope("prototype")`,
+possibly also declaring a custom scoped-proxy mode.
+
+NOTE: To provide a custom strategy for scope resolution rather than relying on the
+annotation-based approach, you can implement the
+{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]
+interface. Be sure to include a default no-arg constructor. Then you can provide the
+fully qualified class name when configuring the scanner, as the following example of both
+an annotation and a bean definition shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
+ public class AppConfig {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = ["org.example"], scopeResolver = MyScopeResolver::class)
+ class AppConfig {
+ // ...
+ }
+----
+======
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+When using certain non-singleton scopes, it may be necessary to generate proxies for the
+scoped objects. The reasoning is described in xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection[Scoped Beans as Dependencies].
+For this purpose, a scoped-proxy attribute is available on the component-scan
+element. The three possible values are: `no`, `interfaces`, and `targetClass`. For example,
+the following configuration results in standard JDK dynamic proxies:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
+ public class AppConfig {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = ["org.example"], scopedProxy = ScopedProxyMode.INTERFACES)
+ class AppConfig {
+ // ...
+ }
+----
+======
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+
+
+[[beans-scanning-qualifiers]]
+== Providing Qualifier Metadata with Annotations
+
+The `@Qualifier` annotation is discussed in xref:core/beans/annotation-config/autowired-qualifiers.adoc[Fine-tuning Annotation-based Autowiring with Qualifiers].
+The examples in that section demonstrate the use of the `@Qualifier` annotation and
+custom qualifier annotations to provide fine-grained control when you resolve autowire
+candidates. Because those examples were based on XML bean definitions, the qualifier
+metadata was provided on the candidate bean definitions by using the `qualifier` or `meta`
+child elements of the `bean` element in the XML. When relying upon classpath scanning for
+auto-detection of components, you can provide the qualifier metadata with type-level
+annotations on the candidate class. The following three examples demonstrate this
+technique:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Component
+ @Qualifier("Action")
+ public class ActionMovieCatalog implements MovieCatalog {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Component
+ @Qualifier("Action")
+ class ActionMovieCatalog : MovieCatalog
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Component
+ @Genre("Action")
+ public class ActionMovieCatalog implements MovieCatalog {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Component
+ @Genre("Action")
+ class ActionMovieCatalog : MovieCatalog {
+ // ...
+ }
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Component
+ @Offline
+ public class CachingMovieCatalog implements MovieCatalog {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+@Component
+@Offline
+class CachingMovieCatalog : MovieCatalog {
+ // ...
+}
+----
+======
+
+NOTE: As with most annotation-based alternatives, keep in mind that the annotation metadata is
+bound to the class definition itself, while the use of XML allows for multiple beans
+of the same type to provide variations in their qualifier metadata, because that
+metadata is provided per-instance rather than per-class.
+
+
+
+[[beans-scanning-index]]
+== Generating an Index of Candidate Components
+
+While classpath scanning is very fast, it is possible to improve the startup performance
+of large applications by creating a static list of candidates at compilation time. In this
+mode, all modules that are targets of component scanning must use this mechanism.
+
+NOTE: Your existing `@ComponentScan` or `` directives must remain
+unchanged to request the context to scan candidates in certain packages. When the
+`ApplicationContext` detects such an index, it automatically uses it rather than scanning
+the classpath.
+
+To generate the index, add an additional dependency to each module that contains
+components that are targets for component scan directives. The following example shows
+how to do so with Maven:
+
+[source,xml,indent=0,subs="verbatim,quotes,attributes"]
+----
+
+
+ org.springframework
+ spring-context-indexer
+ {spring-version}
+ true
+
+
+----
+
+With Gradle 4.5 and earlier, the dependency should be declared in the `compileOnly`
+configuration, as shown in the following example:
+
+[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
+----
+ dependencies {
+ compileOnly "org.springframework:spring-context-indexer:{spring-version}"
+ }
+----
+
+With Gradle 4.6 and later, the dependency should be declared in the `annotationProcessor`
+configuration, as shown in the following example:
+
+[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
+----
+ dependencies {
+ annotationProcessor "org.springframework:spring-context-indexer:{spring-version}"
+ }
+----
+
+The `spring-context-indexer` artifact generates a `META-INF/spring.components` file that
+is included in the jar file.
+
+NOTE: When working with this mode in your IDE, the `spring-context-indexer` must be
+registered as an annotation processor to make sure the index is up-to-date when
+candidate components are updated.
+
+TIP: The index is enabled automatically when a `META-INF/spring.components` file is found
+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 via the
+xref:appendix.adoc#appendix-spring-properties[`SpringProperties`] mechanism.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc
new file mode 100644
index 000000000000..c77bc8a92358
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc
@@ -0,0 +1,1041 @@
+[[context-introduction]]
+= Additional Capabilities of the `ApplicationContext`
+
+As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`
+package provides basic functionality for managing and manipulating beans, including in a
+programmatic way. The `org.springframework.context` package adds the
+{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]
+interface, which extends the `BeanFactory` interface, in addition to extending other
+interfaces to provide additional functionality in a more application
+framework-oriented style. Many people use the `ApplicationContext` in a completely
+declarative fashion, not even creating it programmatically, but instead relying on
+support classes such as `ContextLoader` to automatically instantiate an
+`ApplicationContext` as part of the normal startup process of a Jakarta EE web application.
+
+To enhance `BeanFactory` functionality in a more framework-oriented style, the context
+package also provides the following functionality:
+
+* Access to messages in i18n-style, through the `MessageSource` interface.
+* Access to resources, such as URLs and files, through the `ResourceLoader` interface.
+* Event publication, namely to beans that implement the `ApplicationListener` interface,
+ through the use of the `ApplicationEventPublisher` interface.
+* Loading of multiple (hierarchical) contexts, letting each be focused on one
+ particular layer, such as the web layer of an application, through the
+ `HierarchicalBeanFactory` interface.
+
+
+
+[[context-functionality-messagesource]]
+== Internationalization using `MessageSource`
+
+The `ApplicationContext` interface extends an interface called `MessageSource` and,
+therefore, provides internationalization ("`i18n`") functionality. Spring also provides the
+`HierarchicalMessageSource` interface, which can resolve messages hierarchically.
+Together, these interfaces provide the foundation upon which Spring effects message
+resolution. The methods defined on these interfaces include:
+
+* `String getMessage(String code, Object[] args, String default, Locale loc)`: The basic
+ method used to retrieve a message from the `MessageSource`. When no message is found
+ for the specified locale, the default message is used. Any arguments passed in become
+ replacement values, using the `MessageFormat` functionality provided by the standard
+ library.
+* `String getMessage(String code, Object[] args, Locale loc)`: Essentially the same as
+ the previous method but with one difference: No default message can be specified. If
+ the message cannot be found, a `NoSuchMessageException` is thrown.
+* `String getMessage(MessageSourceResolvable resolvable, Locale locale)`: All properties
+ used in the preceding methods are also wrapped in a class named
+ `MessageSourceResolvable`, which you can use with this method.
+
+When an `ApplicationContext` is loaded, it automatically searches for a `MessageSource`
+bean defined in the context. The bean must have the name `messageSource`. If such a bean
+is found, all calls to the preceding methods are delegated to the message source. If no
+message source is found, the `ApplicationContext` attempts to find a parent containing a
+bean with the same name. If it does, it uses that bean as the `MessageSource`. If the
+`ApplicationContext` cannot find any source for messages, an empty
+`DelegatingMessageSource` is instantiated in order to be able to accept calls to the
+methods defined above.
+
+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`:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+ format
+ exceptions
+ windows
+
+
+
+
+----
+
+The example assumes that you have three resource bundles called `format`, `exceptions` and `windows`
+defined in your classpath. Any request to resolve a message is
+handled in the JDK-standard way of resolving messages through `ResourceBundle` objects. For the
+purposes of the example, assume the contents of two of the above resource bundle files
+are as follows:
+
+[source,properties,indent=0,subs="verbatim,quotes"]
+----
+ # in format.properties
+ message=Alligators rock!
+----
+
+[source,properties,indent=0,subs="verbatim,quotes"]
+----
+ # in exceptions.properties
+ argument.required=The {0} argument is required.
+----
+
+The next example shows a program to run the `MessageSource` functionality.
+Remember that all `ApplicationContext` implementations are also `MessageSource`
+implementations and so can be cast to the `MessageSource` interface.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
+ String message = resources.getMessage("message", null, "Default", Locale.ENGLISH);
+ System.out.println(message);
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun main() {
+ val resources = ClassPathXmlApplicationContext("beans.xml")
+ val message = resources.getMessage("message", null, "Default", Locale.ENGLISH)
+ println(message)
+ }
+----
+======
+
+The resulting output from the above program is as follows:
+
+[literal,subs="verbatim,quotes"]
+----
+Alligators rock!
+----
+
+To summarize, the `MessageSource` is defined in a file called `beans.xml`, which
+exists at the root of your classpath. The `messageSource` bean definition refers to a
+number of resource bundles through its `basenames` property. The three files that are
+passed in the list to the `basenames` property exist as files at the root of your
+classpath and are called `format.properties`, `exceptions.properties`, and
+`windows.properties`, respectively.
+
+The next example shows arguments passed to the message lookup. These arguments are
+converted into `String` objects and inserted into placeholders in the lookup message.
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class Example {
+
+ private MessageSource messages;
+
+ public void setMessages(MessageSource messages) {
+ this.messages = messages;
+ }
+
+ public void execute() {
+ String message = this.messages.getMessage("argument.required",
+ new Object [] {"userDao"}, "Required", Locale.ENGLISH);
+ System.out.println(message);
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class Example {
+
+ lateinit var messages: MessageSource
+
+ fun execute() {
+ val message = messages.getMessage("argument.required",
+ arrayOf("userDao"), "Required", Locale.ENGLISH)
+ println(message)
+ }
+}
+----
+======
+
+The resulting output from the invocation of the `execute()` method is as follows:
+
+[literal,subs="verbatim,quotes"]
+----
+The userDao argument is required.
+----
+
+With regard to internationalization ("`i18n`"), Spring's various `MessageSource`
+implementations follow the same locale resolution and fallback rules as the standard JDK
+`ResourceBundle`. In short, and continuing with the example `messageSource` defined
+previously, if you want to resolve messages against the British (`en-GB`) locale, you
+would create files called `format_en_GB.properties`, `exceptions_en_GB.properties`, and
+`windows_en_GB.properties`, respectively.
+
+Typically, locale resolution is managed by the surrounding environment of the
+application. In the following example, the locale against which (British) messages are
+resolved is specified manually:
+
+[literal,subs="verbatim,quotes"]
+----
+# in exceptions_en_GB.properties
+argument.required=Ebagum lad, the ''{0}'' argument is required, I say, required.
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(final String[] args) {
+ MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
+ String message = resources.getMessage("argument.required",
+ new Object [] {"userDao"}, "Required", Locale.UK);
+ System.out.println(message);
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun main() {
+ val resources = ClassPathXmlApplicationContext("beans.xml")
+ val message = resources.getMessage("argument.required",
+ arrayOf("userDao"), "Required", Locale.UK)
+ println(message)
+ }
+----
+======
+
+The resulting output from the running of the above program is as follows:
+
+[literal,subs="verbatim,quotes"]
+----
+Ebagum lad, the 'userDao' argument is required, I say, required.
+----
+
+You can also use the `MessageSourceAware` interface to acquire a reference to any
+`MessageSource` that has been defined. Any bean that is defined in 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
+`ResourceBundleMessageSource` implementation. In particular, it allows for reading
+files from any Spring resource location (not only from the classpath) and supports hot
+reloading of bundle property files (while efficiently caching them in between).
+See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]
+javadoc for details.
+
+
+
+[[context-functionality-events]]
+== Standard and Custom Events
+
+Event handling in the `ApplicationContext` is provided through the `ApplicationEvent`
+class and the `ApplicationListener` interface. If a bean that implements the
+`ApplicationListener` interface is deployed into the context, every time an
+`ApplicationEvent` gets published to the `ApplicationContext`, that bean is notified.
+Essentially, this is the standard Observer design pattern.
+
+TIP: As of Spring 4.2, the event infrastructure has been significantly improved and offers
+an xref:core/beans/context-introduction.adoc#context-functionality-events-annotation[annotation-based model] as well as the
+ability to publish any arbitrary event (that is, an object that does not necessarily
+extend from `ApplicationEvent`). When such an object is published, we wrap it in an
+event for you.
+
+The following table describes the standard events that Spring provides:
+
+[[beans-ctx-events-tbl]]
+.Built-in Events
+[cols="30%,70%"]
+|===
+| Event| Explanation
+
+| `ContextRefreshedEvent`
+| Published when the `ApplicationContext` is initialized or refreshed (for example, by
+ using the `refresh()` method on the `ConfigurableApplicationContext` interface).
+ Here, "`initialized`" means that all beans are loaded, post-processor beans are detected
+ and activated, singletons are pre-instantiated, and the `ApplicationContext` object is
+ ready for use. As long as the context has not been closed, a refresh can be triggered
+ multiple times, provided that the chosen `ApplicationContext` actually supports such
+ "`hot`" refreshes. For example, `XmlWebApplicationContext` supports hot refreshes, but
+ `GenericApplicationContext` does not.
+
+| `ContextStartedEvent`
+| Published when the `ApplicationContext` is started by using the `start()` method on the
+ `ConfigurableApplicationContext` interface. Here, "`started`" means that all `Lifecycle`
+ beans receive an explicit start signal. Typically, this signal is used to restart beans
+ after an explicit stop, but it may also be used to start components that have not been
+ configured for autostart (for example, components that have not already started on
+ initialization).
+
+| `ContextStoppedEvent`
+| Published when the `ApplicationContext` is stopped by using the `stop()` method on the
+ `ConfigurableApplicationContext` interface. Here, "`stopped`" means that all `Lifecycle`
+ beans receive an explicit stop signal. A stopped context may be restarted through a
+ `start()` call.
+
+| `ContextClosedEvent`
+| Published when the `ApplicationContext` is being closed by using the `close()` method
+ on the `ConfigurableApplicationContext` interface or via a JVM shutdown hook. Here,
+ "closed" means that all singleton beans will be destroyed. Once the context is closed,
+ it reaches its end of life and cannot be refreshed or restarted.
+
+| `RequestHandledEvent`
+| A web-specific event telling all beans that an HTTP request has been serviced. This
+ event is published after the request is complete. This event is only applicable to
+ web applications that use Spring's `DispatcherServlet`.
+
+| `ServletRequestHandledEvent`
+| A subclass of `RequestHandledEvent` that adds Servlet-specific context information.
+
+|===
+
+You can also create and publish your own custom events. The following example shows a
+simple class that extends Spring's `ApplicationEvent` base class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class BlockedListEvent extends ApplicationEvent {
+
+ private final String address;
+ private final String content;
+
+ public BlockedListEvent(Object source, String address, String content) {
+ super(source);
+ this.address = address;
+ this.content = content;
+ }
+
+ // accessor and other methods...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class BlockedListEvent(source: Any,
+ val address: String,
+ val content: String) : ApplicationEvent(source)
+----
+======
+
+To publish a custom `ApplicationEvent`, call the `publishEvent()` method on an
+`ApplicationEventPublisher`. Typically, this is done by creating a class that implements
+`ApplicationEventPublisherAware` and registering it as a Spring bean. The following
+example shows such a class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class EmailService implements ApplicationEventPublisherAware {
+
+ private List blockedList;
+ private ApplicationEventPublisher publisher;
+
+ public void setBlockedList(List blockedList) {
+ this.blockedList = blockedList;
+ }
+
+ public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
+ this.publisher = publisher;
+ }
+
+ public void sendEmail(String address, String content) {
+ if (blockedList.contains(address)) {
+ publisher.publishEvent(new BlockedListEvent(this, address, content));
+ return;
+ }
+ // send email...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class EmailService : ApplicationEventPublisherAware {
+
+ private lateinit var blockedList: List
+ private lateinit var publisher: ApplicationEventPublisher
+
+ fun setBlockedList(blockedList: List) {
+ this.blockedList = blockedList
+ }
+
+ override fun setApplicationEventPublisher(publisher: ApplicationEventPublisher) {
+ this.publisher = publisher
+ }
+
+ fun sendEmail(address: String, content: String) {
+ if (blockedList!!.contains(address)) {
+ publisher!!.publishEvent(BlockedListEvent(this, address, content))
+ return
+ }
+ // send email...
+ }
+ }
+----
+======
+
+At configuration time, the Spring container detects that `EmailService` implements
+`ApplicationEventPublisherAware` and automatically calls
+`setApplicationEventPublisher()`. In reality, the parameter passed in is the Spring
+container itself. You are interacting with the application context through its
+`ApplicationEventPublisher` interface.
+
+To receive the custom `ApplicationEvent`, you can create a class that implements
+`ApplicationListener` and register it as a Spring bean. The following example
+shows such a class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class BlockedListNotifier implements ApplicationListener {
+
+ private String notificationAddress;
+
+ public void setNotificationAddress(String notificationAddress) {
+ this.notificationAddress = notificationAddress;
+ }
+
+ public void onApplicationEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class BlockedListNotifier : ApplicationListener {
+
+ lateinit var notificationAddress: String
+
+ override fun onApplicationEvent(event: BlockedListEvent) {
+ // notify appropriate parties via notificationAddress...
+ }
+ }
+----
+======
+
+Notice that `ApplicationListener` is generically parameterized with the type of your
+custom event (`BlockedListEvent` in the preceding example). This means that the
+`onApplicationEvent()` method can remain type-safe, avoiding any need for downcasting.
+You can register as many event listeners as you wish, but note that, by default, event
+listeners receive events synchronously. This means that the `publishEvent()` method
+blocks until all listeners have finished processing the event. One advantage of this
+synchronous and single-threaded approach is that, when a listener receives an event, it
+operates inside the transaction context of the publisher if a transaction context is
+available. If another strategy for event publication becomes necessary, see the javadoc
+for Spring's
+{api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface
+and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`]
+implementation for configuration options.
+
+The following example shows the bean definitions used to register and configure each of
+the classes above:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+ known.spammer@example.org
+ known.hacker@example.org
+ john.doe@example.org
+
+
+
+
+
+
+
+----
+
+Putting it all together, when the `sendEmail()` method of the `emailService` bean is
+called, if there are any email messages that should be blocked, a custom event of type
+`BlockedListEvent` is published. The `blockedListNotifier` bean is registered as an
+`ApplicationListener` and receives the `BlockedListEvent`, at which point it can
+notify appropriate parties.
+
+NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans
+within the same application context. However, for more sophisticated enterprise
+integration needs, the separately maintained
+https://projects.spring.io/spring-integration/[Spring Integration] project provides
+complete support for building lightweight,
+https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven
+architectures that build upon the well-known Spring programming model.
+
+
+[[context-functionality-events-annotation]]
+=== Annotation-based Event Listeners
+
+You can register an event listener on any method of a managed bean by using the
+`@EventListener` annotation. The `BlockedListNotifier` can be rewritten as follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class BlockedListNotifier {
+
+ private String notificationAddress;
+
+ public void setNotificationAddress(String notificationAddress) {
+ this.notificationAddress = notificationAddress;
+ }
+
+ @EventListener
+ public void processBlockedListEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class BlockedListNotifier {
+
+ lateinit var notificationAddress: String
+
+ @EventListener
+ fun processBlockedListEvent(event: BlockedListEvent) {
+ // notify appropriate parties via notificationAddress...
+ }
+ }
+----
+======
+
+The method signature once again declares the event type to which it listens,
+but, this time, with a flexible name and without implementing a specific listener interface.
+The event type can also be narrowed through generics as long as the actual event type
+resolves your generic parameter in its implementation hierarchy.
+
+If your method should listen to several events or if you want to define it with no
+parameter at all, the event types can also be specified on the annotation itself. The
+following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})
+ public void handleContextStart() {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @EventListener(ContextStartedEvent::class, ContextRefreshedEvent::class)
+ fun handleContextStart() {
+ // ...
+ }
+----
+======
+
+It is also possible to add additional runtime filtering by using the `condition` attribute
+of the annotation that defines a xref:core/expressions.adoc[`SpEL` expression], 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
+`content` attribute of the event is equal to `my-event`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @EventListener(condition = "#blEvent.content == 'my-event'")
+ public void processBlockedListEvent(BlockedListEvent blEvent) {
+ // notify appropriate parties via notificationAddress...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @EventListener(condition = "#blEvent.content == 'my-event'")
+ fun processBlockedListEvent(blEvent: BlockedListEvent) {
+ // notify appropriate parties via notificationAddress...
+ }
+----
+======
+
+Each `SpEL` expression evaluates against a dedicated context. The following table lists the
+items made available to the context so that you can use them for conditional event processing:
+
+[[context-functionality-events-annotation-tbl]]
+.Event SpEL available metadata
+|===
+| Name| Location| Description| Example
+
+| Event
+| root object
+| The actual `ApplicationEvent`.
+| `#root.event` or `event`
+
+| Arguments array
+| root object
+| The arguments (as an object array) used to invoke the method.
+| `#root.args` or `args`; `args[0]` to access the first argument, etc.
+
+| __Argument name__
+| evaluation context
+| The name of any of the method arguments. If, for some reason, the names are not available
+ (for example, because there is no debug information in the compiled byte code), individual
+ arguments are also available using the `#a<#arg>` syntax where `<#arg>` stands for the
+ argument index (starting from 0).
+| `#blEvent` or `#a0` (you can also use `#p0` or `#p<#arg>` parameter notation as an alias)
+|===
+
+Note that `#root.event` gives you access to the underlying event, even if your method
+signature actually refers to an arbitrary object that was published.
+
+If you need to publish an event as the result of processing another event, you can change the
+method signature to return the event that should be published, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @EventListener
+ public ListUpdateEvent handleBlockedListEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress and
+ // then publish a ListUpdateEvent...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @EventListener
+ fun handleBlockedListEvent(event: BlockedListEvent): ListUpdateEvent {
+ // notify appropriate parties via notificationAddress and
+ // then publish a ListUpdateEvent...
+ }
+----
+======
+
+NOTE: This feature is not supported for
+xref:core/beans/context-introduction.adoc#context-functionality-events-async[asynchronous listeners].
+
+The `handleBlockedListEvent()` method publishes a new `ListUpdateEvent` for every
+`BlockedListEvent` that it handles. If you need to publish several events, you can return
+a `Collection` or an array of events instead.
+
+
+[[context-functionality-events-async]]
+=== Asynchronous Listeners
+
+If you want a particular listener to process events asynchronously, you can reuse the
+xref:integration/scheduling.adoc#scheduling-annotation-support-async[regular `@Async` support].
+The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @EventListener
+ @Async
+ public void processBlockedListEvent(BlockedListEvent event) {
+ // BlockedListEvent is processed in a separate thread
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @EventListener
+ @Async
+ fun processBlockedListEvent(event: BlockedListEvent) {
+ // BlockedListEvent is processed in a separate thread
+ }
+----
+======
+
+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
+ {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}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]
+ to publish the event manually.
+
+
+[[context-functionality-events-order]]
+=== Ordering Listeners
+
+If you need one listener to be invoked before another one, you can add the `@Order`
+annotation to the method declaration, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @EventListener
+ @Order(42)
+ public void processBlockedListEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @EventListener
+ @Order(42)
+ fun processBlockedListEvent(event: BlockedListEvent) {
+ // notify appropriate parties via notificationAddress...
+ }
+----
+======
+
+
+[[context-functionality-events-generics]]
+=== Generic Events
+
+You can also use generics to further define the structure of your event. Consider using an
+`EntityCreatedEvent` where `T` is the type of the actual entity that got created. For example, you
+can create the following listener definition to receive only `EntityCreatedEvent` for a
+`Person`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @EventListener
+ public void onPersonCreated(EntityCreatedEvent event) {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @EventListener
+ fun onPersonCreated(event: EntityCreatedEvent) {
+ // ...
+ }
+----
+======
+
+Due to type erasure, this works only if the event that is fired resolves the generic
+parameters on which the event listener filters (that is, something like
+`class PersonCreatedEvent extends EntityCreatedEvent { ... }`).
+
+In certain circumstances, this may become quite tedious if all events follow the same
+structure (as should be the case for the event in the preceding example). In such a case,
+you can implement `ResolvableTypeProvider` to guide the framework beyond what the runtime
+environment provides. The following event shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class EntityCreatedEvent extends ApplicationEvent implements ResolvableTypeProvider {
+
+ public EntityCreatedEvent(T entity) {
+ super(entity);
+ }
+
+ @Override
+ public ResolvableType getResolvableType() {
+ return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getSource()));
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class EntityCreatedEvent(entity: T) : ApplicationEvent(entity), ResolvableTypeProvider {
+
+ override fun getResolvableType(): ResolvableType? {
+ return ResolvableType.forClassWithGenerics(javaClass, ResolvableType.forInstance(getSource()))
+ }
+ }
+----
+======
+
+TIP: This works not only for `ApplicationEvent` but any arbitrary object that you send as
+an event.
+
+
+
+[[context-functionality-resources]]
+== Convenient Access to Low-level Resources
+
+For optimal usage and understanding of application contexts, you should familiarize
+yourself with Spring's `Resource` abstraction, as described in xref:web/webflux-webclient/client-builder.adoc#webflux-client-builder-reactor-resources[Resources].
+
+An application context is a `ResourceLoader`, which can be used to load `Resource` objects.
+A `Resource` is essentially a more feature rich version of the JDK `java.net.URL` class.
+In fact, the implementations of the `Resource` wrap an instance of `java.net.URL`, where
+appropriate. A `Resource` can obtain low-level resources from almost any location in a
+transparent fashion, including from the classpath, a filesystem location, anywhere
+describable with a standard URL, and some other variations. If the resource location
+string is a simple path without any special prefixes, where those resources come from is
+specific and appropriate to the actual application context type.
+
+You can configure a bean deployed into the application context to implement the special
+callback interface, `ResourceLoaderAware`, to be automatically called back at
+initialization time with the application context itself passed in as the `ResourceLoader`.
+You can also expose properties of type `Resource`, to be used to access static resources.
+They are injected into it like any other properties. You can specify those `Resource`
+properties as simple `String` paths and rely on automatic conversion from those text
+strings to actual `Resource` objects when the bean is deployed.
+
+The location path or paths supplied to an `ApplicationContext` constructor are actually
+resource strings and, in simple form, are treated appropriately according to the specific
+context implementation. For example `ClassPathXmlApplicationContext` treats a simple
+location path as a classpath location. You can also use location paths (resource strings)
+with special prefixes to force loading of definitions from the classpath or a URL,
+regardless of the actual context type.
+
+
+
+[[context-functionality-startup]]
+== Application Startup Tracking
+
+The `ApplicationContext` manages the lifecycle of Spring applications and provides a rich
+programming model around components. As a result, complex applications can have equally
+complex component graphs and startup phases.
+
+Tracking the application startup steps with specific metrics can help understand where
+time is being spent during the startup phase, but it can also be used as a way to better
+understand the context lifecycle as a whole.
+
+The `AbstractApplicationContext` (and its subclasses) is instrumented with an
+`ApplicationStartup`, which collects `StartupStep` data about various startup phases:
+
+* application context lifecycle (base packages scanning, config classes management)
+* beans lifecycle (instantiation, smart initialization, post processing)
+* application events processing
+
+Here is an example of instrumentation in the `AnnotationConfigApplicationContext`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // create a startup step and start recording
+ StartupStep scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan");
+ // add tagging information to the current step
+ scanPackages.tag("packages", () -> Arrays.toString(basePackages));
+ // perform the actual phase we're instrumenting
+ this.scanner.scan(basePackages);
+ // end the current step
+ scanPackages.end();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // create a startup step and start recording
+ val scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan")
+ // add tagging information to the current step
+ scanPackages.tag("packages", () -> Arrays.toString(basePackages))
+ // perform the actual phase we're instrumenting
+ this.scanner.scan(basePackages)
+ // end the current step
+ scanPackages.end()
+----
+======
+
+The application context is already instrumented with multiple steps.
+Once recorded, these startup steps can be collected, displayed and analyzed with specific tools.
+For a complete list of existing startup steps, you can check out the
+xref:core/appendix/application-startup-steps.adoc[dedicated appendix section].
+
+The default `ApplicationStartup` implementation is a no-op variant, for minimal overhead.
+This means no metrics will be collected during application startup by default.
+Spring Framework ships with an implementation for tracking startup steps with Java Flight Recorder:
+`FlightRecorderApplicationStartup`. To use this variant, you must configure an instance of it
+to the `ApplicationContext` as soon as it's been created.
+
+Developers can also use the `ApplicationStartup` infrastructure if they're providing their own
+`AbstractApplicationContext` subclass, or if they wish to collect more precise data.
+
+WARNING: `ApplicationStartup` is meant to be only used during application startup and for
+the core container; this is by no means a replacement for Java profilers or
+metrics libraries like https://micrometer.io[Micrometer].
+
+To start collecting custom `StartupStep`, components can either get the `ApplicationStartup`
+instance from the application context directly, make their component implement `ApplicationStartupAware`,
+or ask for the `ApplicationStartup` type on any injection point.
+
+NOTE: Developers should not use the `"spring.*"` namespace when creating custom startup steps.
+This namespace is reserved for internal Spring usage and is subject to change.
+
+[[context-create]]
+== Convenient ApplicationContext Instantiation for Web Applications
+
+You can create `ApplicationContext` instances declaratively by using, for example, a
+`ContextLoader`. Of course, you can also create `ApplicationContext` instances
+programmatically by using one of the `ApplicationContext` implementations.
+
+You can register an `ApplicationContext` by using the `ContextLoaderListener`, as the
+following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+ contextConfigLocation
+ /WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+----
+
+The listener inspects the `contextConfigLocation` parameter. If the parameter does not
+exist, the listener uses `/WEB-INF/applicationContext.xml` as a default. When the
+parameter does exist, the listener separates the `String` by using predefined
+delimiters (comma, semicolon, and whitespace) and uses the values as locations where
+application contexts are searched. Ant-style path patterns are supported as well.
+Examples are `/WEB-INF/{asterisk}Context.xml` (for all files with names that end with
+`Context.xml` and that reside in the `WEB-INF` directory) and `/WEB-INF/**/*Context.xml`
+(for all such files in any subdirectory of `WEB-INF`).
+
+
+
+[[context-deploy-rar]]
+== Deploying a Spring `ApplicationContext` as a Jakarta EE RAR File
+
+It is possible to deploy a Spring `ApplicationContext` as a RAR file, encapsulating the
+context and all of its required bean classes and library JARs in a Jakarta EE RAR deployment
+unit. This is the equivalent of bootstrapping a stand-alone `ApplicationContext` (only hosted
+in Jakarta EE environment) being able to access the Jakarta EE servers facilities. RAR deployment
+is a more natural alternative to a scenario of deploying a headless WAR file -- in effect,
+a WAR file without any HTTP entry points that is used only for bootstrapping a Spring
+`ApplicationContext` in a Jakarta EE environment.
+
+RAR deployment is ideal for application contexts that do not need HTTP entry points but
+rather consist only of message endpoints and scheduled jobs. Beans in such a context can
+use application server resources such as the JTA transaction manager and JNDI-bound JDBC
+`DataSource` instances and JMS `ConnectionFactory` instances and can also register with
+the platform's JMX server -- all through Spring's standard transaction management and JNDI
+and JMX support facilities. Application components can also interact with the application
+server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.
+
+See the javadoc of the
+{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]
+class for the configuration details involved in RAR deployment.
+
+For a simple deployment of a Spring ApplicationContext as a Jakarta 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
+`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`).
+. Drop the resulting RAR file into your
+application server's deployment directory.
+
+NOTE: Such RAR deployment units are usually self-contained. They do not expose components
+to the outside world, not even to other modules of the same application. Interaction with a
+RAR-based `ApplicationContext` usually occurs through JMS destinations that it shares with
+other modules. A RAR-based `ApplicationContext` may also, for example, schedule some jobs
+or react to new files in the file system (or the like). If it needs to allow synchronous
+access from the outside, it could (for example) export RMI endpoints, which may be used
+by other application modules on the same machine.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc
new file mode 100644
index 000000000000..73579b414ded
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc
@@ -0,0 +1,52 @@
+[[context-load-time-weaver]]
+= Registering a `LoadTimeWeaver`
+
+The `LoadTimeWeaver` is used by Spring to dynamically transform classes as they are
+loaded into the Java virtual machine (JVM).
+
+To enable load-time weaving, you can add the `@EnableLoadTimeWeaving` to one of your
+`@Configuration` classes, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @EnableLoadTimeWeaving
+ public class AppConfig {
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @EnableLoadTimeWeaving
+ class AppConfig
+----
+======
+
+Alternatively, for XML configuration, you can use the `context:load-time-weaver` element:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+Once configured for the `ApplicationContext`, any bean within that `ApplicationContext`
+may implement `LoadTimeWeaverAware`, thereby receiving a reference to the load-time
+weaver instance. This is particularly useful in combination with
+xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be
+necessary for JPA class transformation.
+Consult the
+{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]
+javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/definition.adoc b/framework-docs/modules/ROOT/pages/core/beans/definition.adoc
new file mode 100644
index 000000000000..97164897c99a
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/definition.adoc
@@ -0,0 +1,448 @@
+[[beans-definition]]
+= Bean Overview
+
+A Spring IoC container manages one or more beans. These beans are created with the
+configuration metadata that you supply to the container (for example, in the form of XML
+`` definitions).
+
+Within the container itself, these bean definitions are represented as `BeanDefinition`
+objects, which contain (among other information) the following metadata:
+
+* A package-qualified class name: typically, the actual implementation class of the
+ bean being defined.
+* Bean behavioral configuration elements, which state how the bean should behave in the
+ container (scope, lifecycle callbacks, and so forth).
+* References to other beans that are needed for the bean to do its work. These
+ references are also called collaborators or dependencies.
+* Other configuration settings to set in the newly created object -- for example, the size
+ limit of the pool or the number of connections to use in a bean that manages a
+ connection pool.
+
+This metadata translates to a set of properties that make up each bean definition.
+The following table describes these properties:
+
+[[beans-factory-bean-definition-tbl]]
+.The bean definition
+|===
+| Property| Explained in...
+
+| Class
+| xref:core/beans/definition.adoc#beans-factory-class[Instantiating Beans]
+
+| Name
+| xref:core/beans/definition.adoc#beans-beanname[Naming Beans]
+
+| Scope
+| xref:core/beans/factory-scopes.adoc[Bean Scopes]
+
+| Constructor arguments
+| xref:core/beans/dependencies/factory-collaborators.adoc[Dependency Injection]
+
+| Properties
+| xref:core/beans/dependencies/factory-collaborators.adoc[Dependency Injection]
+
+| Autowiring mode
+| xref:core/beans/dependencies/factory-autowire.adoc[Autowiring Collaborators]
+
+| Lazy initialization mode
+| xref:core/beans/dependencies/factory-lazy-init.adoc[Lazy-initialized Beans]
+
+| Initialization method
+| xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-initializingbean[Initialization Callbacks]
+
+| Destruction method
+| xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-disposablebean[Destruction Callbacks]
+|===
+
+In addition to bean definitions that contain information on how to create a specific
+bean, the `ApplicationContext` implementations also permit the registration of existing
+objects that are created outside the container (by users). This is done by accessing the
+ApplicationContext's `BeanFactory` through the `getBeanFactory()` method, which returns
+the `DefaultListableBeanFactory` implementation. `DefaultListableBeanFactory` supports
+this registration through the `registerSingleton(..)` and `registerBeanDefinition(..)`
+methods. However, typical applications work solely with beans defined through regular
+bean definition metadata.
+
+[NOTE]
+====
+Bean metadata and manually supplied singleton instances need to be registered as early
+as possible, in order for the container to properly reason about them during autowiring
+and other introspection steps. While overriding existing metadata and existing
+singleton instances is supported to some degree, the registration of new beans at
+runtime (concurrently with live access to the factory) is not officially supported and may
+lead to concurrent access exceptions, inconsistent state in the bean container, or both.
+====
+
+
+
+[[beans-beanname]]
+== Naming Beans
+
+Every bean has one or more identifiers. These identifiers must be unique within the
+container that hosts the bean. A bean usually has only one identifier. However, if it
+requires more than one, the extra ones can be considered aliases.
+
+In XML-based configuration metadata, you use the `id` attribute, the `name` attribute, or
+both to specify bean identifiers. The `id` attribute lets you specify exactly one `id`.
+Conventionally, these names are alphanumeric ('myBean', 'someService', etc.), but they
+can contain special characters as well. If you want to introduce other aliases for the
+bean, you can also specify them in the `name` attribute, separated by a comma (`,`),
+semicolon (`;`), or white space. Although the `id` attribute is defined as an
+`xsd:string` type, bean `id` uniqueness is enforced by the container, though not by XML
+parsers.
+
+You are not required to supply a `name` or an `id` for a bean. If you do not supply a
+`name` or `id` explicitly, the container generates a unique name for that bean. However,
+if you want to refer to that bean by name, through the use of the `ref` element or a
+Service Locator style lookup, you must provide a name.
+Motivations for not supplying a name are related to using xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-inner-beans[inner beans]
+ and xref:core/beans/dependencies/factory-autowire.adoc[autowiring collaborators].
+
+.Bean Naming Conventions
+****
+The convention is to use the standard Java convention for instance field names when
+naming beans. That is, bean names start with a lowercase letter and are camel-cased
+from there. Examples of such names include `accountManager`,
+`accountService`, `userDao`, `loginController`, and so forth.
+
+Naming beans consistently makes your configuration easier to read and understand.
+Also, if you use Spring AOP, it helps a lot when applying advice to a set of beans
+related by name.
+****
+
+NOTE: With component scanning in the classpath, Spring generates bean names for unnamed
+components, following the rules described earlier: essentially, taking the simple class name
+and turning its initial character to lower-case. However, in the (unusual) special
+case when there is more than one character and both the first and second characters
+are upper case, the original casing gets preserved. These are the same rules as
+defined by `java.beans.Introspector.decapitalize` (which Spring uses here).
+
+
+[[beans-beanname-alias]]
+=== Aliasing a Bean outside the Bean Definition
+
+In a bean definition itself, you can supply more than one name for the bean, by using a
+combination of up to one name specified by the `id` attribute and any number of other
+names in the `name` attribute. These names can be equivalent aliases to the same bean
+and are useful for some situations, such as letting each component in an application
+refer to a common dependency by using a bean name that is specific to that component
+itself.
+
+Specifying all aliases where the bean is actually defined is not always adequate,
+however. It is sometimes desirable to introduce an alias for a bean that is defined
+elsewhere. This is commonly the case in large systems where configuration is split
+amongst each subsystem, with each subsystem having its own set of object definitions.
+In XML-based configuration metadata, you can use the `` element to accomplish
+this. The following example shows how to do so:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+In this case, a bean (in the same container) named `fromName` may also,
+after the use of this alias definition, be referred to as `toName`.
+
+For example, the configuration metadata for subsystem A may refer to a DataSource by the
+name of `subsystemA-dataSource`. The configuration metadata for subsystem B may refer to
+a DataSource by the name of `subsystemB-dataSource`. When composing the main application
+that uses both these subsystems, the main application refers to the DataSource by the
+name of `myApp-dataSource`. To have all three names refer to the same object, you can
+add the following alias definitions to the configuration metadata:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+----
+
+Now each component and the main application can refer to the dataSource through a name
+that is unique and guaranteed not to clash with any other definition (effectively
+creating a namespace), yet they refer to the same bean.
+
+.Java-configuration
+****
+If you use Java Configuration, the `@Bean` annotation can be used to provide aliases.
+See xref:core/beans/java/bean-annotation.adoc[Using the `@Bean` Annotation] for details.
+****
+
+
+
+[[beans-factory-class]]
+== Instantiating Beans
+
+A bean definition is essentially a recipe for creating one or more objects. The
+container looks at the recipe for a named bean when asked and uses the configuration
+metadata encapsulated by that bean definition to create (or acquire) an actual object.
+
+If you use XML-based configuration metadata, you specify the type (or class) of object
+that is to be instantiated in the `class` attribute of the `` element. This
+`class` attribute (which, internally, is a `Class` property on a `BeanDefinition`
+instance) is usually mandatory. (For exceptions, see
+xref:core/beans/definition.adoc#beans-factory-class-instance-factory-method[Instantiation by Using an Instance Factory Method] and xref:core/beans/child-bean-definitions.adoc[Bean Definition Inheritance].)
+You can use the `Class` property in one of two ways:
+
+* Typically, to specify the bean class to be constructed in the case where the container
+ itself directly creates the bean by calling its constructor reflectively, somewhat
+ equivalent to Java code with the `new` operator.
+* To specify the actual class containing the `static` factory method that is
+ invoked to create the object, in the less common case where the container invokes a
+ `static` factory method on a class to create the bean. The object type returned
+ from the invocation of the `static` factory method may be the same class or another
+ class entirely.
+
+.Nested class names
+****
+If you want to configure a bean definition for a nested class, you may use either the
+binary name or the source name of the nested class.
+
+For example, if you have a class called `SomeThing` in the `com.example` package, and
+this `SomeThing` class has a `static` nested class called `OtherThing`, they can be
+separated by a dollar sign (`$`) or a dot (`.`). So the value of the `class` attribute in
+a bean definition would be `com.example.SomeThing$OtherThing` or
+`com.example.SomeThing.OtherThing`.
+****
+
+
+[[beans-factory-class-ctor]]
+=== Instantiation with a Constructor
+
+When you create a bean by the constructor approach, all normal classes are usable by and
+compatible with Spring. That is, the class being developed does not need to implement
+any specific interfaces or to be coded in a specific fashion. Simply specifying the bean
+class should suffice. However, depending on what type of IoC you use for that specific
+bean, you may need a default (empty) constructor.
+
+The Spring IoC container can manage virtually any class you want it to manage. It is
+not limited to managing true JavaBeans. Most Spring users prefer actual JavaBeans with
+only a default (no-argument) constructor and appropriate setters and getters modeled
+after the properties in the container. You can also have more exotic non-bean-style
+classes in your container. If, for example, you need to use a legacy connection pool
+that absolutely does not adhere to the JavaBean specification, Spring can manage it as
+well.
+
+With XML-based configuration metadata you can specify your bean class as follows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+For details about the mechanism for supplying arguments to the constructor (if required)
+and setting object instance properties after the object is constructed, see
+xref:core/beans/dependencies/factory-collaborators.adoc[Injecting Dependencies].
+
+
+[[beans-factory-class-static-factory-method]]
+=== Instantiation with a Static Factory Method
+
+When defining a bean that you create with a static factory method, use the `class`
+attribute to specify the class that contains the `static` factory method and an attribute
+named `factory-method` to specify the name of the factory method itself. You should be
+able to call this method (with optional arguments, as described later) and return a live
+object, which subsequently is treated as if it had been created through a constructor.
+One use for such a bean definition is to call `static` factories in legacy code.
+
+The following bean definition specifies that the bean will be created by calling a
+factory method. The definition does not specify the type (class) of the returned object,
+but rather the class containing the factory method. In this example, the
+`createInstance()` method must be a `static` method. The following example shows how to
+specify a factory method:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+The following example shows a class that would work with the preceding bean definition:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class ClientService {
+ private static ClientService clientService = new ClientService();
+ private ClientService() {}
+
+ public static ClientService createInstance() {
+ return clientService;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class ClientService private constructor() {
+ companion object {
+ private val clientService = ClientService()
+ @JvmStatic
+ fun createInstance() = clientService
+ }
+ }
+----
+======
+
+For details about the mechanism for supplying (optional) arguments to the factory method
+and setting object instance properties after the object is returned from the factory,
+see xref:core/beans/dependencies/factory-properties-detailed.adoc[Dependencies and Configuration in Detail].
+
+
+[[beans-factory-class-instance-factory-method]]
+=== Instantiation by Using an Instance Factory Method
+
+Similar to instantiation through a xref:core/beans/definition.adoc#beans-factory-class-static-factory-method[static factory method]
+, instantiation with an instance factory method invokes a non-static
+method of an existing bean from the container to create a new bean. To use this
+mechanism, leave the `class` attribute empty and, in the `factory-bean` attribute,
+specify the name of a bean in the current (or parent or ancestor) container that contains
+the instance method that is to be invoked to create the object. Set the name of the
+factory method itself with the `factory-method` attribute. The following example shows
+how to configure such a bean:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+The following example shows the corresponding class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class DefaultServiceLocator {
+
+ private static ClientService clientService = new ClientServiceImpl();
+
+ public ClientService createClientServiceInstance() {
+ return clientService;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class DefaultServiceLocator {
+ companion object {
+ private val clientService = ClientServiceImpl()
+ }
+ fun createClientServiceInstance(): ClientService {
+ return clientService
+ }
+ }
+----
+======
+
+One factory class can also hold more than one factory method, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+The following example shows the corresponding class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class DefaultServiceLocator {
+
+ private static ClientService clientService = new ClientServiceImpl();
+
+ private static AccountService accountService = new AccountServiceImpl();
+
+ public ClientService createClientServiceInstance() {
+ return clientService;
+ }
+
+ public AccountService createAccountServiceInstance() {
+ return accountService;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class DefaultServiceLocator {
+ companion object {
+ private val clientService = ClientServiceImpl()
+ private val accountService = AccountServiceImpl()
+ }
+
+ fun createClientServiceInstance(): ClientService {
+ return clientService
+ }
+
+ fun createAccountServiceInstance(): AccountService {
+ return accountService
+ }
+ }
+----
+======
+
+This approach shows that the factory bean itself can be managed and configured through
+dependency injection (DI). See xref:core/beans/dependencies/factory-properties-detailed.adoc[Dependencies and Configuration in Detail]
+.
+
+NOTE: In Spring documentation, "factory bean" refers to a bean that is configured in the
+Spring container and that creates objects through an
+xref:core/beans/definition.adoc#beans-factory-class-instance-factory-method[instance] or
+xref:core/beans/definition.adoc#beans-factory-class-static-factory-method[static] factory method. By contrast,
+`FactoryBean` (notice the capitalization) refers to a Spring-specific
+xref:core/beans/factory-extension.adoc#beans-factory-extension-factorybean[`FactoryBean`] implementation class.
+
+
+[[beans-factory-type-determination]]
+=== Determining a Bean's Runtime Type
+
+The runtime type of a specific bean is non-trivial to determine. A specified class in
+the bean metadata definition is just an initial class reference, potentially combined
+with a declared factory method or being a `FactoryBean` class which may lead to a
+different runtime type of the bean, or not being set at all in case of an instance-level
+factory method (which is resolved via the specified `factory-bean` name instead).
+Additionally, AOP proxying may wrap a bean instance with an interface-based proxy with
+limited exposure of the target bean's actual type (just its implemented interfaces).
+
+The recommended way to find out about the actual runtime type of a particular bean is
+a `BeanFactory.getType` call for the specified bean name. This takes all of the above
+cases into account and returns the type of object that a `BeanFactory.getBean` call is
+going to return for the same bean name.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies.adoc
new file mode 100644
index 000000000000..e22058a1ff3b
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies.adoc
@@ -0,0 +1,12 @@
+[[beans-dependencies]]
+= Dependencies
+:page-section-summary-toc: 1
+
+A typical enterprise application does not consist of a single object (or bean in the
+Spring parlance). Even the simplest application has a few objects that work together to
+present what the end-user sees as a coherent application. This next section explains how
+you go from defining a number of bean definitions that stand alone to a fully realized
+application where objects collaborate to achieve a goal.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-autowire.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-autowire.adoc
new file mode 100644
index 000000000000..829fe815a81c
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-autowire.adoc
@@ -0,0 +1,127 @@
+[[beans-factory-autowire]]
+= Autowiring Collaborators
+
+The Spring container can autowire relationships between collaborating beans. You can
+let Spring resolve collaborators (other beans) automatically for your bean by
+inspecting the contents of the `ApplicationContext`. Autowiring has the following
+advantages:
+
+* Autowiring can significantly reduce the need to specify properties or constructor
+ arguments. (Other mechanisms such as a bean template
+ xref:core/beans/child-bean-definitions.adoc[discussed elsewhere in this chapter] are also valuable
+ in this regard.)
+* Autowiring can update a configuration as your objects evolve. For example, if you need
+ to add a dependency to a class, that dependency can be satisfied automatically without
+ you needing to modify the configuration. Thus autowiring can be especially useful
+ during development, without negating the option of switching to explicit wiring when
+ the code base becomes more stable.
+
+When using XML-based configuration metadata (see xref:core/beans/dependencies/factory-collaborators.adoc[Dependency Injection]), you
+can specify the autowire mode for a bean definition with the `autowire` attribute of the
+`` element. The autowiring functionality has four modes. You specify autowiring
+per bean and can thus choose which ones to autowire. The following table describes the
+four autowiring modes:
+
+[[beans-factory-autowiring-modes-tbl]]
+.Autowiring modes
+[cols="20%,80%"]
+|===
+| Mode| Explanation
+
+| `no`
+| (Default) No autowiring. Bean references must be defined by `ref` elements. Changing
+ the default setting is not recommended for larger deployments, because specifying
+ collaborators explicitly gives greater control and clarity. To some extent, it
+ documents the structure of a system.
+
+| `byName`
+| Autowiring by property name. Spring looks for a bean with the same name as the
+ property that needs to be autowired. For example, if a bean definition is set to
+ autowire by name and it contains a `master` property (that is, it has a
+ `setMaster(..)` method), Spring looks for a bean definition named `master` and uses
+ it to set the property.
+
+| `byType`
+| Lets a property be autowired if exactly one bean of the property type exists in
+ the container. If more than one exists, a fatal exception is thrown, which indicates
+ that you may not use `byType` autowiring for that bean. If there are no matching
+ beans, nothing happens (the property is not set).
+
+| `constructor`
+| Analogous to `byType` but applies to constructor arguments. If there is not exactly
+ one bean of the constructor argument type in the container, a fatal error is raised.
+|===
+
+With `byType` or `constructor` autowiring mode, you can wire arrays and
+typed collections. In such cases, all autowire candidates within the container that
+match the expected type are provided to satisfy the dependency. You can autowire
+strongly-typed `Map` instances if the expected key type is `String`. An autowired `Map`
+instance's values consist of all bean instances that match the expected type, and the
+`Map` instance's keys contain the corresponding bean names.
+
+
+[[beans-autowired-exceptions]]
+== Limitations and Disadvantages of Autowiring
+
+Autowiring works best when it is used consistently across a project. If autowiring is
+not used in general, it might be confusing to developers to use it to wire only one or
+two bean definitions.
+
+Consider the limitations and disadvantages of autowiring:
+
+* Explicit dependencies in `property` and `constructor-arg` settings always override
+ autowiring. You cannot autowire simple properties such as primitives,
+ `Strings`, and `Classes` (and arrays of such simple properties). This limitation is
+ by-design.
+* Autowiring is less exact than explicit wiring. Although, as noted in the earlier table,
+ Spring is careful to avoid guessing in case of ambiguity that might have unexpected
+ results. The relationships between your Spring-managed objects are no longer
+ documented explicitly.
+* Wiring information may not be available to tools that may generate documentation from
+ a Spring container.
+* Multiple bean definitions within the container may match the type specified by the
+ setter method or constructor argument to be autowired. For arrays, collections, or
+ `Map` instances, this is not necessarily a problem. However, for dependencies that
+ expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean
+ definition is available, an exception is thrown.
+
+In the latter scenario, you have several options:
+
+* Abandon autowiring in favor of explicit wiring.
+* Avoid autowiring for a bean definition by setting its `autowire-candidate` attributes
+ to `false`, as described in the xref:core/beans/dependencies/factory-autowire.adoc#beans-factory-autowire-candidate[next section].
+* Designate a single bean definition as the primary candidate by setting the
+ `primary` attribute of its `` element to `true`.
+* Implement the more fine-grained control available with annotation-based configuration,
+ as described in xref:core/beans/annotation-config.adoc[Annotation-based Container Configuration].
+
+
+
+[[beans-factory-autowire-candidate]]
+== Excluding a Bean from Autowiring
+
+On a per-bean basis, you can exclude a bean from autowiring. In Spring's XML format, set
+the `autowire-candidate` attribute of the `` element to `false`. The container
+makes that specific bean definition unavailable to the autowiring infrastructure
+(including annotation style configurations such as xref:core/beans/annotation-config/autowired.adoc[`@Autowired`]
+).
+
+NOTE: The `autowire-candidate` attribute is designed to only affect type-based autowiring.
+It does not affect explicit references by name, which get resolved even if the
+specified bean is not marked as an autowire candidate. As a consequence, autowiring
+by name nevertheless injects a bean if the name matches.
+
+You can also limit autowire candidates based on pattern-matching against bean names. The
+top-level `` element accepts one or more patterns within its
+`default-autowire-candidates` attribute. For example, to limit autowire candidate status
+to any bean whose name ends with `Repository`, provide a value of `*Repository`. To
+provide multiple patterns, define them in a comma-separated list. An explicit value of
+`true` or `false` for a bean definition's `autowire-candidate` attribute always takes
+precedence. For such beans, the pattern matching rules do not apply.
+
+These techniques are useful for beans that you never want to be injected into other
+beans by autowiring. It does not mean that an excluded bean cannot itself be configured by
+using autowiring. Rather, the bean itself is not a candidate for autowiring other beans.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-collaborators.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-collaborators.adoc
new file mode 100644
index 000000000000..25bbaff2b63b
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-collaborators.adoc
@@ -0,0 +1,608 @@
+[[beans-factory-collaborators]]
+= Dependency Injection
+
+Dependency injection (DI) is a process whereby objects define their dependencies
+(that is, the other objects with which they work) only through constructor arguments,
+arguments to a factory method, or properties that are set on the object instance after
+it is constructed or returned from a factory method. The container then injects those
+dependencies when it creates the bean. This process is fundamentally the inverse (hence
+the name, Inversion of Control) of the bean itself controlling the instantiation
+or location of its dependencies on its own by using direct construction of classes or
+the Service Locator pattern.
+
+Code is cleaner with the DI principle, and decoupling is more effective when objects are
+provided with their dependencies. The object does not look up its dependencies and does
+not know the location or class of the dependencies. As a result, your classes become easier
+to test, particularly when the dependencies are on interfaces or abstract base classes,
+which allow for stub or mock implementations to be used in unit tests.
+
+DI exists in two major variants: xref:core/beans/dependencies/factory-collaborators.adoc#beans-constructor-injection[Constructor-based dependency injection]
+ and xref:core/beans/dependencies/factory-collaborators.adoc#beans-setter-injection[Setter-based dependency injection].
+
+
+[[beans-constructor-injection]]
+== Constructor-based Dependency Injection
+
+Constructor-based DI is accomplished by the container invoking a constructor with a
+number of arguments, each representing a dependency. Calling a `static` factory method
+with specific arguments to construct the bean is nearly equivalent, and this discussion
+treats arguments to a constructor and to a `static` factory method similarly. The
+following example shows a class that can only be dependency-injected with constructor
+injection:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class SimpleMovieLister {
+
+ // the SimpleMovieLister has a dependency on a MovieFinder
+ private final MovieFinder movieFinder;
+
+ // a constructor so that the Spring container can inject a MovieFinder
+ public SimpleMovieLister(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // business logic that actually uses the injected MovieFinder is omitted...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // a constructor so that the Spring container can inject a MovieFinder
+ class SimpleMovieLister(private val movieFinder: MovieFinder) {
+ // business logic that actually uses the injected MovieFinder is omitted...
+ }
+----
+======
+
+Notice that there is nothing special about this class. It is a POJO that
+has no dependencies on container specific interfaces, base classes, or annotations.
+
+[[beans-factory-ctor-arguments-resolution]]
+=== Constructor Argument Resolution
+
+Constructor argument resolution matching occurs by using the argument's type. If no
+potential ambiguity exists in the constructor arguments of a bean definition, the
+order in which the constructor arguments are defined in a bean definition is the order
+in which those arguments are supplied to the appropriate constructor when the bean is
+being instantiated. Consider the following class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package x.y;
+
+ public class ThingOne {
+
+ public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
+ // ...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package x.y
+
+ class ThingOne(thingTwo: ThingTwo, thingThree: ThingThree)
+----
+======
+
+Assuming that the `ThingTwo` and `ThingThree` classes are not related by inheritance, no
+potential ambiguity exists. Thus, the following configuration works fine, and you do not
+need to specify the constructor argument indexes or types explicitly in the
+`` element.
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+----
+
+When another bean is referenced, the type is known, and matching can occur (as was the
+case with the preceding example). When a simple type is used, such as
+`true`, Spring cannot determine the type of the value, and so cannot match
+by type without help. Consider the following class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package examples;
+
+ public class ExampleBean {
+
+ // Number of years to calculate the Ultimate Answer
+ private final int years;
+
+ // The Answer to Life, the Universe, and Everything
+ private final String ultimateAnswer;
+
+ public ExampleBean(int years, String ultimateAnswer) {
+ this.years = years;
+ this.ultimateAnswer = ultimateAnswer;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package examples
+
+ 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
+ )
+----
+======
+
+.[[beans-factory-ctor-arguments-type]]Constructor argument type matching
+--
+In the preceding scenario, the container can use type matching with simple types if
+you explicitly specify the type of the constructor argument by using the `type` attribute,
+as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+--
+
+.[[beans-factory-ctor-arguments-index]]Constructor argument index
+--
+You can use the `index` attribute to specify explicitly the index of constructor arguments,
+as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+
+In addition to resolving the ambiguity of multiple simple values, specifying an index
+resolves ambiguity where a constructor has two arguments of the same type.
+
+NOTE: The index is 0-based.
+--
+
+.[[beans-factory-ctor-arguments-name]]Constructor argument name
+--
+You can also use the constructor parameter name for value disambiguation, as the following
+example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+
+Keep in mind that, to make this work out of the box, your code must be compiled with the
+debug flag enabled so that Spring can look up the parameter name from the constructor.
+If you cannot or do not want to compile your code with the debug flag, you can use the
+https://download.oracle.com/javase/8/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties]
+JDK annotation to explicitly name your constructor arguments. The sample class would
+then have to look as follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package examples;
+
+ public class ExampleBean {
+
+ // Fields omitted
+
+ @ConstructorProperties({"years", "ultimateAnswer"})
+ public ExampleBean(int years, String ultimateAnswer) {
+ this.years = years;
+ this.ultimateAnswer = ultimateAnswer;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package examples
+
+ class ExampleBean
+ @ConstructorProperties("years", "ultimateAnswer")
+ constructor(val years: Int, val ultimateAnswer: String)
+----
+======
+--
+
+
+[[beans-setter-injection]]
+== Setter-based Dependency Injection
+
+Setter-based DI is accomplished by the container calling setter methods on your
+beans after invoking a no-argument constructor or a no-argument `static` factory method to
+instantiate your bean.
+
+The following example shows a class that can only be dependency-injected by using pure
+setter injection. This class is conventional Java. It is a POJO that has no dependencies
+on container specific interfaces, base classes, or annotations.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class SimpleMovieLister {
+
+ // the SimpleMovieLister has a dependency on the MovieFinder
+ private MovieFinder movieFinder;
+
+ // a setter method so that the Spring container can inject a MovieFinder
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // business logic that actually uses the injected MovieFinder is omitted...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+class SimpleMovieLister {
+
+ // a late-initialized property so that the Spring container can inject a MovieFinder
+ lateinit var movieFinder: MovieFinder
+
+ // business logic that actually uses the injected MovieFinder is omitted...
+}
+----
+======
+
+
+The `ApplicationContext` supports constructor-based and setter-based DI for the beans it
+manages. It also supports setter-based DI after some dependencies have already been
+injected through the constructor approach. You configure the dependencies in the form of
+a `BeanDefinition`, which you use in conjunction with `PropertyEditor` instances to
+convert properties from one format to another. However, most Spring users do not work
+with these classes directly (that is, programmatically) but rather with XML `bean`
+definitions, annotated components (that is, classes annotated with `@Component`,
+`@Controller`, and so forth), or `@Bean` methods in Java-based `@Configuration` classes.
+These sources are then converted internally into instances of `BeanDefinition` and used to
+load an entire Spring IoC container instance.
+
+[[beans-constructor-vs-setter-injection]]
+.Constructor-based or setter-based DI?
+****
+Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to
+use constructors for mandatory dependencies and setter methods or configuration methods
+for optional dependencies. Note that use of the xref:core/beans/annotation-config/autowired.adoc[@Autowired]
+annotation on a setter method can be used to make the property be a required dependency;
+however, constructor injection with programmatic validation of arguments is preferable.
+
+The Spring team generally advocates constructor injection, as it lets you implement
+application components as immutable objects and ensures that required dependencies
+are not `null`. Furthermore, constructor-injected components are always returned to the client
+(calling) code in a fully initialized state. As a side note, a large number of constructor
+arguments is a bad code smell, implying that the class likely has too many
+responsibilities and should be refactored to better address proper separation of concerns.
+
+Setter injection should primarily only be used for optional dependencies that can be
+assigned reasonable default values within the class. Otherwise, not-null checks must be
+performed everywhere the code uses the dependency. One benefit of setter injection is that
+setter methods make objects of that class amenable to reconfiguration or re-injection
+later. Management through xref:integration/jmx.adoc[JMX MBeans] is therefore a compelling
+use case for setter injection.
+
+Use the DI style that makes the most sense for a particular class. Sometimes, when dealing
+with third-party classes for which you do not have the source, the choice is made for you.
+For example, if a third-party class does not expose any setter methods, then constructor
+injection may be the only available form of DI.
+****
+
+
+[[beans-dependency-resolution]]
+== Dependency Resolution Process
+
+The container performs bean dependency resolution as follows:
+
+* The `ApplicationContext` is created and initialized with configuration metadata that
+ describes all the beans. Configuration metadata can be specified by XML, Java code, or
+ annotations.
+* For each bean, its dependencies are expressed in the form of properties, constructor
+ arguments, or arguments to the static-factory method (if you use that instead of a
+ normal constructor). These dependencies are provided to the bean, when the bean is
+ actually created.
+* Each property or constructor argument is an actual definition of the value to set, or
+ a reference to another bean in the container.
+* Each property or constructor argument that is a value is converted from its specified
+ format to the actual type of that property or constructor argument. By default, Spring
+ can convert a value supplied in string format to all built-in types, such as `int`,
+ `long`, `String`, `boolean`, and so forth.
+
+The Spring container validates the configuration of each bean as the container is created.
+However, the bean properties themselves are not set until the bean is actually created.
+Beans that are singleton-scoped and set to be pre-instantiated (the default) are created
+when the container is created. Scopes are defined in xref:core/beans/factory-scopes.adoc[Bean Scopes]. Otherwise,
+the bean is created only when it is requested. Creation of a bean potentially causes a
+graph of beans to be created, as the bean's dependencies and its dependencies'
+dependencies (and so on) are created and assigned. Note that resolution mismatches among
+those dependencies may show up late -- that is, on first creation of the affected bean.
+
+.Circular dependencies
+****
+If you use predominantly constructor injection, it is possible to create an unresolvable
+circular dependency scenario.
+
+For example: Class A requires an instance of class B through constructor injection, and
+class B requires an instance of class A through constructor injection. If you configure
+beans for classes A and B to be injected into each other, the Spring IoC container
+detects this circular reference at runtime, and throws a
+`BeanCurrentlyInCreationException`.
+
+One possible solution is to edit the source code of some classes to be configured by
+setters rather than constructors. Alternatively, avoid constructor injection and use
+setter injection only. In other words, although it is not recommended, you can configure
+circular dependencies with setter injection.
+
+Unlike the typical case (with no circular dependencies), a circular dependency
+between bean A and bean B forces one of the beans to be injected into the other prior to
+being fully initialized itself (a classic chicken-and-egg scenario).
+****
+
+You can generally trust Spring to do the right thing. It detects configuration problems,
+such as references to non-existent beans and circular dependencies, at container
+load-time. Spring sets properties and resolves dependencies as late as possible, when
+the bean is actually created. This means that a Spring container that has loaded
+correctly can later generate an exception when you request an object if there is a
+problem creating that object or one of its dependencies -- for example, the bean throws an
+exception as a result of a missing or invalid property. This potentially delayed
+visibility of some configuration issues is why `ApplicationContext` implementations by
+default pre-instantiate singleton beans. At the cost of some upfront time and memory to
+create these beans before they are actually needed, you discover configuration issues
+when the `ApplicationContext` is created, not later. You can still override this default
+behavior so that singleton beans initialize lazily, rather than being eagerly
+pre-instantiated.
+
+If no circular dependencies exist, when one or more collaborating beans are being
+injected into a dependent bean, each collaborating bean is totally configured prior
+to being injected into the dependent bean. This means that, if bean A has a dependency on
+bean B, the Spring IoC container completely configures bean B prior to invoking the
+setter method on bean A. In other words, the bean is instantiated (if it is not a
+pre-instantiated singleton), its dependencies are set, and the relevant lifecycle
+methods (such as a xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-initializingbean[configured init method]
+or the xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-initializingbean[InitializingBean callback method])
+are invoked.
+
+
+[[beans-some-examples]]
+== Examples of Dependency Injection
+
+The following example uses XML-based configuration metadata for setter-based DI. A small
+part of a Spring XML configuration file specifies some bean definitions as follows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+The following example shows the corresponding `ExampleBean` class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class ExampleBean {
+
+ private AnotherBean beanOne;
+
+ private YetAnotherBean beanTwo;
+
+ private int i;
+
+ public void setBeanOne(AnotherBean beanOne) {
+ this.beanOne = beanOne;
+ }
+
+ public void setBeanTwo(YetAnotherBean beanTwo) {
+ this.beanTwo = beanTwo;
+ }
+
+ public void setIntegerProperty(int i) {
+ this.i = i;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+class ExampleBean {
+ lateinit var beanOne: AnotherBean
+ lateinit var beanTwo: YetAnotherBean
+ var i: Int = 0
+}
+----
+======
+
+In the preceding example, setters are declared to match against the properties specified
+in the XML file. The following example uses constructor-based DI:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+The following example shows the corresponding `ExampleBean` class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class ExampleBean {
+
+ private AnotherBean beanOne;
+
+ private YetAnotherBean beanTwo;
+
+ private int i;
+
+ public ExampleBean(
+ AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
+ this.beanOne = anotherBean;
+ this.beanTwo = yetAnotherBean;
+ this.i = i;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+class ExampleBean(
+ private val beanOne: AnotherBean,
+ private val beanTwo: YetAnotherBean,
+ private val i: Int)
+----
+======
+
+The constructor arguments specified in the bean definition are used as arguments to
+the constructor of the `ExampleBean`.
+
+Now consider a variant of this example, where, instead of using a constructor, Spring is
+told to call a `static` factory method to return an instance of the object:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+----
+
+The following example shows the corresponding `ExampleBean` class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class ExampleBean {
+
+ // a private constructor
+ private ExampleBean(...) {
+ ...
+ }
+
+ // a static factory method; the arguments to this method can be
+ // considered the dependencies of the bean that is returned,
+ // regardless of how those arguments are actually used.
+ public static ExampleBean createInstance (
+ AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
+
+ ExampleBean eb = new ExampleBean (...);
+ // some other operations...
+ return eb;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class ExampleBean private constructor() {
+ companion object {
+ // a static factory method; the arguments to this method can be
+ // considered the dependencies of the bean that is returned,
+ // regardless of how those arguments are actually used.
+ @JvmStatic
+ fun createInstance(anotherBean: AnotherBean, yetAnotherBean: YetAnotherBean, i: Int): ExampleBean {
+ val eb = ExampleBean (...)
+ // some other operations...
+ return eb
+ }
+ }
+ }
+----
+======
+
+Arguments to the `static` factory method are supplied by `` elements,
+exactly the same as if a constructor had actually been used. The type of the class being
+returned by the factory method does not have to be of the same type as the class that
+contains the `static` factory method (although, in this example, it is). An instance
+(non-static) factory method can be used in an essentially identical fashion (aside
+from the use of the `factory-bean` attribute instead of the `class` attribute), so we
+do not discuss those details here.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-dependson.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-dependson.adoc
new file mode 100644
index 000000000000..17e5e98246bb
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-dependson.adoc
@@ -0,0 +1,40 @@
+[[beans-factory-dependson]]
+= Using `depends-on`
+
+If a bean is a dependency of another bean, that usually means that one bean is set as a
+property of another. Typically you accomplish this with the <`
+element>> in XML-based configuration metadata. However, sometimes dependencies between
+beans are less direct. An example is when a static initializer in a class needs to be
+triggered, such as for database driver registration. The `depends-on` attribute can
+explicitly force one or more beans to be initialized before the bean using this element
+is initialized. The following example uses the `depends-on` attribute to express a
+dependency on a single bean:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+----
+
+To express a dependency on multiple beans, supply a list of bean names as the value of
+the `depends-on` attribute (commas, whitespace, and semicolons are valid
+delimiters):
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+----
+
+NOTE: The `depends-on` attribute can specify both an initialization-time dependency and,
+in the case of xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singleton] beans only, a corresponding
+destruction-time dependency. Dependent beans that define a `depends-on` relationship
+with a given bean are destroyed first, prior to the given bean itself being destroyed.
+Thus, `depends-on` can also control shutdown order.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-lazy-init.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-lazy-init.adoc
new file mode 100644
index 000000000000..59fd3a319b9e
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-lazy-init.adoc
@@ -0,0 +1,42 @@
+[[beans-factory-lazy-init]]
+= Lazy-initialized Beans
+
+By default, `ApplicationContext` implementations eagerly create and configure all
+xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singleton] beans as part of the initialization
+process. Generally, this pre-instantiation is desirable, because errors in the
+configuration or surrounding environment are discovered immediately, as opposed to hours
+or even days later. When this behavior is not desirable, you can prevent
+pre-instantiation of a singleton bean by marking the bean definition as being
+lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean
+instance when it is first requested, rather than at startup.
+
+In XML, this behavior is controlled by the `lazy-init` attribute on the ``
+element, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+----
+
+When the preceding configuration is consumed by an `ApplicationContext`, the `lazy` bean
+is not eagerly pre-instantiated when the `ApplicationContext` starts,
+whereas the `not.lazy` bean is eagerly pre-instantiated.
+
+However, when a lazy-initialized bean is a dependency of a singleton bean that is
+not lazy-initialized, the `ApplicationContext` creates the lazy-initialized bean at
+startup, because it must satisfy the singleton's dependencies. The lazy-initialized bean
+is injected into a singleton bean elsewhere that is not lazy-initialized.
+
+You can also control lazy-initialization at the container level by using the
+`default-lazy-init` attribute on the `` element, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc
new file mode 100644
index 000000000000..108202c40ac7
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc
@@ -0,0 +1,434 @@
+[[beans-factory-method-injection]]
+= Method Injection
+
+In most application scenarios, most beans in the container are
+xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singletons]. When a singleton bean needs to
+collaborate with another singleton bean or a non-singleton bean needs to collaborate
+with another non-singleton bean, you typically handle the dependency by defining one
+bean as a property of the other. A problem arises when the bean lifecycles are
+different. Suppose singleton bean A needs to use non-singleton (prototype) bean B,
+perhaps on each method invocation on A. The container creates the singleton bean A only
+once, and thus only gets one opportunity to set the properties. The container cannot
+provide bean A with a new instance of bean B every time one is needed.
+
+A solution is to forego some inversion of control. You can xref:core/beans/factory-nature.adoc#beans-factory-aware[make bean A aware of the container]
+ by implementing the `ApplicationContextAware` interface,
+and by xref:core/beans/basics.adoc#beans-factory-client[making a `getBean("B")` call to the container] ask for (a
+typically new) bean B instance every time bean A needs it. The following example
+shows this approach:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages",fold="none"]
+----
+ package fiona.apple;
+
+ // Spring-API imports
+ import org.springframework.beans.BeansException;
+ import org.springframework.context.ApplicationContext;
+ import org.springframework.context.ApplicationContextAware;
+
+ /**
+ * A class that uses a stateful Command-style class to perform
+ * some processing.
+ */
+ public class CommandManager implements ApplicationContextAware {
+
+ private ApplicationContext applicationContext;
+
+ public Object process(Map commandState) {
+ // grab a new instance of the appropriate Command
+ Command command = createCommand();
+ // set the state on the (hopefully brand new) Command instance
+ command.setState(commandState);
+ return command.execute();
+ }
+
+ protected Command createCommand() {
+ // notice the Spring API dependency!
+ return this.applicationContext.getBean("command", Command.class);
+ }
+
+ public void setApplicationContext(
+ ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages",fold="none"]
+----
+ package fiona.apple
+
+ // Spring-API imports
+ import org.springframework.context.ApplicationContext
+ import org.springframework.context.ApplicationContextAware
+
+ // A class that uses a stateful Command-style class to perform
+ // some processing.
+ class CommandManager : ApplicationContextAware {
+
+ private lateinit var applicationContext: ApplicationContext
+
+ fun process(commandState: Map<*, *>): Any {
+ // grab a new instance of the appropriate Command
+ val command = createCommand()
+ // set the state on the (hopefully brand new) Command instance
+ command.state = commandState
+ return command.execute()
+ }
+
+ // notice the Spring API dependency!
+ protected fun createCommand() =
+ applicationContext.getBean("command", Command::class.java)
+
+ override fun setApplicationContext(applicationContext: ApplicationContext) {
+ this.applicationContext = applicationContext
+ }
+ }
+----
+======
+
+The preceding is not desirable, because the business code is aware of and coupled to the
+Spring Framework. Method Injection, a somewhat advanced feature of the Spring IoC
+container, lets you handle this use case cleanly.
+
+****
+You can read more about the motivation for Method Injection in
+https://spring.io/blog/2004/08/06/method-injection/[this blog entry].
+****
+
+
+
+[[beans-factory-lookup-method-injection]]
+== Lookup Method Injection
+
+Lookup method injection is the ability of the container to override methods on
+container-managed beans and return the lookup result for another named bean in the
+container. The lookup typically involves a prototype bean, as in the scenario described
+in xref:core/beans/dependencies/factory-method-injection.adoc[the preceding section]. The Spring Framework
+implements this method injection by using bytecode generation from the CGLIB library to
+dynamically generate a subclass that overrides the method.
+
+[NOTE]
+====
+* For this dynamic subclassing to work, the class that the Spring bean container
+ subclasses cannot be `final`, and the method to be overridden cannot be `final`, either.
+* Unit-testing a class that has an `abstract` method requires you to subclass the class
+ yourself and to supply a stub implementation of the `abstract` method.
+* Concrete methods are also necessary for component scanning, which requires concrete
+ classes to pick up.
+* A further key limitation is that lookup methods do not work with factory methods and
+ in particular not with `@Bean` methods in configuration classes, since, in that case,
+ the container is not in charge of creating the instance and therefore cannot create
+ a runtime-generated subclass on the fly.
+====
+
+In the case of the `CommandManager` class in the previous code snippet, the
+Spring container dynamically overrides the implementation of the `createCommand()`
+method. The `CommandManager` class does not have any Spring dependencies, as
+the reworked example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages",fold="none"]
+----
+ package fiona.apple;
+
+ // no more Spring imports!
+
+ public abstract class CommandManager {
+
+ public Object process(Object commandState) {
+ // grab a new instance of the appropriate Command interface
+ Command command = createCommand();
+ // set the state on the (hopefully brand new) Command instance
+ command.setState(commandState);
+ return command.execute();
+ }
+
+ // okay... but where is the implementation of this method?
+ protected abstract Command createCommand();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages",fold="none"]
+----
+ package fiona.apple
+
+ // no more Spring imports!
+
+ abstract class CommandManager {
+
+ fun process(commandState: Any): Any {
+ // grab a new instance of the appropriate Command interface
+ val command = createCommand()
+ // set the state on the (hopefully brand new) Command instance
+ command.state = commandState
+ return command.execute()
+ }
+
+ // okay... but where is the implementation of this method?
+ protected abstract fun createCommand(): Command
+ }
+----
+======
+
+In the client class that contains the method to be injected (the `CommandManager` in this
+case), the method to be injected requires a signature of the following form:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+ [abstract] theMethodName(no-arguments);
+----
+
+If the method is `abstract`, the dynamically-generated subclass implements the method.
+Otherwise, the dynamically-generated subclass overrides the concrete method defined in
+the original class. Consider the following example:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+----
+
+The bean identified as `commandManager` calls its own `createCommand()` method
+whenever it needs a new instance of the `myCommand` bean. You must be careful to deploy
+the `myCommand` bean as a prototype if that is actually what is needed. If it is
+a xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singleton], the same instance of the `myCommand`
+bean is returned each time.
+
+Alternatively, within the annotation-based component model, you can declare a lookup
+method through the `@Lookup` annotation, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public abstract class CommandManager {
+
+ public Object process(Object commandState) {
+ Command command = createCommand();
+ command.setState(commandState);
+ return command.execute();
+ }
+
+ @Lookup("myCommand")
+ protected abstract Command createCommand();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ abstract class CommandManager {
+
+ fun process(commandState: Any): Any {
+ val command = createCommand()
+ command.state = commandState
+ return command.execute()
+ }
+
+ @Lookup("myCommand")
+ protected abstract fun createCommand(): Command
+ }
+----
+======
+
+Or, more idiomatically, you can rely on the target bean getting resolved against the
+declared return type of the lookup method:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public abstract class CommandManager {
+
+ public Object process(Object commandState) {
+ Command command = createCommand();
+ command.setState(commandState);
+ return command.execute();
+ }
+
+ @Lookup
+ protected abstract Command createCommand();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ abstract class CommandManager {
+
+ fun process(commandState: Any): Any {
+ val command = createCommand()
+ command.state = commandState
+ return command.execute()
+ }
+
+ @Lookup
+ protected abstract fun createCommand(): Command
+ }
+----
+======
+
+Note that you should typically declare such annotated lookup methods with a concrete
+stub implementation, in order for them to be compatible with Spring's component
+scanning rules where abstract classes get ignored by default. This limitation does not
+apply to explicitly registered or explicitly imported bean classes.
+
+[TIP]
+====
+Another way of accessing differently scoped target beans is an `ObjectFactory`/
+`Provider` injection point. See xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection[Scoped Beans as Dependencies].
+
+You may also find the `ServiceLocatorFactoryBean` (in the
+`org.springframework.beans.factory.config` package) to be useful.
+====
+
+
+
+[[beans-factory-arbitrary-method-replacement]]
+== Arbitrary Method Replacement
+
+A less useful form of method injection than lookup method injection is the ability to
+replace arbitrary methods in a managed bean with another method implementation. You
+can safely skip the rest of this section until you actually need this functionality.
+
+With XML-based configuration metadata, you can use the `replaced-method` element to
+replace an existing method implementation with another, for a deployed bean. Consider
+the following class, which has a method called `computeValue` that we want to override:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class MyValueCalculator {
+
+ public String computeValue(String input) {
+ // some real code...
+ }
+
+ // some other methods...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class MyValueCalculator {
+
+ fun computeValue(input: String): String {
+ // some real code...
+ }
+
+ // some other methods...
+ }
+----
+======
+
+A class that implements the `org.springframework.beans.factory.support.MethodReplacer`
+interface provides the new method definition, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ /**
+ * meant to be used to override the existing computeValue(String)
+ * implementation in MyValueCalculator
+ */
+ public class ReplacementComputeValue implements MethodReplacer {
+
+ public Object reimplement(Object o, Method m, Object[] args) throws Throwable {
+ // get the input value, work with it, and return a computed result
+ String input = (String) args[0];
+ ...
+ return ...;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ /**
+ * 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 {
+ // get the input value, work with it, and return a computed result
+ val input = args[0] as String;
+ ...
+ return ...;
+ }
+ }
+----
+======
+
+
+
+The bean definition to deploy the original class and specify the method override would
+resemble the following example:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+ String
+
+
+
+
+----
+
+You can use one or more `` elements within the ``
+element to indicate the method signature of the method being overridden. The signature
+for the arguments is necessary only if the method is overloaded and multiple variants
+exist within the class. For convenience, the type string for an argument may be a
+substring of the fully qualified type name. For example, the following all match
+`java.lang.String`:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ java.lang.String
+ String
+ Str
+----
+
+Because the number of arguments is often enough to distinguish between each possible
+choice, this shortcut can save a lot of typing, by letting you type only the
+shortest string that matches an argument type.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc
new file mode 100644
index 000000000000..ae7874fa329f
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc
@@ -0,0 +1,626 @@
+[[beans-factory-properties-detailed]]
+= Dependencies and Configuration in Detail
+
+As mentioned in the xref:core/beans/dependencies/factory-collaborators.adoc[previous section], you can define bean
+properties and constructor arguments as references to other managed beans (collaborators)
+or as values defined inline. Spring's XML-based configuration metadata supports
+sub-element types within its `` and `` elements for this
+purpose.
+
+
+[[beans-value-element]]
+== Straight Values (Primitives, Strings, and so on)
+
+The `value` attribute of the `` element specifies a property or constructor
+argument as a human-readable string representation. Spring's
+xref:core/validation/convert.adoc#core-convert-ConversionService-API[conversion service] is used to convert these
+values from a `String` to the actual type of the property or argument.
+The following example shows various values being set:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+The following example uses the xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-p-namespace[p-namespace] for even more succinct
+XML configuration:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+----
+
+The preceding XML is more succinct. However, typos are discovered at runtime rather than
+design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ
+IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])
+that supports automatic property completion when you create bean definitions. Such IDE
+assistance is highly recommended.
+
+You can also configure a `java.util.Properties` instance, as follows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+ jdbc.driver.className=com.mysql.jdbc.Driver
+ jdbc.url=jdbc:mysql://localhost:3306/mydb
+
+
+
+----
+
+The Spring container converts the text inside the `` element into a
+`java.util.Properties` instance by using the JavaBeans `PropertyEditor` mechanism. This
+is a nice shortcut, and is one of a few places where the Spring team do favor the use of
+the nested `` element over the `value` attribute style.
+
+[[beans-idref-element]]
+=== The `idref` element
+
+The `idref` element is simply an error-proof way to pass the `id` (a string value - not
+a reference) of another bean in the container to a `` or ``
+element. The following example shows how to use it:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+The preceding bean definition snippet is exactly equivalent (at runtime) to the
+following snippet:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+----
+
+The first form is preferable to the second, because using the `idref` tag lets the
+container validate at deployment time that the referenced, named bean actually
+exists. In the second variation, no validation is performed on the value that is passed
+to the `targetName` property of the `client` bean. Typos are only discovered (with most
+likely fatal results) when the `client` bean is actually instantiated. If the `client`
+bean is a xref:core/beans/factory-scopes.adoc[prototype] bean, this typo and the resulting exception
+may only be discovered long after the container is deployed.
+
+NOTE: The `local` attribute on the `idref` element is no longer supported in the 4.0 beans
+XSD, since it does not provide value over a regular `bean` reference any more. Change
+your existing `idref local` references to `idref bean` when upgrading to the 4.0 schema.
+
+A common place (at least in versions earlier than Spring 2.0) where the `` element
+brings value is in the configuration of xref:core/aop-api/pfb.adoc#aop-pfb-1[AOP interceptors] in a
+`ProxyFactoryBean` bean definition. Using `` elements when you specify the
+interceptor names prevents you from misspelling an interceptor ID.
+
+
+[[beans-ref-element]]
+== References to Other Beans (Collaborators)
+
+The `ref` element is the final element inside a `` or ``
+definition element. Here, you set the value of the specified property of a bean to be a
+reference to another bean (a collaborator) managed by the container. The referenced bean
+is a dependency of the bean whose property is to be set, and it is initialized on demand
+as needed before the property is set. (If the collaborator is a singleton bean, it may
+already be initialized by the container.) All references are ultimately a reference to
+another object. Scoping and validation depend on whether you specify the ID or name of the
+other object through the `bean` or `parent` attribute.
+
+Specifying the target bean through the `bean` attribute of the `` tag is the most
+general form and allows creation of a reference to any bean in the same container or
+parent container, regardless of whether it is in the same XML file. The value of the
+`bean` attribute may be the same as the `id` attribute of the target bean or be the same
+as one of the values in the `name` attribute of the target bean. The following example
+shows how to use a `ref` element:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+Specifying the target bean through the `parent` attribute creates a reference to a bean
+that is in a parent container of the current container. The value of the `parent`
+attribute may be the same as either the `id` attribute of the target bean or one of the
+values in the `name` attribute of the target bean. The target bean must be in a
+parent container of the current one. You should use this bean reference variant mainly
+when you have a hierarchy of containers and you want to wrap an existing bean in a parent
+container with a proxy that has the same name as the parent bean. The following pair of
+listings shows how to use the `parent` attribute:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+ class="org.springframework.aop.framework.ProxyFactoryBean">
+
+
+
+
+
+----
+
+NOTE: The `local` attribute on the `ref` element is no longer supported in the 4.0 beans
+XSD, since it does not provide value over a regular `bean` reference any more. Change
+your existing `ref local` references to `ref bean` when upgrading to the 4.0 schema.
+
+
+[[beans-inner-beans]]
+== Inner Beans
+
+A `` element inside the `` or `` elements defines an
+inner bean, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+----
+
+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, because inner beans are always anonymous and are always created with the outer
+bean. It is not possible to access inner beans independently or to inject them into
+collaborating beans other than into the enclosing bean.
+
+As a corner case, it is possible to receive destruction callbacks from a custom scope --
+for example, for a request-scoped inner bean contained within a singleton bean. The creation
+of the inner bean instance is tied to its containing bean, but destruction callbacks let it
+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]]
+== Collections
+
+The `
`, ``, ``, and `` elements set the properties
+and arguments of the Java `Collection` types `List`, `Set`, `Map`, and `Properties`,
+respectively. The following example shows how to use them:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+ administrator@example.org
+ support@example.org
+ development@example.org
+
+
+
+
+
+ a list element followed by a reference
+
+
+
+
+
+
+
+
+
+
+ just some string
+
+
+
+
+----
+
+The value of a map key or value, or a set value, can also be any of the
+following elements:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+ bean | ref | idref | list | set | map | props | value | null
+----
+
+[[beans-collection-elements-merging]]
+=== Collection Merging
+
+The Spring container also supports merging collections. An application
+developer can define a parent `
`, ``, `` or `` element
+and have child `
`, ``, `` or `` elements inherit and
+override values from the parent collection. That is, the child collection's values are
+the result of merging the elements of the parent and child collections, with the child's
+collection elements overriding values specified in the parent collection.
+
+This section on merging discusses the parent-child bean mechanism. Readers unfamiliar
+with parent and child bean definitions may wish to read the
+xref:core/beans/child-bean-definitions.adoc[relevant section] before continuing.
+
+The following example demonstrates collection merging:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+ administrator@example.com
+ support@example.com
+
+
+
+
+
+
+
+ sales@example.com
+ support@example.co.uk
+
+
+
+
+----
+
+Notice the use of the `merge=true` attribute on the `` element of the
+`adminEmails` property of the `child` bean definition. When the `child` bean is resolved
+and instantiated by the container, the resulting instance has an `adminEmails`
+`Properties` collection that contains the result of merging the child's
+`adminEmails` collection with the parent's `adminEmails` collection. The following listing
+shows the result:
+
+[literal,subs="verbatim,quotes"]
+----
+administrator=administrator@example.com
+sales=sales@example.com
+support=support@example.co.uk
+----
+
+The child `Properties` collection's value set inherits all property elements from the
+parent ``, and the child's value for the `support` value overrides the value in
+the parent collection.
+
+This merging behavior applies similarly to the `
`, ``, and ``
+collection types. In the specific case of the `
` element, the semantics
+associated with the `List` collection type (that is, the notion of an `ordered`
+collection of values) is maintained. The parent's values precede all of the child list's
+values. In the case of the `Map`, `Set`, and `Properties` collection types, no ordering
+exists. Hence, no ordering semantics are in effect for the collection types that underlie
+the associated `Map`, `Set`, and `Properties` implementation types that the container
+uses internally.
+
+[[beans-collection-merge-limitations]]
+=== Limitations of Collection Merging
+
+You cannot merge different collection types (such as a `Map` and a `List`). If you
+do attempt to do so, an appropriate `Exception` is thrown. The `merge` attribute must be
+specified on the lower, inherited, child definition. Specifying the `merge` attribute on
+a parent collection definition is redundant and does not result in the desired merging.
+
+[[beans-collection-elements-strongly-typed]]
+=== Strongly-typed collection
+
+Thanks to Java's support for generic types, you can use strongly typed collections.
+That is, it is possible to declare a `Collection` type such that it can only contain
+(for example) `String` elements. If you use Spring to dependency-inject a
+strongly-typed `Collection` into a bean, you can take advantage of Spring's
+type-conversion support such that the elements of your strongly-typed `Collection`
+instances are converted to the appropriate type prior to being added to the `Collection`.
+The following Java class and bean definition show how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class SomeClass {
+
+ private Map accounts;
+
+ public void setAccounts(Map accounts) {
+ this.accounts = accounts;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+class SomeClass {
+ lateinit var accounts: Map
+}
+----
+======
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+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
+`3.99`) are converted into an actual `Float` type.
+
+
+[[beans-null-element]]
+== Null and Empty String Values
+
+Spring treats empty arguments for properties and the like as empty `Strings`. The
+following XML-based configuration metadata snippet sets the `email` property to the empty
+`String` value ("").
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+The preceding example is equivalent to the following Java code:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ exampleBean.setEmail("");
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ exampleBean.email = ""
+----
+======
+
+
+The `` element handles `null` values. The following listing shows an example:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+----
+
+The preceding configuration is equivalent to the following Java code:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ exampleBean.setEmail(null);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ exampleBean.email = null
+----
+======
+
+
+[[beans-p-namespace]]
+== XML Shortcut with the p-namespace
+
+The p-namespace lets you use the `bean` element's attributes (instead of nested
+`` elements) to describe your property values collaborating beans, or both.
+
+Spring supports extensible configuration formats xref:core/appendix/xsd-schemas.adoc[with namespaces],
+which are based on an XML Schema definition. The `beans` configuration format discussed in
+this chapter is defined in an XML Schema document. However, the p-namespace is not defined
+in an XSD file and exists only in the core of Spring.
+
+The following example shows two XML snippets (the first uses
+standard XML format and the second uses the p-namespace) that resolve to the same result:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+----
+
+The example shows an attribute in the p-namespace called `email` in the bean definition.
+This tells Spring to include a property declaration. As previously mentioned, the
+p-namespace does not have a schema definition, so you can set the name of the attribute
+to the property name.
+
+This next example includes two more bean definitions that both have a reference to
+another bean:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+This example includes not only a property value using the p-namespace
+but also uses a special format to declare property references. Whereas the first bean
+definition uses `` to create a reference from bean
+`john` to bean `jane`, the second bean definition uses `p:spouse-ref="jane"` as an
+attribute to do the exact same thing. In this case, `spouse` is the property name,
+whereas the `-ref` part indicates that this is not a straight value but rather a
+reference to another bean.
+
+NOTE: The p-namespace is not as flexible as the standard XML format. For example, the format
+for declaring property references clashes with properties that end in `Ref`, whereas the
+standard XML format does not. We recommend that you choose your approach carefully and
+communicate this to your team members to avoid producing XML documents that use all
+three approaches at the same time.
+
+
+[[beans-c-namespace]]
+== XML Shortcut with the c-namespace
+
+Similar to the xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-p-namespace[XML Shortcut with the p-namespace], the c-namespace, introduced in Spring
+3.1, allows inlined attributes for configuring the constructor arguments rather
+then nested `constructor-arg` elements.
+
+The following example uses the `c:` namespace to do the same thing as the from
+xref:core/beans/dependencies/factory-collaborators.adoc#beans-constructor-injection[Constructor-based Dependency Injection]:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+The `c:` namespace uses the same conventions as the `p:` one (a trailing `-ref` for
+bean references) for setting the constructor arguments by their names. Similarly,
+it needs to be declared in the XML file even though it is not defined in an XSD schema
+(it exists inside the Spring core).
+
+For the rare cases where the constructor argument names are not available (usually if
+the bytecode was compiled without debugging information), you can use fallback to the
+argument indexes, as follows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+----
+
+NOTE: Due to the XML grammar, the index notation requires the presence of the leading `_`,
+as XML attribute names cannot start with a number (even though some IDEs allow it).
+A corresponding index notation is also available for `` elements but
+not commonly used since the plain order of declaration is usually sufficient there.
+
+In practice, the constructor resolution
+xref:core/beans/dependencies/factory-collaborators.adoc#beans-factory-ctor-arguments-resolution[mechanism] is quite efficient in matching
+arguments, so unless you really need to, we recommend using the name notation
+throughout your configuration.
+
+
+[[beans-compound-property-names]]
+== Compound Property Names
+
+You can use compound or nested property names when you set bean properties, as long as
+all components of the path except the final property name are not `null`. Consider the
+following bean definition:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+The `something` bean has a `fred` property, which has a `bob` property, which has a `sammy`
+property, and that final `sammy` property is being set to a value of `123`. In order for
+this to work, the `fred` property of `something` and the `bob` property of `fred` must not
+be `null` after the bean is constructed. Otherwise, a `NullPointerException` is thrown.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc
new file mode 100644
index 000000000000..441fdb49b56b
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc
@@ -0,0 +1,803 @@
+[[beans-environment]]
+= Environment Abstraction
+
+The {api-spring-framework}/core/env/Environment.html[`Environment`] interface
+is an abstraction integrated in the container that models two key
+aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]
+and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].
+
+A profile is a named, logical group of bean definitions to be registered with the
+container only if the given profile is active. Beans may be assigned to a profile
+whether defined in XML or with annotations. The role of the `Environment` object with
+relation to profiles is in determining which profiles (if any) are currently active,
+and which profiles (if any) should be active by default.
+
+Properties play an important role in almost all applications and may originate from
+a variety of sources: properties files, JVM system properties, system environment
+variables, JNDI, servlet context parameters, ad-hoc `Properties` objects, `Map` objects, and so
+on. The role of the `Environment` object with relation to properties is to provide the
+user with a convenient service interface for configuring property sources and resolving
+properties from them.
+
+
+
+[[beans-definition-profiles]]
+== Bean Definition Profiles
+
+Bean definition profiles provide a mechanism in the core container that allows for
+registration of different beans in different environments. The word, "`environment,`"
+can mean different things to different users, and this feature can help with many
+use cases, including:
+
+* Working against an in-memory datasource in development versus looking up that same
+datasource from JNDI when in QA or production.
+* Registering monitoring infrastructure only when deploying an application into a
+performance environment.
+* Registering customized implementations of beans for customer A versus customer
+B deployments.
+
+Consider the first use case in a practical application that requires a
+`DataSource`. In a test environment, the configuration might resemble the following:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("my-schema.sql")
+ .addScript("my-test-data.sql")
+ .build();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Bean
+ fun dataSource(): DataSource {
+ return EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("my-schema.sql")
+ .addScript("my-test-data.sql")
+ .build()
+ }
+----
+======
+
+Now consider how this application can be deployed into a QA or production
+environment, assuming that the datasource for the application is registered
+with the production application server's JNDI directory. Our `dataSource` bean
+now looks like the following listing:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Bean(destroyMethod = "")
+ public DataSource dataSource() throws Exception {
+ Context ctx = new InitialContext();
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Bean(destroyMethod = "")
+ fun dataSource(): DataSource {
+ val ctx = InitialContext()
+ return ctx.lookup("java:comp/env/jdbc/datasource") as DataSource
+ }
+----
+======
+
+The problem is how to switch between using these two variations based on the
+current environment. Over time, Spring users have devised a number of ways to
+get this done, usually relying on a combination of system environment variables
+and XML `` statements containing pass:q[`${placeholder}`] tokens that resolve
+to the correct configuration file path depending on the value of an environment
+variable. Bean definition profiles is a core container feature that provides a
+solution to this problem.
+
+If we generalize the use case shown in the preceding example of environment-specific bean
+definitions, we end up with the need to register certain bean definitions in
+certain contexts but not in others. You could say that you want to register a
+certain profile of bean definitions in situation A and a different profile in
+situation B. We start by updating our configuration to reflect this need.
+
+
+[[beans-definition-profiles-java]]
+=== Using `@Profile`
+
+The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]
+annotation lets you indicate that a component is eligible for registration
+when one or more specified profiles are active. Using our preceding example, we
+can rewrite the `dataSource` configuration as follows:
+
+--
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @Profile("development")
+ public class StandaloneDataConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
+ .build();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @Profile("development")
+ class StandaloneDataConfig {
+
+ @Bean
+ fun dataSource(): DataSource {
+ return EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
+ .build()
+ }
+ }
+----
+======
+--
+
+--
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @Profile("production")
+ public class JndiDataConfig {
+
+ @Bean(destroyMethod = "") // <1>
+ public DataSource dataSource() throws Exception {
+ Context ctx = new InitialContext();
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
+ }
+ }
+----
+======
+<1> `@Bean(destroyMethod = "")` disables default destroy method inference.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ @Configuration
+ @Profile("production")
+ class JndiDataConfig {
+
+ @Bean(destroyMethod = "") // <1>
+ fun dataSource(): DataSource {
+ val ctx = InitialContext()
+ return ctx.lookup("java:comp/env/jdbc/datasource") as DataSource
+ }
+ }
+----
+<1> `@Bean(destroyMethod = "")` disables default destroy method inference.
+--
+
+NOTE: As mentioned earlier, with `@Bean` methods, you typically choose to use programmatic
+JNDI lookups, by using either Spring's `JndiTemplate`/`JndiLocatorDelegate` helpers or the
+straight JNDI `InitialContext` usage shown earlier but not the `JndiObjectFactoryBean`
+variant, which would force you to declare the return type as the `FactoryBean` type.
+
+The profile string may contain a simple profile name (for example, `production`) or a
+profile expression. A profile expression allows for more complicated profile logic to be
+expressed (for example, `production & us-east`). The following operators are supported in
+profile expressions:
+
+* `!`: A logical `NOT` of the profile
+* `&`: A logical `AND` of the profiles
+* `|`: A logical `OR` of the profiles
+
+NOTE: You cannot mix the `&` and `|` operators without using parentheses. For example,
+`production & us-east | eu-central` is not a valid expression. It must be expressed as
+`production & (us-east | eu-central)`.
+
+You can use `@Profile` as a xref:core/beans/classpath-scanning.adoc#beans-meta-annotations[meta-annotation] for the purpose
+of creating a custom composed annotation. The following example defines a custom
+`@Production` annotation that you can use as a drop-in replacement for
+`@Profile("production")`:
+
+--
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Target(ElementType.TYPE)
+ @Retention(RetentionPolicy.RUNTIME)
+ @Profile("production")
+ public @interface Production {
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Target(AnnotationTarget.CLASS)
+ @Retention(AnnotationRetention.RUNTIME)
+ @Profile("production")
+ annotation class Production
+----
+======
+--
+
+TIP: If a `@Configuration` class is marked with `@Profile`, all of the `@Bean` methods and
+`@Import` annotations associated with that class are bypassed unless one or more of
+the specified profiles are active. If a `@Component` or `@Configuration` class is marked
+with `@Profile({"p1", "p2"})`, that class is not registered or processed unless
+profiles 'p1' or 'p2' have been activated. If a given profile is prefixed with the
+NOT operator (`!`), the annotated element is registered only if the profile is not
+active. For example, given `@Profile({"p1", "!p2"})`, registration will occur if profile
+'p1' is active or if profile 'p2' is not active.
+
+`@Profile` can also be declared at the method level to include only one particular bean
+of a configuration class (for example, for alternative variants of a particular bean), as
+the following example shows:
+
+--
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean("dataSource")
+ @Profile("development") // <1>
+ public DataSource standaloneDataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
+ .build();
+ }
+
+ @Bean("dataSource")
+ @Profile("production") // <2>
+ public DataSource jndiDataSource() throws Exception {
+ Context ctx = new InitialContext();
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
+ }
+ }
+----
+======
+<1> The `standaloneDataSource` method is available only in the `development` profile.
+<2> The `jndiDataSource` method is available only in the `production` profile.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean("dataSource")
+ @Profile("development") // <1>
+ fun standaloneDataSource(): DataSource {
+ return EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
+ .build()
+ }
+
+ @Bean("dataSource")
+ @Profile("production") // <2>
+ fun jndiDataSource() =
+ InitialContext().lookup("java:comp/env/jdbc/datasource") as DataSource
+ }
+----
+<1> The `standaloneDataSource` method is available only in the `development` profile.
+<2> The `jndiDataSource` method is available only in the `production` profile.
+--
+
+[NOTE]
+====
+With `@Profile` on `@Bean` methods, a special scenario may apply: In the case of
+overloaded `@Bean` methods of the same Java method name (analogous to constructor
+overloading), a `@Profile` condition needs to be consistently declared on all
+overloaded methods. If the conditions are inconsistent, only the condition on the
+first declaration among the overloaded methods matters. Therefore, `@Profile` can
+not be used to select an overloaded method with a particular argument signature over
+another. Resolution between all factory methods for the same bean follows Spring's
+constructor resolution algorithm at creation time.
+
+If you want to define alternative beans with different profile conditions,
+use distinct Java method names that point to the same bean name by using the `@Bean` name
+attribute, as shown in the preceding example. If the argument signatures are all
+the same (for example, all of the variants have no-arg factory methods), this is the only
+way to represent such an arrangement in a valid Java class in the first place
+(since there can only be one method of a particular name and argument signature).
+====
+
+
+[[beans-definition-profiles-xml]]
+=== XML Bean Definition Profiles
+
+The XML counterpart is the `profile` attribute of the `` element. Our preceding sample
+configuration can be rewritten in two XML files, as follows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+
+It is also possible to avoid that split and nest `` elements within the same file,
+as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+The `spring-bean.xsd` has been constrained to allow such elements only as the
+last ones in the file. This should help provide flexibility without incurring
+clutter in the XML files.
+
+[NOTE]
+=====
+The XML counterpart does not support the profile expressions described earlier. It is possible,
+however, to negate a profile by using the `!` operator. It is also possible to apply a logical
+"`and`" by nesting the profiles, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+----
+
+In the preceding example, the `dataSource` bean is exposed if both the `production` and
+`us-east` profiles are active.
+=====
+
+
+[[beans-definition-profiles-enable]]
+=== Activating a Profile
+
+Now that we have updated our configuration, we still need to instruct Spring which
+profile is active. If we started our sample application right now, we would see
+a `NoSuchBeanDefinitionException` thrown, because the container could not find
+the Spring bean named `dataSource`.
+
+Activating a profile can be done in several ways, but the most straightforward is to do
+it programmatically against the `Environment` API which is available through an
+`ApplicationContext`. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.getEnvironment().setActiveProfiles("development");
+ ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
+ ctx.refresh();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val ctx = AnnotationConfigApplicationContext().apply {
+ environment.setActiveProfiles("development")
+ register(SomeConfig::class.java, StandaloneDataConfig::class.java, JndiDataConfig::class.java)
+ refresh()
+ }
+----
+======
+
+In addition, you can also declaratively activate profiles through the
+`spring.profiles.active` property, which may be specified through system environment
+variables, JVM system properties, servlet context parameters in `web.xml`, or even as an
+entry in JNDI (see xref:core/beans/environment.adoc#beans-property-source-abstraction[`PropertySource` Abstraction]). In integration tests, active
+profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test`
+module (see xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[context configuration with environment profiles]
+).
+
+Note that profiles are not an "`either-or`" proposition. You can activate multiple
+profiles at once. Programmatically, you can provide multiple profile names to the
+`setActiveProfiles()` method, which accepts `String...` varargs. The following example
+activates multiple profiles:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ctx.getEnvironment().setActiveProfiles("profile1", "profile2");
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ ctx.getEnvironment().setActiveProfiles("profile1", "profile2")
+----
+======
+
+Declaratively, `spring.profiles.active` may accept a comma-separated list of profile names,
+as the following example shows:
+
+[literal,indent=0,subs="verbatim,quotes"]
+----
+ -Dspring.profiles.active="profile1,profile2"
+----
+
+
+[[beans-definition-profiles-default]]
+=== Default Profile
+
+The default profile represents the profile that is enabled by default. Consider the
+following example:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @Profile("default")
+ public class DefaultDataConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .build();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @Profile("default")
+ class DefaultDataConfig {
+
+ @Bean
+ fun dataSource(): DataSource {
+ return EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .build()
+ }
+ }
+----
+======
+
+If no profile is active, the `dataSource` is created. You can see this
+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.
+
+
+
+[[beans-property-source-abstraction]]
+== `PropertySource` Abstraction
+
+Spring's `Environment` abstraction provides search operations over a configurable
+hierarchy of property sources. Consider the following listing:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ApplicationContext ctx = new GenericApplicationContext();
+ Environment env = ctx.getEnvironment();
+ boolean containsMyProperty = env.containsProperty("my-property");
+ System.out.println("Does my environment contain the 'my-property' property? " + containsMyProperty);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val ctx = GenericApplicationContext()
+ val env = ctx.environment
+ val containsMyProperty = env.containsProperty("my-property")
+ println("Does my environment contain the 'my-property' property? $containsMyProperty")
+----
+======
+
+In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is
+defined for the current environment. To answer this question, the `Environment` object performs
+a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]
+objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and
+Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]
+is configured with two PropertySource objects -- one representing the set of JVM system properties
+(`System.getProperties()`) and one representing the set of system environment variables
+(`System.getenv()`).
+
+NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone
+applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]
+is populated with additional default property sources including servlet config, servlet
+context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]
+if JNDI is available.
+
+Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty("my-property")`
+returns true if a `my-property` system property or `my-property` environment variable is present at
+runtime.
+
+[TIP]
+====
+The search performed is hierarchical. By default, system properties have precedence over
+environment variables. So, if the `my-property` property happens to be set in both places during
+a call to `env.getProperty("my-property")`, the system property value "`wins`" and is returned.
+Note that property values are not merged
+but rather completely overridden by a preceding entry.
+
+For a common `StandardServletEnvironment`, the full hierarchy is as follows, with the
+highest-precedence entries at the top:
+
+. ServletConfig parameters (if applicable -- for example, in case of a `DispatcherServlet` context)
+. ServletContext parameters (web.xml context-param entries)
+. JNDI environment variables (`java:comp/env/` entries)
+. JVM system properties (`-D` command-line arguments)
+. JVM system environment (operating system environment variables)
+====
+
+Most importantly, the entire mechanism is configurable. Perhaps you have a custom source
+of properties that you want to integrate into this search. To do so, implement
+and instantiate your own `PropertySource` and add it to the set of `PropertySources` for the
+current `Environment`. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ConfigurableApplicationContext ctx = new GenericApplicationContext();
+MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
+sources.addFirst(new MyPropertySource());
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val ctx = GenericApplicationContext()
+ val sources = ctx.environment.propertySources
+ sources.addFirst(MyPropertySource())
+----
+======
+
+In the preceding code, `MyPropertySource` has been added with highest precedence in the
+search. If it contains a `my-property` property, the property is detected and returned, in favor of
+any `my-property` property in any other `PropertySource`. The
+{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]
+API exposes a number of methods that allow for precise manipulation of the set of
+property sources.
+
+
+
+[[beans-using-propertysource]]
+== Using `@PropertySource`
+
+The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]
+annotation provides a convenient and declarative mechanism for adding a `PropertySource`
+to Spring's `Environment`.
+
+Given a file called `app.properties` that contains the key-value pair `testbean.name=myTestBean`,
+the following `@Configuration` class uses `@PropertySource` in such a way that
+a call to `testBean.getName()` returns `myTestBean`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @PropertySource("classpath:/com/myco/app.properties")
+ public class AppConfig {
+
+ @Autowired
+ Environment env;
+
+ @Bean
+ public TestBean testBean() {
+ TestBean testBean = new TestBean();
+ testBean.setName(env.getProperty("testbean.name"));
+ return testBean;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @PropertySource("classpath:/com/myco/app.properties")
+ class AppConfig {
+
+ @Autowired
+ private lateinit var env: Environment
+
+ @Bean
+ fun testBean() = TestBean().apply {
+ name = env.getProperty("testbean.name")!!
+ }
+ }
+----
+======
+
+Any `${...}` placeholders present in a `@PropertySource` resource location are
+resolved against the set of property sources already registered against the
+environment, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
+ public class AppConfig {
+
+ @Autowired
+ Environment env;
+
+ @Bean
+ public TestBean testBean() {
+ TestBean testBean = new TestBean();
+ testBean.setName(env.getProperty("testbean.name"));
+ return testBean;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @PropertySource("classpath:/com/\${my.placeholder:default/path}/app.properties")
+ class AppConfig {
+
+ @Autowired
+ private lateinit var env: Environment
+
+ @Bean
+ fun testBean() = TestBean().apply {
+ name = env.getProperty("testbean.name")!!
+ }
+ }
+----
+======
+
+Assuming that `my.placeholder` is present in one of the property sources already
+registered (for example, system properties or environment variables), the placeholder is
+resolved to the corresponding value. If not, then `default/path` is used
+as a default. If no default is specified and a property cannot be resolved, an
+`IllegalArgumentException` is thrown.
+
+NOTE: The `@PropertySource` annotation is repeatable, according to Java 8 conventions.
+However, all such `@PropertySource` annotations need to be declared at the same
+level, either directly on the configuration class or as meta-annotations within the
+same custom annotation. Mixing direct annotations and meta-annotations is not
+recommended, since direct annotations effectively override meta-annotations.
+
+
+
+[[beans-placeholder-resolution-in-statements]]
+== Placeholder Resolution in Statements
+
+Historically, the value of placeholders in elements could be resolved only against
+JVM system properties or environment variables. This is no longer the case. Because
+the `Environment` abstraction is integrated throughout the container, it is easy to
+route resolution of placeholders through it. This means that you may configure the
+resolution process in any way you like. You can change the precedence of searching through
+system properties and environment variables or remove them entirely. You can also add your
+own property sources to the mix, as appropriate.
+
+Concretely, the following statement works regardless of where the `customer`
+property is defined, as long as it is available in the `Environment`:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc
new file mode 100644
index 000000000000..6882cdb7add1
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc
@@ -0,0 +1,493 @@
+[[beans-factory-extension]]
+= Container Extension Points
+
+Typically, an application developer does not need to subclass `ApplicationContext`
+implementation classes. Instead, the Spring IoC container can be extended by plugging in
+implementations of special integration interfaces. The next few sections describe these
+integration interfaces.
+
+
+
+[[beans-factory-extension-bpp]]
+== Customizing Beans by Using a `BeanPostProcessor`
+
+The `BeanPostProcessor` interface defines callback methods that you can implement to
+provide your own (or override the container's default) instantiation logic, dependency
+resolution logic, and so forth. If you want to implement some custom logic after the
+Spring container finishes instantiating, configuring, and initializing a bean, you can
+plug in one or more custom `BeanPostProcessor` implementations.
+
+You can configure multiple `BeanPostProcessor` instances, and you can control the order
+in which these `BeanPostProcessor` instances run by setting the `order` property.
+You can set this property only if the `BeanPostProcessor` implements the `Ordered`
+interface. If you write your own `BeanPostProcessor`, you should consider implementing
+the `Ordered` interface, too. For further details, see the javadoc of the
+{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]
+and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note
+on xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances]
+.
+
+[NOTE]
+====
+`BeanPostProcessor` instances operate on bean (or object) instances. That is,
+the Spring IoC container instantiates a bean instance and then `BeanPostProcessor`
+instances do their work.
+
+`BeanPostProcessor` instances are scoped per-container. This is relevant only if you
+use container hierarchies. If you define a `BeanPostProcessor` in one container,
+it post-processes only the beans in that container. In other words, beans that are
+defined in one container are not post-processed by a `BeanPostProcessor` defined in
+another container, even if both containers are part of the same hierarchy.
+
+To change the actual bean definition (that is, the blueprint that defines the bean),
+you instead need to use a `BeanFactoryPostProcessor`, as described in
+xref:core/beans/factory-extension.adoc#beans-factory-extension-factory-postprocessors[Customizing Configuration Metadata with a `BeanFactoryPostProcessor`].
+====
+
+The `org.springframework.beans.factory.config.BeanPostProcessor` interface consists of
+exactly two callback methods. When such a class is registered as a post-processor with
+the container, for each bean instance that is created by the container, the
+post-processor gets a callback from the container both before container
+initialization methods (such as `InitializingBean.afterPropertiesSet()` or any
+declared `init` method) are called, and after any bean initialization callbacks.
+The post-processor can take any action with the bean instance, including ignoring the
+callback completely. A bean post-processor typically checks for callback interfaces,
+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 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.
+
+Note that, when declaring a `BeanPostProcessor` by using an `@Bean` factory method on a
+configuration class, the return type of the factory method should be the implementation
+class itself or at least the `org.springframework.beans.factory.config.BeanPostProcessor`
+interface, clearly indicating the post-processor nature of that bean. Otherwise, the
+`ApplicationContext` cannot autodetect it by type before fully creating it.
+Since a `BeanPostProcessor` needs to be instantiated early in order to apply to the
+initialization of other beans in the context, this early type detection is critical.
+
+[[beans-factory-programmatically-registering-beanpostprocessors]]
+.Programmatically registering `BeanPostProcessor` instances
+NOTE: While the recommended approach for `BeanPostProcessor` registration is through
+`ApplicationContext` auto-detection (as described earlier), you can register them
+programmatically against a `ConfigurableBeanFactory` by using the `addBeanPostProcessor`
+method. This can be useful when you need to evaluate conditional logic before
+registration or even for copying bean post processors across contexts in a hierarchy.
+Note, however, that `BeanPostProcessor` instances added programmatically do not respect
+the `Ordered` interface. Here, it is the order of registration that dictates the order
+of execution. Note also that `BeanPostProcessor` instances registered programmatically
+are always processed before those registered through auto-detection, regardless of any
+explicit ordering.
+
+.`BeanPostProcessor` instances and AOP auto-proxying
+[NOTE]
+====
+Classes that implement the `BeanPostProcessor` interface are special and are treated
+differently by the container. All `BeanPostProcessor` instances and beans that they
+directly reference are instantiated on startup, as part of the special startup phase
+of the `ApplicationContext`. Next, all `BeanPostProcessor` instances are registered
+in a sorted fashion and applied to all further beans in the container. Because AOP
+auto-proxying is implemented as a `BeanPostProcessor` itself, neither `BeanPostProcessor`
+instances nor the beans they directly reference are eligible for auto-proxying and,
+thus, do not have aspects woven into them.
+
+For any such bean, you should see an informational log message: `Bean someBean is not
+eligible for getting processed by all BeanPostProcessor interfaces (for example: not
+eligible for auto-proxying)`.
+
+If you have beans wired into your `BeanPostProcessor` by using autowiring or
+`@Resource` (which may fall back to autowiring), Spring might access unexpected beans
+when searching for type-matching dependency candidates and, therefore, make them
+ineligible for auto-proxying or other kinds of bean post-processing. For example, if you
+have a dependency annotated with `@Resource` where the field or setter name does not
+directly correspond to the declared name of a bean and no name attribute is used,
+Spring accesses other beans for matching them by type.
+====
+
+The following examples show how to write, register, and use `BeanPostProcessor` instances
+in an `ApplicationContext`.
+
+
+[[beans-factory-extension-bpp-examples-hw]]
+=== Example: Hello World, `BeanPostProcessor`-style
+
+This first example illustrates basic usage. The example shows a custom
+`BeanPostProcessor` implementation that invokes the `toString()` method of each bean as
+it is created by the container and prints the resulting string to the system console.
+
+The following listing shows the custom `BeanPostProcessor` implementation class definition:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package scripting;
+
+ import org.springframework.beans.factory.config.BeanPostProcessor;
+
+ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {
+
+ // simply return the instantiated bean as-is
+ public Object postProcessBeforeInitialization(Object bean, String beanName) {
+ return bean; // we could potentially return any object reference here...
+ }
+
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ System.out.println("Bean '" + beanName + "' created : " + bean.toString());
+ return bean;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package scripting
+
+ import org.springframework.beans.factory.config.BeanPostProcessor
+
+ class InstantiationTracingBeanPostProcessor : BeanPostProcessor {
+
+ // simply return the instantiated bean as-is
+ override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any? {
+ return bean // we could potentially return any object reference here...
+ }
+
+ override fun postProcessAfterInitialization(bean: Any, beanName: String): Any? {
+ println("Bean '$beanName' created : $bean")
+ return bean
+ }
+ }
+----
+======
+
+The following `beans` element uses the `InstantiationTracingBeanPostProcessor`:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+----
+
+Notice how the `InstantiationTracingBeanPostProcessor` is merely defined. It does not
+even have a name, and, because it is a bean, it can be dependency-injected as you would any
+other bean. (The preceding configuration also defines a bean that is backed by a Groovy
+script. The Spring dynamic language support is detailed in the chapter entitled
+xref:languages/dynamic.adoc[Dynamic Language Support].)
+
+The following Java application runs the preceding code and configuration:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import org.springframework.context.ApplicationContext;
+ import org.springframework.context.support.ClassPathXmlApplicationContext;
+ import org.springframework.scripting.Messenger;
+
+ public final class Boot {
+
+ public static void main(final String[] args) throws Exception {
+ ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml");
+ Messenger messenger = ctx.getBean("messenger", Messenger.class);
+ System.out.println(messenger);
+ }
+
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ fun main() {
+ val ctx = ClassPathXmlApplicationContext("scripting/beans.xml")
+ val messenger = ctx.getBean("messenger")
+ println(messenger)
+ }
+----
+======
+
+The output of the preceding application resembles the following:
+
+[literal,subs="verbatim,quotes"]
+----
+Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961
+org.springframework.scripting.groovy.GroovyMessenger@272961
+----
+
+
+[[beans-factory-extension-bpp-examples-aabpp]]
+=== Example: The `AutowiredAnnotationBeanPostProcessor`
+
+Using callback interfaces or annotations in conjunction with a custom `BeanPostProcessor`
+implementation is a common means of extending the Spring IoC container. An example is
+Spring's `AutowiredAnnotationBeanPostProcessor` -- a `BeanPostProcessor` implementation
+that ships with the Spring distribution and autowires annotated fields, setter methods,
+and arbitrary config methods.
+
+
+
+[[beans-factory-extension-factory-postprocessors]]
+== Customizing Configuration Metadata with a `BeanFactoryPostProcessor`
+
+The next extension point that we look at is the
+`org.springframework.beans.factory.config.BeanFactoryPostProcessor`. The semantics of
+this interface are similar to those of the `BeanPostProcessor`, with one major
+difference: `BeanFactoryPostProcessor` operates on the bean configuration metadata.
+That is, the Spring IoC container lets a `BeanFactoryPostProcessor` read the
+configuration metadata and potentially change it _before_ the container instantiates
+any beans other than `BeanFactoryPostProcessor` instances.
+
+You can configure multiple `BeanFactoryPostProcessor` instances, and you can control the order in
+which these `BeanFactoryPostProcessor` instances run by setting the `order` property.
+However, you can only set this property if the `BeanFactoryPostProcessor` implements the
+`Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should
+consider implementing the `Ordered` interface, too. See the javadoc of the
+{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]
+and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.
+
+[NOTE]
+====
+If you want to change the actual bean instances (that is, the objects that are created
+from the configuration metadata), then you instead need to use a `BeanPostProcessor`
+(described earlier in xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp[Customizing Beans by Using a `BeanPostProcessor`]). While it is technically possible
+to work with bean instances within a `BeanFactoryPostProcessor` (for example, by using
+`BeanFactory.getBean()`), doing so causes premature bean instantiation, violating the
+standard container lifecycle. This may cause negative side effects, such as bypassing
+bean post processing.
+
+Also, `BeanFactoryPostProcessor` instances are scoped per-container. This is only relevant
+if you use container hierarchies. If you define a `BeanFactoryPostProcessor` in one
+container, it is applied only to the bean definitions in that container. Bean definitions
+in one container are not post-processed by `BeanFactoryPostProcessor` instances in another
+container, even if both containers are part of the same hierarchy.
+====
+
+A bean factory post-processor is automatically run when it is declared inside an
+`ApplicationContext`, in order to apply changes to the configuration metadata that
+define the container. Spring includes a number of predefined bean factory
+post-processors, such as `PropertyOverrideConfigurer` and
+`PropertySourcesPlaceholderConfigurer`. You can also use a custom `BeanFactoryPostProcessor`
+-- for example, to register custom property editors.
+
+An `ApplicationContext` automatically detects any beans that are deployed into it that
+implement the `BeanFactoryPostProcessor` interface. It uses these beans as bean factory
+post-processors, at the appropriate time. You can deploy these post-processor beans as
+you would any other bean.
+
+NOTE: As with ``BeanPostProcessor``s , you typically do not want to configure
+``BeanFactoryPostProcessor``s for lazy initialization. If no other bean references a
+`Bean(Factory)PostProcessor`, that post-processor will not get instantiated at all.
+Thus, marking it for lazy initialization will be ignored, and the
+`Bean(Factory)PostProcessor` will be instantiated eagerly even if you set the
+`default-lazy-init` attribute to `true` on the declaration of your `` element.
+
+
+[[beans-factory-placeholderconfigurer]]
+=== Example: The Class Name Substitution `PropertySourcesPlaceholderConfigurer`
+
+You can use the `PropertySourcesPlaceholderConfigurer` to externalize property values
+from a bean definition in a separate file by using the standard Java `Properties` format.
+Doing so enables the person deploying an application to customize environment-specific
+properties, such as database URLs and passwords, without the complexity or risk of
+modifying the main XML definition file or files for the container.
+
+Consider the following XML-based configuration metadata fragment, where a `DataSource`
+with placeholder values is defined:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+----
+
+The example shows properties configured from an external `Properties` file. At runtime,
+a `PropertySourcesPlaceholderConfigurer` is applied to the metadata that replaces some
+properties of the DataSource. The values to replace are specified as placeholders of the
+form pass:q[`${property-name}`], which follows the Ant and log4j and JSP EL style.
+
+The actual values come from another file in the standard Java `Properties` format:
+
+[literal,subs="verbatim,quotes"]
+----
+jdbc.driverClassName=org.hsqldb.jdbcDriver
+jdbc.url=jdbc:hsqldb:hsql://production:9002
+jdbc.username=sa
+jdbc.password=root
+----
+
+Therefore, the `${jdbc.username}` string is replaced at runtime with the value, 'sa', and
+the same applies for other placeholder values that match keys in the properties file.
+The `PropertySourcesPlaceholderConfigurer` checks for placeholders in most properties and
+attributes of a bean definition. Furthermore, you can customize the placeholder prefix and suffix.
+
+With the `context` namespace introduced in Spring 2.5, you can configure property placeholders
+with a dedicated configuration element. You can provide one or more locations as a
+comma-separated list in the `location` attribute, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+The `PropertySourcesPlaceholderConfigurer` not only looks for properties in the `Properties`
+file you specify. By default, if it cannot find a property in the specified properties files,
+it checks against Spring `Environment` properties and regular Java `System` properties.
+
+[TIP]
+=====
+You can use the `PropertySourcesPlaceholderConfigurer` to substitute class names, which
+is sometimes useful when you have to pick a particular implementation class at runtime.
+The following example shows how to do so:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+ classpath:com/something/strategy.properties
+
+
+ custom.strategy.class=com.something.DefaultStrategy
+
+
+
+
+----
+
+If the class cannot be resolved at runtime to a valid class, resolution of the bean
+fails when it is about to be created, which is during the `preInstantiateSingletons()`
+phase of an `ApplicationContext` for a non-lazy-init bean.
+=====
+
+
+[[beans-factory-overrideconfigurer]]
+=== Example: The `PropertyOverrideConfigurer`
+
+The `PropertyOverrideConfigurer`, another bean factory post-processor, resembles the
+`PropertySourcesPlaceholderConfigurer`, but unlike the latter, the original definitions
+can have default values or no values at all for bean properties. If an overriding
+`Properties` file does not have an entry for a certain bean property, the default
+context definition is used.
+
+Note that the bean definition is not aware of being overridden, so it is not
+immediately obvious from the XML definition file that the override configurer is being
+used. In case of multiple `PropertyOverrideConfigurer` instances that define different
+values for the same bean property, the last one wins, due to the overriding mechanism.
+
+Properties file configuration lines take the following format:
+
+[literal,subs="verbatim,quotes"]
+----
+beanName.property=value
+----
+
+The following listing shows an example of the format:
+
+[literal,subs="verbatim,quotes"]
+----
+dataSource.driverClassName=com.mysql.jdbc.Driver
+dataSource.url=jdbc:mysql:mydb
+----
+
+This example file can be used with a container definition that contains a bean called
+`dataSource` that has `driver` and `url` properties.
+
+Compound property names are also supported, as long as every component of the path
+except the final property being overridden is already non-null (presumably initialized
+by the constructors). In the following example, the `sammy` property of the `bob` property of the `fred` property of the `tom` bean
+is set to the scalar value `123`:
+
+[literal,subs="verbatim,quotes"]
+----
+tom.fred.bob.sammy=123
+----
+
+
+NOTE: Specified override values are always literal values. They are not translated into
+bean references. This convention also applies when the original value in the XML bean
+definition specifies a bean reference.
+
+With the `context` namespace introduced in Spring 2.5, it is possible to configure
+property overriding with a dedicated configuration element, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+
+
+[[beans-factory-extension-factorybean]]
+== Customizing Instantiation Logic with a `FactoryBean`
+
+You can implement the `org.springframework.beans.factory.FactoryBean` interface for objects that
+are themselves factories.
+
+The `FactoryBean` interface is a point of pluggability into the Spring IoC container's
+instantiation logic. If you have complex initialization code that is better expressed in
+Java as opposed to a (potentially) verbose amount of XML, you can create your own
+`FactoryBean`, write the complex initialization inside that class, and then plug your
+custom `FactoryBean` into the container.
+
+The `FactoryBean` interface provides three methods:
+
+* `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. 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 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, 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
+`FactoryBean` instance itself.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc
new file mode 100644
index 000000000000..634ee04486f2
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc
@@ -0,0 +1,679 @@
+[[beans-factory-nature]]
+= Customizing the Nature of a Bean
+
+The Spring Framework provides a number of interfaces you can use to customize the nature
+of a bean. This section groups them as follows:
+
+* xref:core/beans/factory-nature.adoc#beans-factory-lifecycle[Lifecycle Callbacks]
+* xref:core/beans/factory-nature.adoc#beans-factory-aware[`ApplicationContextAware` and `BeanNameAware`]
+* xref:core/beans/factory-nature.adoc#aware-list[Other `Aware` Interfaces]
+
+
+
+[[beans-factory-lifecycle]]
+== Lifecycle Callbacks
+
+To interact with the container's management of the bean lifecycle, you can implement
+the Spring `InitializingBean` and `DisposableBean` interfaces. The container calls
+`afterPropertiesSet()` for the former and `destroy()` for the latter to let the bean
+perform certain actions upon initialization and destruction of your beans.
+
+[TIP]
+====
+The JSR-250 `@PostConstruct` and `@PreDestroy` annotations are generally considered best
+practice for receiving lifecycle callbacks in a modern Spring application. Using these
+annotations means that your beans are not coupled to Spring-specific interfaces.
+For details, see xref:core/beans/annotation-config/postconstruct-and-predestroy-annotations.adoc[Using `@PostConstruct` and `@PreDestroy`].
+
+If you do not want to use the JSR-250 annotations but you still want to remove
+coupling, consider `init-method` and `destroy-method` bean definition metadata.
+====
+
+Internally, the Spring Framework uses `BeanPostProcessor` implementations to process any
+callback interfaces it can find and call the appropriate methods. If you need custom
+features or other lifecycle behavior Spring does not by default offer, you can
+implement a `BeanPostProcessor` yourself. For more information, see
+xref:core/beans/factory-extension.adoc[Container Extension Points].
+
+In addition to the initialization and destruction callbacks, Spring-managed objects may
+also implement the `Lifecycle` interface so that those objects can participate in the
+startup and shutdown process, as driven by the container's own lifecycle.
+
+The lifecycle callback interfaces are described in this section.
+
+
+[[beans-factory-lifecycle-initializingbean]]
+=== Initialization Callbacks
+
+The `org.springframework.beans.factory.InitializingBean` interface lets a bean
+perform initialization work after the container has set all necessary properties on the
+bean. The `InitializingBean` interface specifies a single method:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ void afterPropertiesSet() throws Exception;
+----
+
+We recommend that you do not use the `InitializingBean` interface, because it
+unnecessarily couples the code to Spring. Alternatively, we suggest using
+the xref:core/beans/annotation-config/postconstruct-and-predestroy-annotations.adoc[`@PostConstruct`] annotation or
+specifying a POJO initialization method. In the case of XML-based configuration metadata,
+you can use the `init-method` attribute to specify the name of the method that has a void
+no-argument signature. With Java configuration, you can use the `initMethod` attribute of
+`@Bean`. See xref:core/beans/java/bean-annotation.adoc#beans-java-lifecycle-callbacks[Receiving Lifecycle Callbacks]. Consider the following example:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class ExampleBean {
+
+ public void init() {
+ // do some initialization work
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class ExampleBean {
+
+ fun init() {
+ // do some initialization work
+ }
+ }
+----
+======
+
+The preceding example has almost exactly the same effect as the following example
+(which consists of two listings):
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class AnotherExampleBean implements InitializingBean {
+
+ @Override
+ public void afterPropertiesSet() {
+ // do some initialization work
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class AnotherExampleBean : InitializingBean {
+
+ override fun afterPropertiesSet() {
+ // do some initialization work
+ }
+ }
+----
+======
+
+However, the first of the two preceding examples does not couple the code to Spring.
+
+
+[[beans-factory-lifecycle-disposablebean]]
+=== Destruction Callbacks
+
+Implementing the `org.springframework.beans.factory.DisposableBean` interface lets a
+bean get a callback when the container that contains it is destroyed. The
+`DisposableBean` interface specifies a single method:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ void destroy() throws Exception;
+----
+
+We recommend that you do not use the `DisposableBean` callback interface, because it
+unnecessarily couples the code to Spring. Alternatively, we suggest using
+the xref:core/beans/annotation-config/postconstruct-and-predestroy-annotations.adoc[`@PreDestroy`] annotation or
+specifying a generic method that is supported by bean definitions. With XML-based
+configuration metadata, you can use the `destroy-method` attribute on the ``.
+With Java configuration, you can use the `destroyMethod` attribute of `@Bean`. See
+xref:core/beans/java/bean-annotation.adoc#beans-java-lifecycle-callbacks[Receiving Lifecycle Callbacks]. Consider the following definition:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class ExampleBean {
+
+ public void cleanup() {
+ // do some destruction work (like releasing pooled connections)
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class ExampleBean {
+
+ fun cleanup() {
+ // do some destruction work (like releasing pooled connections)
+ }
+ }
+----
+======
+
+The preceding definition has almost exactly the same effect as the following definition:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class AnotherExampleBean implements DisposableBean {
+
+ @Override
+ public void destroy() {
+ // do some destruction work (like releasing pooled connections)
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class AnotherExampleBean : DisposableBean {
+
+ override fun destroy() {
+ // do some destruction work (like releasing pooled connections)
+ }
+ }
+----
+======
+
+However, the first of the two preceding definitions does not couple the code to Spring.
+
+TIP: You can assign the `destroy-method` attribute of a `` element a special
+`(inferred)` value, which instructs Spring to automatically detect a public `close` or
+`shutdown` method on the specific bean class. (Any class that implements
+`java.lang.AutoCloseable` or `java.io.Closeable` would therefore match.) You can also set
+this special `(inferred)` value on the `default-destroy-method` attribute of a
+`` element to apply this behavior to an entire set of beans (see
+xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-default-init-destroy-methods[Default Initialization and Destroy Methods]). Note that this is the
+default behavior with Java configuration.
+
+[[beans-factory-lifecycle-default-init-destroy-methods]]
+=== Default Initialization and Destroy Methods
+
+When you write initialization and destroy method callbacks that do not use the
+Spring-specific `InitializingBean` and `DisposableBean` callback interfaces, you
+typically write methods with names such as `init()`, `initialize()`, `dispose()`, and so
+on. Ideally, the names of such lifecycle callback methods are standardized across a
+project so that all developers use the same method names and ensure consistency.
+
+You can configure the Spring container to "`look`" for named initialization and destroy
+callback method names on every bean. This means that you, as an application
+developer, can write your application classes and use an initialization callback called
+`init()`, without having to configure an `init-method="init"` attribute with each bean
+definition. The Spring IoC container calls that method when the bean is created (and in
+accordance with the standard lifecycle callback contract xref:core/beans/factory-nature.adoc#beans-factory-lifecycle[described previously]
+). This feature also enforces a consistent naming convention for
+initialization and destroy method callbacks.
+
+Suppose that your initialization callback methods are named `init()` and your destroy
+callback methods are named `destroy()`. Your class then resembles the class in the
+following example:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class DefaultBlogService implements BlogService {
+
+ private BlogDao blogDao;
+
+ public void setBlogDao(BlogDao blogDao) {
+ this.blogDao = blogDao;
+ }
+
+ // this is (unsurprisingly) the initialization callback method
+ public void init() {
+ if (this.blogDao == null) {
+ throw new IllegalStateException("The [blogDao] property must be set.");
+ }
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class DefaultBlogService : BlogService {
+
+ private var blogDao: BlogDao? = null
+
+ // this is (unsurprisingly) the initialization callback method
+ fun init() {
+ if (blogDao == null) {
+ throw IllegalStateException("The [blogDao] property must be set.")
+ }
+ }
+ }
+----
+======
+
+You could then use that class in a bean resembling the following:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+The presence of the `default-init-method` attribute on the top-level `` element
+attribute causes the Spring IoC container to recognize a method called `init` on the bean
+class as the initialization method callback. When a bean is created and assembled, if the
+bean class has such a method, it is invoked at the appropriate time.
+
+You can configure destroy method callbacks similarly (in XML, that is) by using the
+`default-destroy-method` attribute on the top-level `` element.
+
+Where existing bean classes already have callback methods that are named at variance
+with the convention, you can override the default by specifying (in XML, that is) the
+method name by using the `init-method` and `destroy-method` attributes of the ``
+itself.
+
+The Spring container guarantees that a configured initialization callback is called
+immediately after a bean is supplied with all dependencies. Thus, the initialization
+callback is called on the raw bean reference, which means that AOP interceptors and so
+forth are not yet applied to the bean. A target bean is fully created first and
+then an AOP proxy (for example) with its interceptor chain is applied. If the target
+bean and the proxy are defined separately, your code can even interact with the raw
+target bean, bypassing the proxy. Hence, it would be inconsistent to apply the
+interceptors to the `init` method, because doing so would couple the lifecycle of the
+target bean to its proxy or interceptors and leave strange semantics when your code
+interacts directly with the raw target bean.
+
+
+
+[[beans-factory-lifecycle-combined-effects]]
+=== Combining Lifecycle Mechanisms
+
+As of Spring 2.5, you have three options for controlling bean lifecycle behavior:
+
+* The xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-initializingbean[`InitializingBean`] and
+xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-disposablebean[`DisposableBean`] callback interfaces
+* Custom `init()` and `destroy()` methods
+* The xref:core/beans/annotation-config/postconstruct-and-predestroy-annotations.adoc[`@PostConstruct` and `@PreDestroy` annotations]
+. You can combine these mechanisms to control a given bean.
+
+NOTE: If multiple lifecycle mechanisms are configured for a bean and each mechanism is
+configured with a different method name, then each configured method is run in the
+order listed after this note. However, if the same method name is configured -- for example,
+`init()` for an initialization method -- for more than one of these lifecycle mechanisms,
+that method is run once, as explained in the
+xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-default-init-destroy-methods[preceding section].
+
+Multiple lifecycle mechanisms configured for the same bean, with different
+initialization methods, are called as follows:
+
+. Methods annotated with `@PostConstruct`
+. `afterPropertiesSet()` as defined by the `InitializingBean` callback interface
+. A custom configured `init()` method
+
+Destroy methods are called in the same order:
+
+. Methods annotated with `@PreDestroy`
+. `destroy()` as defined by the `DisposableBean` callback interface
+. A custom configured `destroy()` method
+
+
+
+[[beans-factory-lifecycle-processor]]
+=== Startup and Shutdown Callbacks
+
+The `Lifecycle` interface defines the essential methods for any object that has its own
+lifecycle requirements (such as starting and stopping some background process):
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface Lifecycle {
+
+ void start();
+
+ void stop();
+
+ boolean isRunning();
+ }
+----
+
+Any Spring-managed object may implement the `Lifecycle` interface. Then, when the
+`ApplicationContext` itself receives start and stop signals (for example, for a stop/restart
+scenario at runtime), it cascades those calls to all `Lifecycle` implementations
+defined within that context. It does this by delegating to a `LifecycleProcessor`, shown
+in the following listing:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface LifecycleProcessor extends Lifecycle {
+
+ void onRefresh();
+
+ void onClose();
+ }
+----
+
+Notice that the `LifecycleProcessor` is itself an extension of the `Lifecycle`
+interface. It also adds two other methods for reacting to the context being refreshed
+and closed.
+
+[TIP]
+====
+Note that the regular `org.springframework.context.Lifecycle` interface is a plain
+contract for explicit start and stop notifications and does not imply auto-startup at context
+refresh time. For fine-grained control over auto-startup of a specific bean (including startup phases),
+consider implementing `org.springframework.context.SmartLifecycle` instead.
+
+Also, please note that stop notifications are not guaranteed to come before destruction.
+On regular shutdown, all `Lifecycle` beans first receive a stop notification before
+the general destruction callbacks are being propagated. However, on hot refresh during a
+context's lifetime or on stopped refresh attempts, only destroy methods are called.
+====
+
+The order of startup and shutdown invocations can be important. If a "`depends-on`"
+relationship exists between any two objects, the dependent side starts after its
+dependency, and it stops before its dependency. However, at times, the direct
+dependencies are unknown. You may only know that objects of a certain type should start
+prior to objects of another type. In those cases, the `SmartLifecycle` interface defines
+another option, namely the `getPhase()` method as defined on its super-interface,
+`Phased`. The following listing shows the definition of the `Phased` interface:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface Phased {
+
+ int getPhase();
+ }
+----
+
+The following listing shows the definition of the `SmartLifecycle` interface:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface SmartLifecycle extends Lifecycle, Phased {
+
+ boolean isAutoStartup();
+
+ void stop(Runnable callback);
+ }
+----
+
+When starting, the objects with the lowest phase start first. When stopping, the
+reverse order is followed. Therefore, an object that implements `SmartLifecycle` and
+whose `getPhase()` method returns `Integer.MIN_VALUE` would be among the first to start
+and the last to stop. At the other end of the spectrum, a phase value of
+`Integer.MAX_VALUE` would indicate that the object should be started last and stopped
+first (likely because it depends on other processes to be running). When considering the
+phase value, it is also important to know that the default phase for any "`normal`"
+`Lifecycle` object that does not implement `SmartLifecycle` is `0`. Therefore, any
+negative phase value indicates that an object should start before those standard
+components (and stop after them). The reverse is true for any positive phase value.
+
+The stop method defined by `SmartLifecycle` accepts a callback. Any
+implementation must invoke that callback's `run()` method after that implementation's
+shutdown process is complete. That enables asynchronous shutdown where necessary, since
+the default implementation of the `LifecycleProcessor` interface,
+`DefaultLifecycleProcessor`, waits up to its timeout value for the group of objects
+within each phase to invoke that callback. The default per-phase timeout is 30 seconds.
+You can override the default lifecycle processor instance by defining a bean named
+`lifecycleProcessor` within the context. If you want only to modify the timeout,
+defining the following would suffice:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+
+As mentioned earlier, the `LifecycleProcessor` interface defines callback methods for the
+refreshing and closing of the context as well. The latter drives the shutdown
+process as if `stop()` had been called explicitly, but it happens when the context is
+closing. The 'refresh' callback, on the other hand, enables another feature of
+`SmartLifecycle` beans. When the context is refreshed (after all objects have been
+instantiated and initialized), that callback is invoked. At that point, the
+default lifecycle processor checks the boolean value returned by each
+`SmartLifecycle` object's `isAutoStartup()` method. If `true`, that object is
+started at that point rather than waiting for an explicit invocation of the context's or
+its own `start()` method (unlike the context refresh, the context start does not happen
+automatically for a standard context implementation). The `phase` value and any
+"`depends-on`" relationships determine the startup order as described earlier.
+
+
+
+[[beans-factory-shutdown]]
+=== Shutting Down the Spring IoC Container Gracefully in Non-Web Applications
+
+[NOTE]
+====
+This section applies only to non-web applications. Spring's web-based
+`ApplicationContext` implementations already have code in place to gracefully shut down
+the Spring IoC container when the relevant web application is shut down.
+====
+
+If you use Spring's IoC container in a non-web application environment (for
+example, in a rich client desktop environment), register a shutdown hook with the
+JVM. Doing so ensures a graceful shutdown and calls the relevant destroy methods on your
+singleton beans so that all resources are released. You must still configure
+and implement these destroy callbacks correctly.
+
+To register a shutdown hook, call the `registerShutdownHook()` method that is
+declared on the `ConfigurableApplicationContext` interface, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import org.springframework.context.ConfigurableApplicationContext;
+ import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+ public final class Boot {
+
+ public static void main(final String[] args) throws Exception {
+ ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
+
+ // add a shutdown hook for the above context...
+ ctx.registerShutdownHook();
+
+ // app runs here...
+
+ // main method exits, hook is called prior to the app shutting down...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.context.support.ClassPathXmlApplicationContext
+
+ fun main() {
+ val ctx = ClassPathXmlApplicationContext("beans.xml")
+
+ // add a shutdown hook for the above context...
+ ctx.registerShutdownHook()
+
+ // app runs here...
+
+ // main method exits, hook is called prior to the app shutting down...
+ }
+----
+======
+
+
+
+[[beans-factory-aware]]
+== `ApplicationContextAware` and `BeanNameAware`
+
+When an `ApplicationContext` creates an object instance that implements the
+`org.springframework.context.ApplicationContextAware` interface, the instance is provided
+with a reference to that `ApplicationContext`. The following listing shows the definition
+of the `ApplicationContextAware` interface:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface ApplicationContextAware {
+
+ void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
+ }
+----
+
+Thus, beans can programmatically manipulate the `ApplicationContext` that created them,
+through the `ApplicationContext` interface or by casting the reference to a known
+subclass of this interface (such as `ConfigurableApplicationContext`, which exposes
+additional functionality). One use would be the programmatic retrieval of other beans.
+Sometimes this capability is useful. However, in general, you should avoid it, because
+it couples the code to Spring and does not follow the Inversion of Control style,
+where collaborators are provided to beans as properties. Other methods of the
+`ApplicationContext` provide access to file resources, publishing application events,
+and accessing a `MessageSource`. These additional features are described in
+xref:core/beans/context-introduction.adoc[Additional Capabilities of the `ApplicationContext`].
+
+Autowiring is another alternative to obtain a reference to the
+`ApplicationContext`. The _traditional_ `constructor` and `byType` autowiring modes
+(as described in xref:core/beans/dependencies/factory-autowire.adoc[Autowiring Collaborators]) can provide a dependency of type
+`ApplicationContext` for a constructor argument or a setter method parameter,
+respectively. For more flexibility, including the ability to autowire fields and
+multiple parameter methods, use the annotation-based autowiring features. If you do,
+the `ApplicationContext` is autowired into a field, constructor argument, or method
+parameter that expects the `ApplicationContext` type if the field, constructor, or
+method in question carries the `@Autowired` annotation. For more information, see
+xref:core/beans/annotation-config/autowired.adoc[Using `@Autowired`].
+
+When an `ApplicationContext` creates a class that implements the
+`org.springframework.beans.factory.BeanNameAware` interface, the class is provided with
+a reference to the name defined in its associated object definition. The following listing
+shows the definition of the BeanNameAware interface:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface BeanNameAware {
+
+ void setBeanName(String name) throws BeansException;
+ }
+----
+
+The callback is invoked after population of normal bean properties but before an
+initialization callback such as `InitializingBean.afterPropertiesSet()` or a custom
+init-method.
+
+
+
+[[aware-list]]
+== Other `Aware` Interfaces
+
+Besides `ApplicationContextAware` and `BeanNameAware` (discussed xref:core/beans/factory-nature.adoc#beans-factory-aware[earlier]),
+Spring offers a wide range of `Aware` callback interfaces that let beans indicate to the container
+that they require a certain infrastructure dependency. As a general rule, the name indicates the
+dependency type. The following table summarizes the most important `Aware` interfaces:
+
+[[beans-factory-nature-aware-list]]
+.Aware interfaces
+|===
+| Name| Injected Dependency| Explained in...
+
+| `ApplicationContextAware`
+| Declaring `ApplicationContext`.
+| xref:core/beans/factory-nature.adoc#beans-factory-aware[`ApplicationContextAware` and `BeanNameAware`]
+
+| `ApplicationEventPublisherAware`
+| Event publisher of the enclosing `ApplicationContext`.
+| xref:core/beans/context-introduction.adoc[Additional Capabilities of the `ApplicationContext`]
+
+| `BeanClassLoaderAware`
+| Class loader used to load the bean classes.
+| xref:core/beans/definition.adoc#beans-factory-class[Instantiating Beans]
+
+| `BeanFactoryAware`
+| Declaring `BeanFactory`.
+| xref:core/beans/beanfactory.adoc[The `BeanFactory` API]
+
+| `BeanNameAware`
+| Name of the declaring bean.
+| xref:core/beans/factory-nature.adoc#beans-factory-aware[`ApplicationContextAware` and `BeanNameAware`]
+
+| `LoadTimeWeaverAware`
+| Defined weaver for processing class definition at load time.
+| xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]
+
+| `MessageSourceAware`
+| Configured strategy for resolving messages (with support for parameterization and
+ internationalization).
+| xref:core/beans/context-introduction.adoc[Additional Capabilities of the `ApplicationContext`]
+
+| `NotificationPublisherAware`
+| Spring JMX notification publisher.
+| xref:integration/jmx/notifications.adoc[Notifications]
+
+| `ResourceLoaderAware`
+| Configured loader for low-level access to resources.
+| xref:web/webflux-webclient/client-builder.adoc#webflux-client-builder-reactor-resources[Resources]
+
+| `ServletConfigAware`
+| Current `ServletConfig` the container runs in. Valid only in a web-aware Spring
+ `ApplicationContext`.
+| xref:web/webmvc.adoc#mvc[Spring MVC]
+
+| `ServletContextAware`
+| Current `ServletContext` the container runs in. Valid only in a web-aware Spring
+ `ApplicationContext`.
+| xref:web/webmvc.adoc#mvc[Spring MVC]
+|===
+
+Note again that using these interfaces ties your code to the Spring API and does not
+follow the Inversion of Control style. As a result, we recommend them for infrastructure
+beans that require programmatic access to the container.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc
new file mode 100644
index 000000000000..6a835bebb2fb
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc
@@ -0,0 +1,768 @@
+[[beans-factory-scopes]]
+= Bean Scopes
+
+When you create a bean definition, you create a recipe for creating actual instances
+of the class defined by that bean definition. The idea that a bean definition is a
+recipe is important, because it means that, as with a class, you can create many object
+instances from a single recipe.
+
+You can control not only the various dependencies and configuration values that are to
+be plugged into an object that is created from a particular bean definition but also control
+the scope of the objects created from a particular bean definition. This approach is
+powerful and flexible, because you can choose the scope of the objects you create
+through configuration instead of having to bake in the scope of an object at the Java
+class level. Beans can be defined to be deployed in one of a number of scopes.
+The Spring Framework supports six scopes, four of which are available only if
+you use a web-aware `ApplicationContext`. You can also create
+xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom[a custom scope.]
+
+The following table describes the supported scopes:
+
+[[beans-factory-scopes-tbl]]
+.Bean scopes
+[cols="20%,80%"]
+|===
+| Scope| Description
+
+| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singleton]
+| (Default) Scopes a single bean definition to a single object instance for each Spring IoC
+ container.
+
+| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-prototype[prototype]
+| Scopes a single bean definition to any number of object instances.
+
+| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-request[request]
+| Scopes a single bean definition to the lifecycle of a single HTTP request. That is,
+ each HTTP request has its own instance of a bean created off the back of a single bean
+ definition. Only valid in the context of a web-aware Spring `ApplicationContext`.
+
+| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-session[session]
+| Scopes a single bean definition to the lifecycle of an HTTP `Session`. Only valid in
+ the context of a web-aware Spring `ApplicationContext`.
+
+| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-application[application]
+| Scopes a single bean definition to the lifecycle of a `ServletContext`. Only valid in
+ the context of a web-aware Spring `ApplicationContext`.
+
+| xref:web/websocket/stomp/scope.adoc[websocket]
+| Scopes a single bean definition to the lifecycle of a `WebSocket`. Only valid in
+ the context of a web-aware Spring `ApplicationContext`.
+|===
+
+NOTE: A thread scope is available but is not registered by default. For more information,
+see the documentation for
+{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].
+For instructions on how to register this or any other custom scope, see
+xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].
+
+
+
+[[beans-factory-scopes-singleton]]
+== The Singleton Scope
+
+Only one shared instance of a singleton bean is managed, and all requests for beans
+with an ID or IDs that match that bean definition result in that one specific bean
+instance being returned by the Spring container.
+
+To put it another way, when you define a bean definition and it is scoped as a
+singleton, the Spring IoC container creates exactly one instance of the object
+defined by that bean definition. This single instance is stored in a cache of such
+singleton beans, and all subsequent requests and references for that named bean
+return the cached object. The following image shows how the singleton scope works:
+
+image::singleton.png[]
+
+Spring's concept of a singleton bean differs from the singleton pattern as defined in
+the Gang of Four (GoF) patterns book. The GoF singleton hard-codes the scope of an
+object such that one and only one instance of a particular class is created per
+ClassLoader. The scope of the Spring singleton is best described as being per-container
+and per-bean. This means that, if you define one bean for a particular class in a
+single Spring container, the Spring container creates one and only one instance
+of the class defined by that bean definition. The singleton scope is the default scope
+in Spring. To define a bean as a singleton in XML, you can define a bean as shown in the
+following example:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+----
+
+
+
+[[beans-factory-scopes-prototype]]
+== The Prototype Scope
+
+The non-singleton prototype scope of bean deployment results in the creation of a new
+bean instance every time a request for that specific bean is made. That is, the bean
+is injected into another bean or you request it through a `getBean()` method call on the
+container. As a rule, you should use the prototype scope for all stateful beans and the
+singleton scope for stateless beans.
+
+The following diagram illustrates the Spring prototype scope:
+
+image::prototype.png[]
+
+(A data access object
+(DAO) is not typically configured as a prototype, because a typical DAO does not hold
+any conversational state. It was easier for us to reuse the core of the
+singleton diagram.)
+
+The following example defines a bean as a prototype in XML:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+In contrast to the other scopes, Spring does not manage the complete lifecycle of a
+prototype bean. The container instantiates, configures, and otherwise assembles a
+prototype object and hands it to the client, with no further record of that prototype
+instance. Thus, although initialization lifecycle callback methods are called on all
+objects regardless of scope, in the case of prototypes, configured destruction
+lifecycle callbacks are not called. The client code must clean up prototype-scoped
+objects and release expensive resources that the prototype beans hold. To get
+the Spring container to release resources held by prototype-scoped beans, try using a
+custom xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp[bean post-processor], which holds a reference to
+beans that need to be cleaned up.
+
+In some respects, the Spring container's role in regard to a prototype-scoped bean is a
+replacement for the Java `new` operator. All lifecycle management past that point must
+be handled by the client. (For details on the lifecycle of a bean in the Spring
+container, see xref:core/beans/factory-nature.adoc#beans-factory-lifecycle[Lifecycle Callbacks].)
+
+
+
+[[beans-factory-scopes-sing-prot-interaction]]
+== Singleton Beans with Prototype-bean Dependencies
+
+When you use singleton-scoped beans with dependencies on prototype beans, be aware that
+dependencies are resolved at instantiation time. Thus, if you dependency-inject a
+prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated
+and then dependency-injected into the singleton bean. The prototype instance is the sole
+instance that is ever supplied to the singleton-scoped bean.
+
+However, suppose you want the singleton-scoped bean to acquire a new instance of the
+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 xref:core/beans/dependencies/factory-method-injection.adoc[Method Injection].
+
+
+
+[[beans-factory-scopes-other]]
+== Request, Session, Application, and WebSocket Scopes
+
+The `request`, `session`, `application`, and `websocket` scopes are available only
+if you use a web-aware Spring `ApplicationContext` implementation (such as
+`XmlWebApplicationContext`). If you use these scopes with regular Spring IoC containers,
+such as the `ClassPathXmlApplicationContext`, an `IllegalStateException` that complains
+about an unknown bean scope is thrown.
+
+
+
+[[beans-factory-scopes-other-web-configuration]]
+=== Initial Web Configuration
+
+To support the scoping of beans at the `request`, `session`, `application`, and
+`websocket` levels (web-scoped beans), some minor initial configuration is
+required before you define your beans. (This initial setup is not required
+for the standard scopes: `singleton` and `prototype`.)
+
+How you accomplish this initial setup depends on your particular Servlet environment.
+
+If you access scoped beans within Spring Web MVC, in effect, within a request that is
+processed by the Spring `DispatcherServlet`, no special setup is necessary.
+`DispatcherServlet` already exposes all relevant state.
+
+If you use a Servlet web container, with requests processed outside of Spring's
+`DispatcherServlet` (for example, when using JSF), you need to register the
+`org.springframework.web.context.request.RequestContextListener` `ServletRequestListener`.
+This can be done programmatically by using the `WebApplicationInitializer` interface.
+Alternatively, add the following declaration to your web application's `web.xml` file:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+ ...
+
+
+ org.springframework.web.context.request.RequestContextListener
+
+
+ ...
+
+----
+
+Alternatively, if there are issues with your listener setup, consider using Spring's
+`RequestContextFilter`. The filter mapping depends on the surrounding web
+application configuration, so you have to change it as appropriate. The following listing
+shows the filter part of a web application:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+ ...
+
+ requestContextFilter
+ org.springframework.web.filter.RequestContextFilter
+
+
+ requestContextFilter
+ /*
+
+ ...
+
+----
+
+`DispatcherServlet`, `RequestContextListener`, and `RequestContextFilter` all do exactly
+the same thing, namely bind the HTTP request object to the `Thread` that is servicing
+that request. This makes beans that are request- and session-scoped available further
+down the call chain.
+
+
+
+[[beans-factory-scopes-request]]
+=== Request scope
+
+Consider the following XML configuration for a bean definition:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+The Spring container creates a new instance of the `LoginAction` bean by using the
+`loginAction` bean definition for each and every HTTP request. That is, the
+`loginAction` bean is scoped at the HTTP request level. You can change the internal
+state of the instance that is created as much as you want, because other instances
+created from the same `loginAction` bean definition do not see these changes in state.
+They are particular to an individual request. When the request completes processing, the
+bean that is scoped to the request is discarded.
+
+When using annotation-driven components or Java configuration, the `@RequestScope` annotation
+can be used to assign a component to the `request` scope. The following example shows how
+to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @RequestScope
+ @Component
+ public class LoginAction {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @RequestScope
+ @Component
+ class LoginAction {
+ // ...
+ }
+----
+======
+
+
+
+[[beans-factory-scopes-session]]
+=== Session Scope
+
+Consider the following XML configuration for a bean definition:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+The Spring container creates a new instance of the `UserPreferences` bean by using the
+`userPreferences` bean definition for the lifetime of a single HTTP `Session`. In other
+words, the `userPreferences` bean is effectively scoped at the HTTP `Session` level. As
+with request-scoped beans, you can change the internal state of the instance that is
+created as much as you want, knowing that other HTTP `Session` instances that are also
+using instances created from the same `userPreferences` bean definition do not see these
+changes in state, because they are particular to an individual HTTP `Session`. When the
+HTTP `Session` is eventually discarded, the bean that is scoped to that particular HTTP
+`Session` is also discarded.
+
+When using annotation-driven components or Java configuration, you can use the
+`@SessionScope` annotation to assign a component to the `session` scope.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @SessionScope
+ @Component
+ public class UserPreferences {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @SessionScope
+ @Component
+ class UserPreferences {
+ // ...
+ }
+----
+======
+
+
+
+
+[[beans-factory-scopes-application]]
+=== Application Scope
+
+Consider the following XML configuration for a bean definition:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+The Spring container creates a new instance of the `AppPreferences` bean by using the
+`appPreferences` bean definition once for the entire web application. That is, the
+`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),
+and it is actually exposed and therefore visible as a `ServletContext` attribute.
+
+When using annotation-driven components or Java configuration, you can use the
+`@ApplicationScope` annotation to assign a component to the `application` scope. The
+following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @ApplicationScope
+ @Component
+ public class AppPreferences {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @ApplicationScope
+ @Component
+ class AppPreferences {
+ // ...
+ }
+----
+======
+
+
+
+
+[[beans-factory-scopes-websocket]]
+=== WebSocket Scope
+
+WebSocket scope is associated with the lifecycle of a WebSocket session and applies to
+STOMP over WebSocket applications, see
+xref:web/websocket/stomp/scope.adoc[WebSocket scope] for more details.
+
+
+
+
+[[beans-factory-scopes-other-injection]]
+=== Scoped Beans as Dependencies
+
+The Spring IoC container manages not only the instantiation of your objects (beans),
+but also the wiring up of collaborators (or dependencies). If you want to inject (for
+example) an HTTP request-scoped bean into another bean of a longer-lived scope, you may
+choose to inject an AOP proxy in place of the scoped bean. That is, you need to inject
+a proxy object that exposes the same public interface as the scoped object but that can
+also retrieve the real target object from the relevant scope (such as an HTTP request)
+and delegate method calls onto the real object.
+
+[NOTE]
+====
+You may also use `` between beans that are scoped as `singleton`,
+with the reference then going through an intermediate proxy that is serializable
+and therefore able to re-obtain the target singleton bean on deserialization.
+
+When declaring `` against a bean of scope `prototype`, every method
+call on the shared proxy leads to the creation of a new target instance to which the
+call is then being forwarded.
+
+Also, scoped proxies are not the only way to access beans from shorter scopes in a
+lifecycle-safe fashion. You may also declare your injection point (that is, the
+constructor or setter argument or autowired field) as `ObjectFactory`,
+allowing for a `getObject()` call to retrieve the current instance on demand every
+time it is needed -- without holding on to the instance or storing it separately.
+
+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`
+declaration and a corresponding `get()` call for every retrieval attempt.
+See xref:core/beans/standard-annotations.adoc[here] for more details on JSR-330 overall.
+====
+
+The configuration in the following example is only one line, but it is important to
+understand the "`why`" as well as the "`how`" behind it:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+ <1>
+
+
+
+
+
+
+
+
+----
+<1> The line that defines the proxy.
+
+
+To create such a proxy, you insert a child `` element into a scoped
+bean definition (see xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection-proxies[Choosing the Type of Proxy to Create] and
+xref:core/appendix/xsd-schemas.adoc[XML Schema-based configuration]).
+Why do definitions of beans scoped at the `request`, `session` and custom-scope
+levels require the `` element?
+Consider the following singleton bean definition and contrast it with
+what you need to define for the aforementioned scopes (note that the following
+`userPreferences` bean definition as it stands is incomplete):
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+----
+
+In the preceding example, the singleton bean (`userManager`) is injected with a reference
+to the HTTP `Session`-scoped bean (`userPreferences`). The salient point here is that the
+`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).
+
+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
+bean as a dependency into singleton bean). Rather, you need a single `userManager`
+object, and, for the lifetime of an HTTP `Session`, you need a `userPreferences` object
+that is specific to the HTTP `Session`. Thus, the container creates an object that
+exposes the exact same public interface as the `UserPreferences` class (ideally an
+object that is a `UserPreferences` instance), which can fetch the real
+`UserPreferences` object from the scoping mechanism (HTTP request, `Session`, and so
+forth). The container injects this proxy object into the `userManager` bean, which is
+unaware that this `UserPreferences` reference is a proxy. In this example, when a
+`UserManager` instance invokes a method on the dependency-injected `UserPreferences`
+object, it is actually invoking a method on the proxy. The proxy then fetches the real
+`UserPreferences` object from (in this case) the HTTP `Session` and delegates the
+method invocation onto the retrieved real `UserPreferences` object.
+
+Thus, you need the following (correct and complete) configuration when injecting
+`request-` and `session-scoped` beans into collaborating objects, as the following example
+shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+[[beans-factory-scopes-other-injection-proxies]]
+==== Choosing the Type of Proxy to Create
+
+By default, when the Spring container creates a proxy for a bean that is marked up with
+the `` element, a CGLIB-based class proxy is created.
+
+[NOTE]
+====
+CGLIB proxies intercept only public method calls! Do not call non-public methods
+on such a proxy. They are not delegated to the actual scoped target object.
+====
+
+Alternatively, you can configure the Spring container to create standard JDK
+interface-based proxies for such scoped beans, by specifying `false` for the value of
+the `proxy-target-class` attribute of the `` element. Using JDK
+interface-based proxies means that you do not need additional libraries in your
+application classpath to affect such proxying. However, it also means that the class of
+the scoped bean must implement at least one interface and that all collaborators
+into which the scoped bean is injected must reference the bean through one of its
+interfaces. The following example shows a proxy based on an interface:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+----
+
+For more detailed information about choosing class-based or interface-based proxying,
+see xref:core/aop/proxying.adoc[Proxying Mechanisms].
+
+
+
+[[beans-factory-scopes-custom]]
+== Custom Scopes
+
+The bean scoping mechanism is extensible. You can define your own
+scopes or even redefine existing scopes, although the latter is considered bad practice
+and you cannot override the built-in `singleton` and `prototype` scopes.
+
+
+[[beans-factory-scopes-custom-creating]]
+=== Creating a Custom Scope
+
+To integrate your custom scopes into the Spring container, you need to implement the
+`org.springframework.beans.factory.config.Scope` interface, which is described in this
+section. For an idea of how to implement your own scopes, see the `Scope`
+implementations that are supplied with the Spring Framework itself and the
+{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,
+which explains the methods you need to implement in more detail.
+
+The `Scope` interface has four methods to get objects from the scope, remove them from
+the scope, and let them be destroyed.
+
+The session scope implementation, for example, returns the session-scoped bean (if it
+does not exist, the method returns a new instance of the bean, after having bound it to
+the session for future reference). The following method returns the object from the
+underlying scope:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Object get(String name, ObjectFactory> objectFactory)
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun get(name: String, objectFactory: ObjectFactory<*>): Any
+----
+======
+
+The session scope implementation, for example, removes the session-scoped bean from the
+underlying session. The object should be returned, but you can return `null` if the
+object with the specified name is not found. The following method removes the object from
+the underlying scope:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Object remove(String name)
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun remove(name: String): Any
+----
+======
+
+The following method registers a callback that the scope should invoke when it is
+destroyed or when the specified object in the scope is destroyed:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ void registerDestructionCallback(String name, Runnable destructionCallback)
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun registerDestructionCallback(name: String, destructionCallback: Runnable)
+----
+======
+
+See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]
+or a Spring scope implementation for more information on destruction callbacks.
+
+The following method obtains the conversation identifier for the underlying scope:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ String getConversationId()
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun getConversationId(): String
+----
+======
+
+This identifier is different for each scope. For a session scoped implementation, this
+identifier can be the session identifier.
+
+
+
+[[beans-factory-scopes-custom-using]]
+=== Using a Custom Scope
+
+After you write and test one or more custom `Scope` implementations, you need to make
+the Spring container aware of your new scopes. The following method is the central
+method to register a new `Scope` with the Spring container:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ void registerScope(String scopeName, Scope scope);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun registerScope(scopeName: String, scope: Scope)
+----
+======
+
+This method is declared on the `ConfigurableBeanFactory` interface, which is available
+through the `BeanFactory` property on most of the concrete `ApplicationContext`
+implementations that ship with Spring.
+
+The first argument to the `registerScope(..)` method is the unique name associated with
+a scope. Examples of such names in the Spring container itself are `singleton` and
+`prototype`. The second argument to the `registerScope(..)` method is an actual instance
+of the custom `Scope` implementation that you wish to register and use.
+
+Suppose that you write your custom `Scope` implementation, and then register it as shown
+in the next example.
+
+NOTE: The next example uses `SimpleThreadScope`, which is included with Spring but is not
+registered by default. The instructions would be the same for your own custom `Scope`
+implementations.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Scope threadScope = new SimpleThreadScope();
+ beanFactory.registerScope("thread", threadScope);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val threadScope = SimpleThreadScope()
+ beanFactory.registerScope("thread", threadScope)
+----
+======
+
+You can then create bean definitions that adhere to the scoping rules of your custom
+`Scope`, as follows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+With a custom `Scope` implementation, you are not limited to programmatic registration
+of the scope. You can also do the `Scope` registration declaratively, by using the
+`CustomScopeConfigurer` class, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+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()`.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc
new file mode 100644
index 000000000000..84fce22f428d
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc
@@ -0,0 +1,43 @@
+[[beans-introduction]]
+= Introduction to the Spring IoC Container and Beans
+
+This chapter covers the Spring Framework implementation of the Inversion of Control
+(IoC) principle. IoC is also known as dependency injection (DI). It is a process whereby
+objects define their dependencies (that is, the other objects they work with) only through
+constructor arguments, arguments to a factory method, or properties that are set on the
+object instance after it is constructed or returned from a factory method. The container
+then injects those dependencies when it creates the bean. This process is fundamentally
+the inverse (hence the name, Inversion of Control) of the bean itself
+controlling the instantiation or location of its dependencies by using direct
+construction of classes or a mechanism such as the Service Locator pattern.
+
+The `org.springframework.beans` and `org.springframework.context` packages are the basis
+for Spring Framework's IoC container. The
+{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]
+interface provides an advanced configuration mechanism capable of managing any type of
+object.
+{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]
+is a sub-interface of `BeanFactory`. It adds:
+
+* Easier integration with Spring's AOP features
+* Message resource handling (for use in internationalization)
+* Event publication
+* Application-layer specific contexts such as the `WebApplicationContext`
+for use in web applications.
+
+In short, the `BeanFactory` provides the configuration framework and basic functionality,
+and the `ApplicationContext` adds more enterprise-specific functionality. The
+`ApplicationContext` is a complete superset of the `BeanFactory` and is used exclusively
+in this chapter in descriptions of Spring's IoC container. For more information on using
+the `BeanFactory` instead of the `ApplicationContext,` see the section covering the
+xref:core/beans/beanfactory.adoc[`BeanFactory` API].
+
+In Spring, the objects that form the backbone of your application and that are managed
+by the Spring IoC container are called beans. A bean is an object that is
+instantiated, assembled, and managed by a Spring IoC container. Otherwise, a
+bean is simply one of many objects in your application. Beans, and the dependencies
+among them, are reflected in the configuration metadata used by a container.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/java.adoc b/framework-docs/modules/ROOT/pages/core/beans/java.adoc
new file mode 100644
index 000000000000..9cb9f492b6e7
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/java.adoc
@@ -0,0 +1,19 @@
+[[beans-java]]
+= Java-based Container Configuration
+:page-section-summary-toc: 1
+
+This section covers how to use annotations in your Java code to configure the Spring
+container. It includes the following topics:
+
+* xref:core/beans/java/basic-concepts.adoc[Basic Concepts: `@Bean` and `@Configuration`]
+* xref:core/beans/java/instantiating-container.adoc[Instantiating the Spring Container by Using `AnnotationConfigApplicationContext`]
+* xref:core/beans/java/bean-annotation.adoc[Using the `@Bean` Annotation]
+* xref:core/beans/java/configuration-annotation.adoc[Using the `@Configuration` annotation]
+* xref:core/beans/java/composing-configuration-classes.adoc[Composing Java-based Configurations]
+* xref:core/beans/environment.adoc#beans-definition-profiles[Bean Definition Profiles]
+* xref:core/beans/environment.adoc#beans-property-source-abstraction[`PropertySource` Abstraction]
+* xref:core/beans/environment.adoc#beans-using-propertysource[Using `@PropertySource`]
+* xref:core/beans/environment.adoc#beans-placeholder-resolution-in-statements[Placeholder Resolution in Statements]
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/java/basic-concepts.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/basic-concepts.adoc
new file mode 100644
index 000000000000..f90a2752b7ea
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/java/basic-concepts.adoc
@@ -0,0 +1,88 @@
+[[beans-java-basic-concepts]]
+= Basic Concepts: `@Bean` and `@Configuration`
+
+The central artifacts in Spring's Java configuration support are
+`@Configuration`-annotated classes and `@Bean`-annotated methods.
+
+The `@Bean` annotation is used to indicate that a method instantiates, configures, and
+initializes a new object to be managed by the Spring IoC container. For those familiar
+with Spring's `` XML configuration, the `@Bean` annotation plays the same role as
+the `` element. You can use `@Bean`-annotated methods with any Spring
+`@Component`. However, they are most often used with `@Configuration` beans.
+
+Annotating a class with `@Configuration` indicates that its primary purpose is as a
+source of bean definitions. Furthermore, `@Configuration` classes let inter-bean
+dependencies be defined by calling other `@Bean` methods in the same class.
+The simplest possible `@Configuration` class reads as follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public MyServiceImpl myService() {
+ return new MyServiceImpl();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun myService(): MyServiceImpl {
+ return MyServiceImpl()
+ }
+ }
+----
+======
+
+The preceding `AppConfig` class is equivalent to the following Spring `` XML:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+.Full @Configuration vs "`lite`" @Bean mode?
+****
+When `@Bean` methods are declared within classes that are not annotated with
+`@Configuration`, they are referred to as being processed in a "`lite`" mode. Bean methods
+declared in a `@Component` or even in a plain old class are considered to be "`lite`",
+with a different primary purpose of the containing class and a `@Bean` method
+being a sort of bonus there. For example, service components may expose management views
+to the container through an additional `@Bean` method on each applicable component class.
+In such scenarios, `@Bean` methods are a general-purpose factory method mechanism.
+
+Unlike full `@Configuration`, lite `@Bean` methods cannot declare inter-bean dependencies.
+Instead, they operate on their containing component's internal state and, optionally, on
+arguments that they may declare. Such a `@Bean` method should therefore not invoke other
+`@Bean` methods. Each such method is literally only a factory method for a particular
+bean reference, without any special runtime semantics. The positive side-effect here is
+that no CGLIB subclassing has to be applied at runtime, so there are no limitations in
+terms of class design (that is, the containing class may be `final` and so forth).
+
+In common scenarios, `@Bean` methods are to be declared within `@Configuration` classes,
+ensuring that "`full`" mode is always used and that cross-method references therefore
+get redirected to the container's lifecycle management. This prevents the same
+`@Bean` method from accidentally being invoked through a regular Java call, which helps
+to reduce subtle bugs that can be hard to track down when operating in "`lite`" mode.
+****
+
+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 by using
+Java-based configuration.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc
new file mode 100644
index 000000000000..52089db3c58d
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc
@@ -0,0 +1,588 @@
+[[beans-java-bean-annotation]]
+= Using the `@Bean` Annotation
+
+`@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:
+
+* xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-initializingbean[init-method]
+* xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-disposablebean[destroy-method]
+* xref:core/beans/dependencies/factory-autowire.adoc[autowiring]
+* `name`.
+
+You can use the `@Bean` annotation in a `@Configuration`-annotated or in a
+`@Component`-annotated class.
+
+
+[[beans-java-declaring-a-bean]]
+== Declaring a Bean
+
+To declare a bean, you can annotate a method with the `@Bean` annotation. You use this
+method to register a bean definition within an `ApplicationContext` of the type
+specified as the method's return value. By default, the bean name is the same as
+the method name. The following example shows a `@Bean` method declaration:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public TransferServiceImpl transferService() {
+ return new TransferServiceImpl();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun transferService() = TransferServiceImpl()
+ }
+----
+======
+
+The preceding configuration is exactly equivalent to the following Spring XML:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+Both declarations make a bean named `transferService` available in the
+`ApplicationContext`, bound to an object instance of type `TransferServiceImpl`, as the
+following text image shows:
+
+[literal,subs="verbatim,quotes"]
+----
+transferService -> com.acme.TransferServiceImpl
+----
+
+You can also use default methods to define beans. This allows composition of bean
+configurations by implementing interfaces with bean definitions on default methods.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public interface BaseConfig {
+
+ @Bean
+ default TransferServiceImpl transferService() {
+ return new TransferServiceImpl();
+ }
+ }
+
+ @Configuration
+ public class AppConfig implements BaseConfig {
+
+ }
+----
+======
+
+You can also declare your `@Bean` method with an interface (or base class)
+return type, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public TransferService transferService() {
+ return new TransferServiceImpl();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun transferService(): TransferService {
+ return TransferServiceImpl()
+ }
+ }
+----
+======
+
+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.
+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`,
+which resolves only once the `transferService` bean has been instantiated).
+
+TIP: If you consistently refer to your types by a declared service interface, your
+`@Bean` return types may safely join that design decision. However, for components
+that implement several interfaces or for components potentially referred to by their
+implementation type, it is safer to declare the most specific return type possible
+(at least as specific as required by the injection points that refer to your bean).
+
+
+[[beans-java-dependencies]]
+== Bean Dependencies
+
+A `@Bean`-annotated method can have an arbitrary number of parameters that describe the
+dependencies required to build that bean. For instance, if our `TransferService`
+requires an `AccountRepository`, we can materialize that dependency with a method
+parameter, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public TransferService transferService(AccountRepository accountRepository) {
+ return new TransferServiceImpl(accountRepository);
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun transferService(accountRepository: AccountRepository): TransferService {
+ return TransferServiceImpl(accountRepository)
+ }
+ }
+----
+======
+
+
+The resolution mechanism is pretty much identical to constructor-based dependency
+injection. See xref:core/beans/dependencies/factory-collaborators.adoc#beans-constructor-injection[the relevant section] for more details.
+
+
+[[beans-java-lifecycle-callbacks]]
+== Receiving Lifecycle Callbacks
+
+Any classes defined with the `@Bean` annotation support the regular lifecycle callbacks
+and can use the `@PostConstruct` and `@PreDestroy` annotations from JSR-250. See
+xref:core/beans/annotation-config/postconstruct-and-predestroy-annotations.adoc[JSR-250 annotations] for further
+details.
+
+The regular Spring xref:core/beans/factory-nature.adoc[lifecycle] callbacks are fully supported as
+well. If a bean implements `InitializingBean`, `DisposableBean`, or `Lifecycle`, their
+respective methods are called by the container.
+
+The standard set of `*Aware` interfaces (such as xref:core/beans/beanfactory.adoc[BeanFactoryAware],
+xref:core/beans/factory-nature.adoc#beans-factory-aware[BeanNameAware],
+xref:core/beans/context-introduction.adoc#context-functionality-messagesource[MessageSourceAware],
+xref:core/beans/factory-nature.adoc#beans-factory-aware[ApplicationContextAware], and so on) are also fully supported.
+
+The `@Bean` annotation supports specifying arbitrary initialization and destruction
+callback methods, much like Spring XML's `init-method` and `destroy-method` attributes
+on the `bean` element, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class BeanOne {
+
+ public void init() {
+ // initialization logic
+ }
+ }
+
+ public class BeanTwo {
+
+ public void cleanup() {
+ // destruction logic
+ }
+ }
+
+ @Configuration
+ public class AppConfig {
+
+ @Bean(initMethod = "init")
+ public BeanOne beanOne() {
+ return new BeanOne();
+ }
+
+ @Bean(destroyMethod = "cleanup")
+ public BeanTwo beanTwo() {
+ return new BeanTwo();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+class BeanOne {
+
+ fun init() {
+ // initialization logic
+ }
+}
+
+class BeanTwo {
+
+ fun cleanup() {
+ // destruction logic
+ }
+}
+
+@Configuration
+class AppConfig {
+
+ @Bean(initMethod = "init")
+ fun beanOne() = BeanOne()
+
+ @Bean(destroyMethod = "cleanup")
+ fun beanTwo() = BeanTwo()
+}
+----
+======
+
+[NOTE]
+=====
+By default, beans defined with Java configuration that have a public `close` or `shutdown`
+method are automatically enlisted with a destruction callback. If you have a public
+`close` or `shutdown` method and you do not wish for it to be called when the container
+shuts down, you can add `@Bean(destroyMethod = "")` to your bean definition to disable the
+default `(inferred)` mode.
+
+You may want to do that by default for a resource that you acquire with JNDI, as its
+lifecycle is managed outside the application. In particular, make sure to always do it
+for a `DataSource`, as it is known to be problematic on Jakarta EE application servers.
+
+The following example shows how to prevent an automatic destruction callback for a
+`DataSource`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Bean(destroyMethod = "")
+ public DataSource dataSource() throws NamingException {
+ return (DataSource) jndiTemplate.lookup("MyDS");
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Bean(destroyMethod = "")
+ fun dataSource(): DataSource {
+ return jndiTemplate.lookup("MyDS") as DataSource
+ }
+----
+======
+
+Also, with `@Bean` methods, you typically use programmatic JNDI lookups, either by
+using Spring's `JndiTemplate` or `JndiLocatorDelegate` helpers or straight JNDI
+`InitialContext` usage but not the `JndiObjectFactoryBean` variant (which would force
+you to declare the return type as the `FactoryBean` type instead of the actual target
+type, making it harder to use for cross-reference calls in other `@Bean` methods that
+intend to refer to the provided resource here).
+=====
+
+In the case of `BeanOne` from the example above the preceding note, it would be equally valid to call the `init()`
+method directly during construction, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public BeanOne beanOne() {
+ BeanOne beanOne = new BeanOne();
+ beanOne.init();
+ return beanOne;
+ }
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun beanOne() = BeanOne().apply {
+ init()
+ }
+
+ // ...
+ }
+----
+======
+
+TIP: When you work directly in Java, you can do anything you like with your objects and do
+not always need to rely on the container lifecycle.
+
+
+[[beans-java-specifying-bean-scope]]
+== Specifying Bean Scope
+
+Spring includes the `@Scope` annotation so that you can specify the scope of a bean.
+
+[[beans-java-available-scopes]]
+=== Using the `@Scope` Annotation
+
+You can specify that your beans defined with the `@Bean` annotation should have a
+specific scope. You can use any of the standard scopes specified in the
+xref:core/beans/factory-scopes.adoc[Bean Scopes] section.
+
+The default scope is `singleton`, but you can override this with the `@Scope` annotation,
+as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class MyConfiguration {
+
+ @Bean
+ @Scope("prototype")
+ public Encryptor encryptor() {
+ // ...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class MyConfiguration {
+
+ @Bean
+ @Scope("prototype")
+ fun encryptor(): Encryptor {
+ // ...
+ }
+ }
+----
+======
+
+[[beans-java-scoped-proxy]]
+=== `@Scope` and `scoped-proxy`
+
+Spring offers a convenient way of working with scoped dependencies through
+xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection[scoped proxies]. 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 `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
+xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection[scoped proxies]) to our `@Bean` using Java,
+it resembles the following:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // an HTTP Session-scoped bean exposed as a proxy
+ @Bean
+ @SessionScope
+ public UserPreferences userPreferences() {
+ return new UserPreferences();
+ }
+
+ @Bean
+ public Service userService() {
+ UserService service = new SimpleUserService();
+ // a reference to the proxied userPreferences bean
+ service.setUserPreferences(userPreferences());
+ return service;
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // an HTTP Session-scoped bean exposed as a proxy
+ @Bean
+ @SessionScope
+ fun userPreferences() = UserPreferences()
+
+ @Bean
+ fun userService(): Service {
+ return SimpleUserService().apply {
+ // a reference to the proxied userPreferences bean
+ setUserPreferences(userPreferences())
+ }
+ }
+----
+======
+
+[[beans-java-customizing-bean-naming]]
+== Customizing Bean Naming
+
+By default, configuration classes use a `@Bean` method's name as the name of the
+resulting bean. This functionality can be overridden, however, with the `name` attribute,
+as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean("myThing")
+ public Thing thing() {
+ return new Thing();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean("myThing")
+ fun thing() = Thing()
+ }
+----
+======
+
+
+[[beans-java-bean-aliasing]]
+== Bean Aliasing
+
+As discussed in xref:core/beans/definition.adoc#beans-beanname[Naming Beans], it is sometimes desirable to give a single bean
+multiple names, otherwise known as bean aliasing. The `name` attribute of the `@Bean`
+annotation accepts a String array for this purpose. The following example shows how to set
+a number of aliases for a bean:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
+ public DataSource dataSource() {
+ // instantiate, configure and return DataSource bean...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean("dataSource", "subsystemA-dataSource", "subsystemB-dataSource")
+ fun dataSource(): DataSource {
+ // instantiate, configure and return DataSource bean...
+ }
+ }
+----
+======
+
+
+[[beans-java-bean-description]]
+== Bean Description
+
+Sometimes, it is helpful to provide a more detailed textual description of a bean. This can
+be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.
+
+To add a description to a `@Bean`, you can use the
+{api-spring-framework}/context/annotation/Description.html[`@Description`]
+annotation, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ @Description("Provides a basic example of a bean")
+ public Thing thing() {
+ return new Thing();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ @Description("Provides a basic example of a bean")
+ fun thing() = Thing()
+ }
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc
new file mode 100644
index 000000000000..bb919b2af7e8
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc
@@ -0,0 +1,843 @@
+[[beans-java-composing-configuration-classes]]
+= Composing Java-based Configurations
+
+Spring's Java-based configuration feature lets you compose annotations, which can reduce
+the complexity of your configuration.
+
+
+[[beans-java-using-import]]
+== Using the `@Import` Annotation
+
+Much as the `` element is used within Spring XML files to aid in modularizing
+configurations, the `@Import` annotation allows for loading `@Bean` definitions from
+another configuration class, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class ConfigA {
+
+ @Bean
+ public A a() {
+ return new A();
+ }
+ }
+
+ @Configuration
+ @Import(ConfigA.class)
+ public class ConfigB {
+
+ @Bean
+ public B b() {
+ return new B();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class ConfigA {
+
+ @Bean
+ fun a() = A()
+ }
+
+ @Configuration
+ @Import(ConfigA::class)
+ class ConfigB {
+
+ @Bean
+ fun b() = B()
+ }
+----
+======
+
+Now, rather than needing to specify both `ConfigA.class` and `ConfigB.class` when
+instantiating the context, only `ConfigB` needs to be supplied explicitly, as the
+following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
+
+ // now both beans A and B will be available...
+ A a = ctx.getBean(A.class);
+ B b = ctx.getBean(B.class);
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(ConfigB::class.java)
+
+ // now both beans A and B will be available...
+ val a = ctx.getBean()
+ val b = ctx.getBean()
+ }
+----
+======
+
+This approach simplifies container instantiation, as only one class needs to be dealt
+with, rather than requiring you to remember a potentially large number of
+`@Configuration` classes during construction.
+
+TIP: As of Spring Framework 4.2, `@Import` also supports references to regular component
+classes, analogous to the `AnnotationConfigApplicationContext.register` method.
+This is particularly useful if you want to avoid component scanning, by using a few
+configuration classes as entry points to explicitly define all your components.
+
+[[beans-java-injecting-imported-beans]]
+=== Injecting Dependencies on Imported `@Bean` Definitions
+
+The preceding example works but is simplistic. In most practical scenarios, beans have
+dependencies on one another across configuration classes. When using XML, this is not an
+issue, because no compiler is involved, and you can declare
+`ref="someBean"` and trust Spring to work it out during container initialization.
+When using `@Configuration` classes, the Java compiler places constraints on
+the configuration model, in that references to other beans must be valid Java syntax.
+
+Fortunately, solving this problem is simple. As xref:core/beans/java/bean-annotation.adoc#beans-java-dependencies[we already discussed],
+a `@Bean` method can have an arbitrary number of parameters that describe the bean
+dependencies. Consider the following more real-world scenario with several `@Configuration`
+classes, each depending on beans declared in the others:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class ServiceConfig {
+
+ @Bean
+ public TransferService transferService(AccountRepository accountRepository) {
+ return new TransferServiceImpl(accountRepository);
+ }
+ }
+
+ @Configuration
+ public class RepositoryConfig {
+
+ @Bean
+ public AccountRepository accountRepository(DataSource dataSource) {
+ return new JdbcAccountRepository(dataSource);
+ }
+ }
+
+ @Configuration
+ @Import({ServiceConfig.class, RepositoryConfig.class})
+ public class SystemTestConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ // return new DataSource
+ }
+ }
+
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
+ // everything wires up across configuration classes...
+ TransferService transferService = ctx.getBean(TransferService.class);
+ transferService.transfer(100.00, "A123", "C456");
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ @Configuration
+ class ServiceConfig {
+
+ @Bean
+ fun transferService(accountRepository: AccountRepository): TransferService {
+ return TransferServiceImpl(accountRepository)
+ }
+ }
+
+ @Configuration
+ class RepositoryConfig {
+
+ @Bean
+ fun accountRepository(dataSource: DataSource): AccountRepository {
+ return JdbcAccountRepository(dataSource)
+ }
+ }
+
+ @Configuration
+ @Import(ServiceConfig::class, RepositoryConfig::class)
+ class SystemTestConfig {
+
+ @Bean
+ fun dataSource(): DataSource {
+ // return new DataSource
+ }
+ }
+
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(SystemTestConfig::class.java)
+ // everything wires up across configuration classes...
+ val transferService = ctx.getBean()
+ transferService.transfer(100.00, "A123", "C456")
+ }
+----
+======
+
+
+There is another way to achieve the same result. Remember that `@Configuration` classes are
+ultimately only another bean in the container: This means that they can take advantage of
+`@Autowired` and `@Value` injection and other features the same as any other bean.
+
+[WARNING]
+====
+Make sure that the dependencies you inject that way are of the simplest kind only. `@Configuration`
+classes are processed quite early during the initialization of the context, and forcing a dependency
+to be injected this way may lead to unexpected early initialization. Whenever possible, resort to
+parameter-based injection, as in the preceding example.
+
+Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProcessor` definitions
+through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the
+instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not
+work on the configuration class itself, since it is possible to create it as a bean instance earlier than
+{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].
+====
+
+The following example shows how one bean can be autowired to another bean:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class ServiceConfig {
+
+ @Autowired
+ private AccountRepository accountRepository;
+
+ @Bean
+ public TransferService transferService() {
+ return new TransferServiceImpl(accountRepository);
+ }
+ }
+
+ @Configuration
+ public class RepositoryConfig {
+
+ private final DataSource dataSource;
+
+ public RepositoryConfig(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ @Bean
+ public AccountRepository accountRepository() {
+ return new JdbcAccountRepository(dataSource);
+ }
+ }
+
+ @Configuration
+ @Import({ServiceConfig.class, RepositoryConfig.class})
+ public class SystemTestConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ // return new DataSource
+ }
+ }
+
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
+ // everything wires up across configuration classes...
+ TransferService transferService = ctx.getBean(TransferService.class);
+ transferService.transfer(100.00, "A123", "C456");
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ @Configuration
+ class ServiceConfig {
+
+ @Autowired
+ lateinit var accountRepository: AccountRepository
+
+ @Bean
+ fun transferService(): TransferService {
+ return TransferServiceImpl(accountRepository)
+ }
+ }
+
+ @Configuration
+ class RepositoryConfig(private val dataSource: DataSource) {
+
+ @Bean
+ fun accountRepository(): AccountRepository {
+ return JdbcAccountRepository(dataSource)
+ }
+ }
+
+ @Configuration
+ @Import(ServiceConfig::class, RepositoryConfig::class)
+ class SystemTestConfig {
+
+ @Bean
+ fun dataSource(): DataSource {
+ // return new DataSource
+ }
+ }
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(SystemTestConfig::class.java)
+ // everything wires up across configuration classes...
+ val transferService = ctx.getBean()
+ transferService.transfer(100.00, "A123", "C456")
+ }
+----
+======
+
+TIP: Constructor injection in `@Configuration` classes is only supported as of Spring
+Framework 4.3. Note also that there is no need to specify `@Autowired` if the target
+bean defines only one constructor.
+
+.[[beans-java-injecting-imported-beans-fq]]Fully-qualifying imported beans for ease of navigation
+--
+In the preceding scenario, using `@Autowired` works well and provides the desired
+modularity, but determining exactly where the autowired bean definitions are declared is
+still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do
+you know exactly where the `@Autowired AccountRepository` bean is declared? It is not
+explicit in the code, and this may be just fine. Remember that the
+https://spring.io/tools[Spring Tools for Eclipse] provides tooling that
+can render graphs showing how everything is wired, which may be all you need. Also,
+your Java IDE can easily find all declarations and uses of the `AccountRepository` type
+and quickly show you the location of `@Bean` methods that return that type.
+
+In cases where this ambiguity is not acceptable and you wish to have direct navigation
+from within your IDE from one `@Configuration` class to another, consider autowiring the
+configuration classes themselves. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class ServiceConfig {
+
+ @Autowired
+ private RepositoryConfig repositoryConfig;
+
+ @Bean
+ public TransferService transferService() {
+ // navigate 'through' the config class to the @Bean method!
+ return new TransferServiceImpl(repositoryConfig.accountRepository());
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+@Configuration
+class ServiceConfig {
+
+ @Autowired
+ private lateinit var repositoryConfig: RepositoryConfig
+
+ @Bean
+ fun transferService(): TransferService {
+ // navigate 'through' the config class to the @Bean method!
+ return TransferServiceImpl(repositoryConfig.accountRepository())
+ }
+}
+----
+======
+
+In the preceding situation, where `AccountRepository` is defined is completely explicit.
+However, `ServiceConfig` is now tightly coupled to `RepositoryConfig`. That is the
+tradeoff. This tight coupling can be somewhat mitigated by using interface-based or
+abstract class-based `@Configuration` classes. Consider the following example:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class ServiceConfig {
+
+ @Autowired
+ private RepositoryConfig repositoryConfig;
+
+ @Bean
+ public TransferService transferService() {
+ return new TransferServiceImpl(repositoryConfig.accountRepository());
+ }
+ }
+
+ @Configuration
+ public interface RepositoryConfig {
+
+ @Bean
+ AccountRepository accountRepository();
+ }
+
+ @Configuration
+ public class DefaultRepositoryConfig implements RepositoryConfig {
+
+ @Bean
+ public AccountRepository accountRepository() {
+ return new JdbcAccountRepository(...);
+ }
+ }
+
+ @Configuration
+ @Import({ServiceConfig.class, DefaultRepositoryConfig.class}) // import the concrete config!
+ public class SystemTestConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ // return DataSource
+ }
+
+ }
+
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
+ TransferService transferService = ctx.getBean(TransferService.class);
+ transferService.transfer(100.00, "A123", "C456");
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ @Configuration
+ class ServiceConfig {
+
+ @Autowired
+ private lateinit var repositoryConfig: RepositoryConfig
+
+ @Bean
+ fun transferService(): TransferService {
+ return TransferServiceImpl(repositoryConfig.accountRepository())
+ }
+ }
+
+ @Configuration
+ interface RepositoryConfig {
+
+ @Bean
+ fun accountRepository(): AccountRepository
+ }
+
+ @Configuration
+ class DefaultRepositoryConfig : RepositoryConfig {
+
+ @Bean
+ fun accountRepository(): AccountRepository {
+ return JdbcAccountRepository(...)
+ }
+ }
+
+ @Configuration
+ @Import(ServiceConfig::class, DefaultRepositoryConfig::class) // import the concrete config!
+ class SystemTestConfig {
+
+ @Bean
+ fun dataSource(): DataSource {
+ // return DataSource
+ }
+
+ }
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(SystemTestConfig::class.java)
+ val transferService = ctx.getBean()
+ transferService.transfer(100.00, "A123", "C456")
+ }
+----
+======
+
+Now `ServiceConfig` is loosely coupled with respect to the concrete
+`DefaultRepositoryConfig`, and built-in IDE tooling is still useful: You can easily
+get a type hierarchy of `RepositoryConfig` implementations. In this
+way, navigating `@Configuration` classes and their dependencies becomes no different
+than the usual process of navigating interface-based code.
+--
+
+TIP: If you want to influence the startup creation order of certain beans, consider
+declaring some of them as `@Lazy` (for creation on first access instead of on startup)
+or as `@DependsOn` certain other beans (making sure that specific other beans are
+created before the current bean, beyond what the latter's direct dependencies imply).
+
+
+[[beans-java-conditional]]
+== Conditionally Include `@Configuration` Classes or `@Bean` Methods
+
+It is often useful to conditionally enable or disable a complete `@Configuration` class
+or even individual `@Bean` methods, based on some arbitrary system state. One common
+example of this is to use the `@Profile` annotation to activate beans only when a specific
+profile has been enabled in the Spring `Environment` (see xref:core/beans/environment.adoc#beans-definition-profiles[Bean Definition Profiles]
+for details).
+
+The `@Profile` annotation is actually implemented by using a much more flexible annotation
+called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].
+The `@Conditional` annotation indicates specific
+`org.springframework.context.annotation.Condition` implementations that should be
+consulted before a `@Bean` is registered.
+
+Implementations of the `Condition` interface provide a `matches(...)`
+method that returns `true` or `false`. For example, the following listing shows the actual
+`Condition` implementation used for `@Profile`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ // Read the @Profile annotation attributes
+ MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
+ if (attrs != null) {
+ for (Object value : attrs.get("value")) {
+ if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ override fun matches(context: ConditionContext, metadata: AnnotatedTypeMetadata): Boolean {
+ // Read the @Profile annotation attributes
+ 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))) {
+ return true
+ }
+ }
+ return false
+ }
+ return true
+ }
+----
+======
+
+See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]
+javadoc for more detail.
+
+
+[[beans-java-combining]]
+== Combining Java and XML Configuration
+
+Spring's `@Configuration` class support does not aim to be a 100% complete replacement
+for Spring XML. Some facilities, such as Spring XML namespaces, remain an ideal way to
+configure the container. In cases where XML is convenient or necessary, you have a
+choice: either instantiate the container in an "`XML-centric`" way by using, for example,
+`ClassPathXmlApplicationContext`, or instantiate it in a "`Java-centric`" way by using
+`AnnotationConfigApplicationContext` and the `@ImportResource` annotation to import XML
+as needed.
+
+[[beans-java-combining-xml-centric]]
+=== XML-centric Use of `@Configuration` Classes
+
+It may be preferable to bootstrap the Spring container from XML and include
+`@Configuration` classes in an ad-hoc fashion. For example, in a large existing codebase
+that uses Spring XML, it is easier to create `@Configuration` classes on an
+as-needed basis and include them from the existing XML files. Later in this section, we cover the
+options for using `@Configuration` classes in this kind of "`XML-centric`" situation.
+
+.[[beans-java-combining-xml-centric-declare-as-bean]]Declaring `@Configuration` classes as plain Spring `` elements
+--
+Remember that `@Configuration` classes are ultimately bean definitions in the
+container. In this series examples, we create a `@Configuration` class named `AppConfig` and
+include it within `system-test-config.xml` as a `` definition. Because
+`` is switched on, the container recognizes the
+`@Configuration` annotation and processes the `@Bean` methods declared in `AppConfig`
+properly.
+
+The following example shows an ordinary configuration class in Java:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Autowired
+ private DataSource dataSource;
+
+ @Bean
+ public AccountRepository accountRepository() {
+ return new JdbcAccountRepository(dataSource);
+ }
+
+ @Bean
+ public TransferService transferService() {
+ return new TransferService(accountRepository());
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Autowired
+ private lateinit var dataSource: DataSource
+
+ @Bean
+ fun accountRepository(): AccountRepository {
+ return JdbcAccountRepository(dataSource)
+ }
+
+ @Bean
+ fun transferService() = TransferService(accountRepository())
+ }
+----
+======
+
+The following example shows part of a sample `system-test-config.xml` file:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+The following example shows a possible `jdbc.properties` file:
+
+[literal,subs="verbatim,quotes"]
+----
+jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
+jdbc.username=sa
+jdbc.password=
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml");
+ TransferService transferService = ctx.getBean(TransferService.class);
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun main() {
+ val ctx = ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml")
+ val transferService = ctx.getBean()
+ // ...
+ }
+----
+======
+
+
+NOTE: In `system-test-config.xml` file, the `AppConfig` `` does not declare an `id`
+element. While it would be acceptable to do so, it is unnecessary, given that no other bean
+ever refers to it, and it is unlikely to be explicitly fetched from the container by name.
+Similarly, the `DataSource` bean is only ever autowired by type, so an explicit bean `id`
+is not strictly required.
+--
+
+.[[beans-java-combining-xml-centric-component-scan]] Using to pick up `@Configuration` classes
+--
+Because `@Configuration` is meta-annotated with `@Component`, `@Configuration`-annotated
+classes are automatically candidates for component scanning. Using the same scenario as
+described in the previous example, we can redefine `system-test-config.xml` to take advantage of component-scanning.
+Note that, in this case, we need not explicitly declare
+``, because `` enables the same
+functionality.
+
+The following example shows the modified `system-test-config.xml` file:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+----
+--
+
+[[beans-java-combining-java-centric]]
+=== `@Configuration` Class-centric Use of XML with `@ImportResource`
+
+In applications where `@Configuration` classes are the primary mechanism for configuring
+the container, it is still likely necessary to use at least some XML. In these
+scenarios, you can use `@ImportResource` and define only as much XML as you need. Doing
+so achieves a "`Java-centric`" approach to configuring the container and keeps XML to a
+bare minimum. The following example (which includes a configuration class, an XML file
+that defines a bean, a properties file, and the `main` class) shows how to use
+the `@ImportResource` annotation to achieve "`Java-centric`" configuration that uses XML
+as needed:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ImportResource("classpath:/com/acme/properties-config.xml")
+ public class AppConfig {
+
+ @Value("${jdbc.url}")
+ private String url;
+
+ @Value("${jdbc.username}")
+ private String username;
+
+ @Value("${jdbc.password}")
+ private String password;
+
+ @Bean
+ public DataSource dataSource() {
+ return new DriverManagerDataSource(url, username, password);
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ImportResource("classpath:/com/acme/properties-config.xml")
+ class AppConfig {
+
+ @Value("\${jdbc.url}")
+ private lateinit var url: String
+
+ @Value("\${jdbc.username}")
+ private lateinit var username: String
+
+ @Value("\${jdbc.password}")
+ private lateinit var password: String
+
+ @Bean
+ fun dataSource(): DataSource {
+ return DriverManagerDataSource(url, username, password)
+ }
+ }
+----
+======
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+ properties-config.xml
+
+
+
+----
+
+[literal,subs="verbatim,quotes"]
+----
+jdbc.properties
+jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
+jdbc.username=sa
+jdbc.password=
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+ TransferService transferService = ctx.getBean(TransferService.class);
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(AppConfig::class.java)
+ val transferService = ctx.getBean()
+ // ...
+ }
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/java/configuration-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/configuration-annotation.adoc
new file mode 100644
index 000000000000..d265db7e7585
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/java/configuration-annotation.adoc
@@ -0,0 +1,264 @@
+[[beans-java-configuration-annotation]]
+= 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 `@Bean`-annotated
+methods. Calls to `@Bean` methods on `@Configuration` classes can also be used to define
+inter-bean dependencies. See xref:core/beans/java/basic-concepts.adoc[Basic Concepts: `@Bean` and `@Configuration`] for a general introduction.
+
+
+[[beans-java-injecting-dependencies]]
+== Injecting Inter-bean Dependencies
+
+When beans have dependencies on one another, expressing that dependency is as simple
+as having one bean method call another, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public BeanOne beanOne() {
+ return new BeanOne(beanTwo());
+ }
+
+ @Bean
+ public BeanTwo beanTwo() {
+ return new BeanTwo();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun beanOne() = BeanOne(beanTwo())
+
+ @Bean
+ fun beanTwo() = BeanTwo()
+ }
+----
+======
+
+In the preceding example, `beanOne` receives a reference to `beanTwo` through constructor
+injection.
+
+NOTE: This method of declaring inter-bean dependencies works only when the `@Bean` method
+is declared within a `@Configuration` class. You cannot declare inter-bean dependencies
+by using plain `@Component` classes.
+
+
+
+[[beans-java-method-injection]]
+== Lookup Method Injection
+
+As noted earlier, xref:core/beans/dependencies/factory-method-injection.adoc[lookup method injection] is an
+advanced feature that you should use rarely. It is useful in cases where a
+singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this
+type of configuration provides a natural means for implementing this pattern. The
+following example shows how to use lookup method injection:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public abstract class CommandManager {
+ public Object process(Object commandState) {
+ // grab a new instance of the appropriate Command interface
+ Command command = createCommand();
+ // set the state on the (hopefully brand new) Command instance
+ command.setState(commandState);
+ return command.execute();
+ }
+
+ // okay... but where is the implementation of this method?
+ protected abstract Command createCommand();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ abstract class CommandManager {
+ fun process(commandState: Any): Any {
+ // grab a new instance of the appropriate Command interface
+ val command = createCommand()
+ // set the state on the (hopefully brand new) Command instance
+ command.setState(commandState)
+ return command.execute()
+ }
+
+ // okay... but where is the implementation of this method?
+ protected abstract fun createCommand(): Command
+ }
+----
+======
+
+By using Java configuration, you can create a subclass of `CommandManager` where
+the abstract `createCommand()` method is overridden in such a way that it looks up a new
+(prototype) command object. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Bean
+ @Scope("prototype")
+ public AsyncCommand asyncCommand() {
+ AsyncCommand command = new AsyncCommand();
+ // inject dependencies here as required
+ return command;
+ }
+
+ @Bean
+ public CommandManager commandManager() {
+ // return new anonymous implementation of CommandManager with createCommand()
+ // overridden to return a new prototype Command object
+ return new CommandManager() {
+ protected Command createCommand() {
+ return asyncCommand();
+ }
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Bean
+ @Scope("prototype")
+ fun asyncCommand(): AsyncCommand {
+ val command = AsyncCommand()
+ // inject dependencies here as required
+ return command
+ }
+
+ @Bean
+ fun commandManager(): CommandManager {
+ // return new anonymous implementation of CommandManager with createCommand()
+ // overridden to return a new prototype Command object
+ return object : CommandManager() {
+ override fun createCommand(): Command {
+ return asyncCommand()
+ }
+ }
+ }
+----
+======
+
+
+[[beans-java-further-information-java-config]]
+== Further Information About How Java-based Configuration Works Internally
+
+Consider the following example, which shows a `@Bean` annotated method being called twice:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public ClientService clientService1() {
+ ClientServiceImpl clientService = new ClientServiceImpl();
+ clientService.setClientDao(clientDao());
+ return clientService;
+ }
+
+ @Bean
+ public ClientService clientService2() {
+ ClientServiceImpl clientService = new ClientServiceImpl();
+ clientService.setClientDao(clientDao());
+ return clientService;
+ }
+
+ @Bean
+ public ClientDao clientDao() {
+ return new ClientDaoImpl();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun clientService1(): ClientService {
+ return ClientServiceImpl().apply {
+ clientDao = clientDao()
+ }
+ }
+
+ @Bean
+ fun clientService2(): ClientService {
+ return ClientServiceImpl().apply {
+ clientDao = clientDao()
+ }
+ }
+
+ @Bean
+ fun clientDao(): ClientDao {
+ return ClientDaoImpl()
+ }
+ }
+----
+======
+
+`clientDao()` has been called once in `clientService1()` and once in `clientService2()`.
+Since this method creates a new instance of `ClientDaoImpl` and returns it, you would
+normally expect to have two instances (one for each service). That definitely would be
+problematic: In Spring, instantiated beans have a `singleton` scope by default. This is
+where the magic comes in: All `@Configuration` classes are subclassed at startup-time
+with `CGLIB`. In the subclass, the child method checks the container first for any
+cached (scoped) beans before it calls the parent method and creates a new instance.
+
+NOTE: The behavior could be different according to the scope of your bean. We are talking
+about singletons here.
+
+[NOTE]
+====
+It is not necessary to add CGLIB to your classpath because CGLIB classes are repackaged
+under the `org.springframework.cglib` package and included directly within the
+`spring-core` JAR.
+====
+
+[TIP]
+====
+There are a few restrictions due to the fact that CGLIB dynamically adds features at
+startup-time. In particular, configuration classes must not be final. However, any
+constructors are allowed on configuration classes, including the use of `@Autowired` or a
+single non-default constructor declaration for default injection.
+
+If you prefer to avoid any CGLIB-imposed limitations, consider declaring your `@Bean`
+methods on non-`@Configuration` classes (for example, on plain `@Component` classes
+instead) or by annotating your configuration class with
+`@Configuration(proxyBeanMethods = false)`. Cross-method calls between `@Bean` methods
+are then not intercepted, so you have to exclusively rely on dependency injection at the
+constructor or method level there.
+====
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc
new file mode 100644
index 000000000000..e9c98ea126a9
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc
@@ -0,0 +1,283 @@
+[[beans-java-instantiating-container]]
+= Instantiating the Spring Container by Using `AnnotationConfigApplicationContext`
+
+The following sections document Spring's `AnnotationConfigApplicationContext`, introduced in Spring
+3.0. This versatile `ApplicationContext` implementation is capable of accepting not only
+`@Configuration` classes as input but also plain `@Component` classes and classes
+annotated with JSR-330 metadata.
+
+When `@Configuration` classes are provided as input, the `@Configuration` class itself
+is registered as a bean definition and all declared `@Bean` methods within the class
+are also registered as bean definitions.
+
+When `@Component` and JSR-330 classes are provided, they are registered as bean
+definitions, and it is assumed that DI metadata such as `@Autowired` or `@Inject` are
+used within those classes where necessary.
+
+
+[[beans-java-instantiating-container-constructor]]
+== Simple Construction
+
+In much the same way that Spring XML files are used as input when instantiating a
+`ClassPathXmlApplicationContext`, you can use `@Configuration` classes as input when
+instantiating an `AnnotationConfigApplicationContext`. This allows for completely
+XML-free usage of the Spring container, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+ MyService myService = ctx.getBean(MyService.class);
+ myService.doStuff();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(AppConfig::class.java)
+ val myService = ctx.getBean()
+ myService.doStuff()
+ }
+----
+======
+
+As mentioned earlier, `AnnotationConfigApplicationContext` is not limited to working only
+with `@Configuration` classes. Any `@Component` or JSR-330 annotated class may be supplied
+as input to the constructor, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
+ MyService myService = ctx.getBean(MyService.class);
+ myService.doStuff();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext(MyServiceImpl::class.java, Dependency1::class.java, Dependency2::class.java)
+ val myService = ctx.getBean()
+ myService.doStuff()
+ }
+----
+======
+
+The preceding example assumes that `MyServiceImpl`, `Dependency1`, and `Dependency2` use Spring
+dependency injection annotations such as `@Autowired`.
+
+
+[[beans-java-instantiating-container-register]]
+== Building the Container Programmatically by Using `register(Class>...)`
+
+You can instantiate an `AnnotationConfigApplicationContext` by using a no-arg constructor
+and then configure it by using the `register()` method. This approach is particularly useful
+when programmatically building an `AnnotationConfigApplicationContext`. The following
+example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(AppConfig.class, OtherConfig.class);
+ ctx.register(AdditionalConfig.class);
+ ctx.refresh();
+ MyService myService = ctx.getBean(MyService.class);
+ myService.doStuff();
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.beans.factory.getBean
+
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext()
+ ctx.register(AppConfig::class.java, OtherConfig::class.java)
+ ctx.register(AdditionalConfig::class.java)
+ ctx.refresh()
+ val myService = ctx.getBean()
+ myService.doStuff()
+ }
+----
+======
+
+
+[[beans-java-instantiating-container-scan]]
+== Enabling Component Scanning with `scan(String...)`
+
+To enable component scanning, you can annotate your `@Configuration` class as follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "com.acme") // <1>
+ public class AppConfig {
+ // ...
+ }
+----
+======
+<1> This annotation enables component scanning.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ @Configuration
+ @ComponentScan(basePackages = ["com.acme"]) // <1>
+ class AppConfig {
+ // ...
+ }
+----
+<1> This annotation enables component scanning.
+
+
+[TIP]
+=====
+Experienced Spring users may be familiar with the XML declaration equivalent from
+Spring's `context:` namespace, shown in the following example:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+=====
+
+In the preceding example, the `com.acme` package is scanned to look for any
+`@Component`-annotated classes, and those classes are registered as Spring bean
+definitions within the container. `AnnotationConfigApplicationContext` exposes the
+`scan(String...)` method to allow for the same component-scanning functionality, as the
+following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public static void main(String[] args) {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.scan("com.acme");
+ ctx.refresh();
+ MyService myService = ctx.getBean(MyService.class);
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun main() {
+ val ctx = AnnotationConfigApplicationContext()
+ ctx.scan("com.acme")
+ ctx.refresh()
+ val myService = ctx.getBean()
+ }
+----
+======
+
+NOTE: Remember that `@Configuration` classes are xref:core/beans/classpath-scanning.adoc#beans-meta-annotations[meta-annotated]
+with `@Component`, so they are candidates for component-scanning. In the preceding example,
+assuming that `AppConfig` is declared within the `com.acme` package (or any package
+underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean`
+methods are processed and registered as bean definitions within the container.
+
+
+[[beans-java-instantiating-container-web]]
+== Support for Web Applications with `AnnotationConfigWebApplicationContext`
+
+A `WebApplicationContext` variant of `AnnotationConfigApplicationContext` is available
+with `AnnotationConfigWebApplicationContext`. You can use this implementation when
+configuring the Spring `ContextLoaderListener` servlet listener, Spring MVC
+`DispatcherServlet`, and so forth. The following `web.xml` snippet configures a typical
+Spring MVC web application (note the use of the `contextClass` context-param and
+init-param):
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+ contextClass
+
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+
+
+
+
+
+ contextConfigLocation
+ com.acme.AppConfig
+
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ dispatcher
+ org.springframework.web.servlet.DispatcherServlet
+
+
+ contextClass
+
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+
+
+
+
+ contextConfigLocation
+ com.acme.web.MvcConfig
+
+
+
+
+
+ dispatcher
+ /app/*
+
+
+----
+
+NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an
+alternative to `AnnotationConfigWebApplicationContext`. See the
+{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]
+javadoc for details.
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/beans/standard-annotations.adoc b/framework-docs/modules/ROOT/pages/core/beans/standard-annotations.adoc
new file mode 100644
index 000000000000..d9929bea3d03
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/beans/standard-annotations.adoc
@@ -0,0 +1,393 @@
+[[beans-standard-annotations]]
+= Using JSR 330 Standard Annotations
+
+Spring offers support for JSR-330 standard annotations (Dependency Injection). Those
+annotations are scanned in the same way as the Spring annotations. To use them, you need
+to have the relevant jars in your classpath.
+
+[NOTE]
+=====
+If you use Maven, the `jakarta.inject` artifact is available in the standard Maven
+repository (
+https://repo.maven.apache.org/maven2/jakarta/inject/jakarta.inject-api/2.0.0/[https://repo.maven.apache.org/maven2/jakarta/inject/jakarta.inject-api/2.0.0/]).
+You can add the following dependency to your file pom.xml:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+ jakarta.inject
+ jakarta.inject-api
+ 2.0.0
+
+----
+=====
+
+
+
+[[beans-inject-named]]
+== Dependency Injection with `@Inject` and `@Named`
+
+Instead of `@Autowired`, you can use `@jakarta.inject.Inject` as follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.inject.Inject;
+
+ public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ public void listMovies() {
+ this.movieFinder.findMovies(...);
+ // ...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.inject.Inject
+
+ class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: MovieFinder
+
+
+ fun listMovies() {
+ movieFinder.findMovies(...)
+ // ...
+ }
+ }
+----
+======
+
+As with `@Autowired`, you can use `@Inject` at the field level, method level
+and constructor-argument level. Furthermore, you may declare your injection point as a
+`Provider`, allowing for on-demand access to beans of shorter scopes or lazy access to
+other beans through a `Provider.get()` call. The following example offers a variant of the
+preceding example:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.inject.Inject;
+ import jakarta.inject.Provider;
+
+ public class SimpleMovieLister {
+
+ private Provider movieFinder;
+
+ @Inject
+ public void setMovieFinder(Provider movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ public void listMovies() {
+ this.movieFinder.get().findMovies(...);
+ // ...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.inject.Inject
+
+ class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: Provider
+
+
+ fun listMovies() {
+ movieFinder.get().findMovies(...)
+ // ...
+ }
+ }
+----
+======
+
+If you would like to use a qualified name for the dependency that should be injected,
+you should use the `@Named` annotation, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.inject.Inject;
+ import jakarta.inject.Named;
+
+ public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.inject.Inject
+ import jakarta.inject.Named
+
+ class SimpleMovieLister {
+
+ private lateinit var movieFinder: MovieFinder
+
+ @Inject
+ fun setMovieFinder(@Named("main") movieFinder: MovieFinder) {
+ this.movieFinder = movieFinder
+ }
+
+ // ...
+ }
+----
+======
+
+As with `@Autowired`, `@Inject` can also be used with `java.util.Optional` or
+`@Nullable`. This is even more applicable here, since `@Inject` does not have
+a `required` attribute. The following pair of examples show how to use `@Inject` and
+`@Nullable`:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public class SimpleMovieLister {
+
+ @Inject
+ public void setMovieFinder(Optional movieFinder) {
+ // ...
+ }
+ }
+----
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class SimpleMovieLister {
+
+ @Inject
+ public void setMovieFinder(@Nullable MovieFinder movieFinder) {
+ // ...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class SimpleMovieLister {
+
+ @Inject
+ var movieFinder: MovieFinder? = null
+ }
+----
+======
+
+
+
+[[beans-named]]
+== `@Named` and `@ManagedBean`: Standard Equivalents to the `@Component` Annotation
+
+Instead of `@Component`, you can use `@jakarta.inject.Named` or `jakarta.annotation.ManagedBean`,
+as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.inject.Inject;
+ import jakarta.inject.Named;
+
+ @Named("movieListener") // @ManagedBean("movieListener") could be used as well
+ public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.inject.Inject
+ import jakarta.inject.Named
+
+ @Named("movieListener") // @ManagedBean("movieListener") could be used as well
+ class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: MovieFinder
+
+ // ...
+ }
+----
+======
+
+It is very common to use `@Component` without specifying a name for the component.
+`@Named` can be used in a similar fashion, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.inject.Inject;
+ import jakarta.inject.Named;
+
+ @Named
+ public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.inject.Inject
+ import jakarta.inject.Named
+
+ @Named
+ class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: MovieFinder
+
+ // ...
+ }
+----
+======
+
+When you use `@Named` or `@ManagedBean`, you can use component scanning in the
+exact same way as when you use Spring annotations, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = "org.example")
+ public class AppConfig {
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ @ComponentScan(basePackages = ["org.example"])
+ class AppConfig {
+ // ...
+ }
+----
+======
+
+NOTE: In contrast to `@Component`, the JSR-330 `@Named` and the JSR-250 `@ManagedBean`
+annotations are not composable. You should use Spring's stereotype model for building
+custom component annotations.
+
+
+
+[[beans-standard-annotations-limitations]]
+== Limitations of JSR-330 Standard Annotations
+
+When you work with standard annotations, you should know that some significant
+features are not available, as the following table shows:
+
+[[annotations-comparison]]
+.Spring component model elements versus JSR-330 variants
+|===
+| Spring| jakarta.inject.*| jakarta.inject restrictions / comments
+
+| @Autowired
+| @Inject
+| `@Inject` has no 'required' attribute. Can be used with Java 8's `Optional` instead.
+
+| @Component
+| @Named / @ManagedBean
+| JSR-330 does not provide a composable model, only a way to identify named components.
+
+| @Scope("singleton")
+| @Singleton
+| The JSR-330 default scope is like Spring's `prototype`. However, in order to keep it
+ consistent with Spring's general defaults, a JSR-330 bean declared in the Spring
+ container is a `singleton` by default. In order to use a scope other than `singleton`,
+ you should use Spring's `@Scope` annotation. `jakarta.inject` also provides a
+ `jakarta.inject.Scope` annotation: however, this one is only intended to be used
+ for creating custom annotations.
+
+| @Qualifier
+| @Qualifier / @Named
+| `jakarta.inject.Qualifier` is just a meta-annotation for building custom qualifiers.
+ Concrete `String` qualifiers (like Spring's `@Qualifier` with a value) can be associated
+ through `jakarta.inject.Named`.
+
+| @Value
+| -
+| no equivalent
+
+| @Lazy
+| -
+| no equivalent
+
+| ObjectFactory
+| Provider
+| `jakarta.inject.Provider` is a direct alternative to Spring's `ObjectFactory`,
+ only with a shorter `get()` method name. It can also be used in combination with
+ Spring's `@Autowired` or with non-annotated constructors and setter methods.
+|===
+
+
+
diff --git a/framework-docs/src/docs/asciidoc/core/core-databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc
similarity index 90%
rename from framework-docs/src/docs/asciidoc/core/core-databuffer-codec.adoc
rename to framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc
index 1f9f6e995a07..a66ade956c27 100644
--- a/framework-docs/src/docs/asciidoc/core/core-databuffer-codec.adoc
+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc
@@ -8,10 +8,10 @@ XNIO, Jetty uses pooled byte buffers with a callback to be released, and so on.
The `spring-core` module provides a set of abstractions to work with various byte buffer
APIs as follows:
-* <> abstracts the creation of a data buffer.
-* <> represents a byte buffer, which may be
-<>.
-* <> offers utility methods for data buffers.
+* xref:core/databuffer-codec.adoc#databuffers-factory[`DataBufferFactory`] abstracts the creation of a data buffer.
+* xref:core/databuffer-codec.adoc#databuffers-buffer[`DataBuffer`] represents a byte buffer, which may be
+xref:core/databuffer-codec.adoc#databuffers-buffer-pooled[pooled].
+* xref:core/databuffer-codec.adoc#databuffers-utils[`DataBufferUtils`] offers utility methods for data buffers.
* <> decode or encode data buffer streams into higher level objects.
@@ -45,7 +45,7 @@ Below is a partial list of benefits:
* Read and write with independent positions, i.e. not requiring a call to `flip()` to
alternate between read and write.
* Capacity expanded on demand as with `java.lang.StringBuilder`.
-* Pooled buffers and reference counting via <>.
+* Pooled buffers and reference counting via xref:core/databuffer-codec.adoc#databuffers-buffer-pooled[`PooledDataBuffer`].
* View a buffer as `java.nio.ByteBuffer`, `InputStream`, or `OutputStream`.
* Determine the index, or the last index, for a given byte.
@@ -104,7 +104,7 @@ The `org.springframework.core.codec` package provides the following strategy int
The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and
`String` encoder and decoder implementations. The `spring-web` module adds Jackson JSON,
Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
-<> in the WebFlux section.
+xref:web/webflux/reactive-spring.adoc#webflux-codecs[Codecs] in the WebFlux section.
@@ -113,7 +113,7 @@ Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
== Using `DataBuffer`
When working with data buffers, special care must be taken to ensure buffers are released
-since they may be <>. We'll use codecs to illustrate
+since they may be xref:core/databuffer-codec.adoc#databuffers-buffer-pooled[pooled]. We'll use codecs to illustrate
how that works but the concepts apply more generally. Let's see what codecs must do
internally to manage data buffers.
@@ -140,8 +140,11 @@ An `Encoder` allocates data buffers that others must read (and release). So an `
doesn't have much to do. However an `Encoder` must take care to release a data buffer if
a serialization error occurs while populating the buffer with data. For example:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
DataBuffer buffer = factory.allocateBuffer();
boolean release = true;
@@ -156,8 +159,10 @@ a serialization error occurs while populating the buffer with data. For example:
}
return buffer;
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val buffer = factory.allocateBuffer()
var release = true
@@ -171,6 +176,7 @@ a serialization error occurs while populating the buffer with data. For example:
}
return buffer
----
+======
The consumer of an `Encoder` is responsible for releasing the data buffers it receives.
In a WebFlux application, the output of the `Encoder` is used to write to the HTTP server
diff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc
new file mode 100644
index 000000000000..a87addc06f54
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc
@@ -0,0 +1,57 @@
+[[expressions]]
+= Spring Expression Language (SpEL)
+
+The Spring Expression Language ("`SpEL`" for short) is a powerful expression language that
+supports querying and manipulating an object graph at runtime. The language syntax is
+similar to Unified EL but offers additional features, most notably method invocation and
+basic string templating functionality.
+
+While there are several other Java expression languages available -- OGNL, MVEL, and JBoss
+EL, to name a few -- the Spring Expression Language was created to provide the Spring
+community with a single well supported expression language that can be used across all
+the products in the Spring portfolio. Its language features are driven by the
+requirements of the projects in the Spring portfolio, including tooling requirements
+for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].
+That said, SpEL is based on a technology-agnostic API that lets other expression language
+implementations be integrated, should the need arise.
+
+While SpEL serves as the foundation for expression evaluation within the Spring
+portfolio, it is not directly tied to Spring and can be used independently. To
+be self contained, many of the examples in this chapter use SpEL as if it were an
+independent expression language. This requires creating a few bootstrapping
+infrastructure classes, such as the parser. Most Spring users need not deal with
+this infrastructure and can, instead, author only expression strings for evaluation.
+An example of this typical use is the integration of SpEL into creating XML or
+annotation-based bean definitions, as shown in
+xref:core/expressions/beandef.adoc[Expression support for defining bean definitions].
+
+This chapter covers the features of the expression language, its API, and its language
+syntax. In several places, `Inventor` and `Society` classes are used as the target
+objects for expression evaluation. These class declarations and the data used to
+populate them are listed at the end of the chapter.
+
+The expression language supports the following functionality:
+
+* Literal expressions
+* Boolean and relational operators
+* Regular expressions
+* Class expressions
+* Accessing properties, arrays, lists, and maps
+* Method invocation
+* Relational operators
+* Assignment
+* Calling constructors
+* Bean references
+* Array construction
+* Inline lists
+* Inline maps
+* Ternary operator
+* Variables
+* User-defined functions
+* Collection projection
+* Collection selection
+* Templated expressions
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/beandef.adoc b/framework-docs/modules/ROOT/pages/core/expressions/beandef.adoc
new file mode 100644
index 000000000000..7617ab15ef70
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/beandef.adoc
@@ -0,0 +1,219 @@
+[[expressions-beandef]]
+= Expressions in Bean Definitions
+
+You can use SpEL expressions with XML-based or annotation-based configuration metadata for
+defining `BeanDefinition` instances. In both cases, the syntax to define the expression is of the
+form `#{ }`.
+
+
+
+[[expressions-beandef-xml-based]]
+== XML Configuration
+
+A property or constructor argument value can be set by using expressions, as the following
+example shows:
+
+[source,xml,indent=0,subs="verbatim"]
+----
+
+
+
+
+
+----
+
+All beans in the application context are available as predefined variables with their
+common bean name. This includes standard context beans such as `environment` (of type
+`org.springframework.core.env.Environment`) as well as `systemProperties` and
+`systemEnvironment` (of type `Map`) for access to the runtime environment.
+
+The following example shows access to the `systemProperties` bean as a SpEL variable:
+
+[source,xml,indent=0,subs="verbatim"]
+----
+
+
+
+
+
+----
+
+Note that you do not have to prefix the predefined variable with the `#` symbol here.
+
+You can also refer to other bean properties by name, as the following example shows:
+
+[source,xml,indent=0,subs="verbatim"]
+----
+
+
+
+
+
+
+
+
+
+
+
+----
+
+
+
+[[expressions-beandef-annotation-based]]
+== Annotation Configuration
+
+To specify a default value, you can place the `@Value` annotation on fields, methods,
+and method or constructor parameters.
+
+The following example sets the default value of a field:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class FieldValueTestBean {
+
+ @Value("#{ systemProperties['user.region'] }")
+ private String defaultLocale;
+
+ public void setDefaultLocale(String defaultLocale) {
+ this.defaultLocale = defaultLocale;
+ }
+
+ public String getDefaultLocale() {
+ return this.defaultLocale;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class FieldValueTestBean {
+
+ @Value("#{ systemProperties['user.region'] }")
+ var defaultLocale: String? = null
+ }
+----
+======
+
+The following example shows the equivalent but on a property setter method:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class PropertyValueTestBean {
+
+ private String defaultLocale;
+
+ @Value("#{ systemProperties['user.region'] }")
+ public void setDefaultLocale(String defaultLocale) {
+ this.defaultLocale = defaultLocale;
+ }
+
+ public String getDefaultLocale() {
+ return this.defaultLocale;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class PropertyValueTestBean {
+
+ @Value("#{ systemProperties['user.region'] }")
+ var defaultLocale: String? = null
+ }
+----
+======
+
+Autowired methods and constructors can also use the `@Value` annotation, as the following
+examples show:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+ private String defaultLocale;
+
+ @Autowired
+ public void configure(MovieFinder movieFinder,
+ @Value("#{ systemProperties['user.region'] }") String defaultLocale) {
+ this.movieFinder = movieFinder;
+ this.defaultLocale = defaultLocale;
+ }
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class SimpleMovieLister {
+
+ private lateinit var movieFinder: MovieFinder
+ private lateinit var defaultLocale: String
+
+ @Autowired
+ fun configure(movieFinder: MovieFinder,
+ @Value("#{ systemProperties['user.region'] }") defaultLocale: String) {
+ this.movieFinder = movieFinder
+ this.defaultLocale = defaultLocale
+ }
+
+ // ...
+ }
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class MovieRecommender {
+
+ private String defaultLocale;
+
+ private CustomerPreferenceDao customerPreferenceDao;
+
+ public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
+ @Value("#{systemProperties['user.country']}") String defaultLocale) {
+ this.customerPreferenceDao = customerPreferenceDao;
+ this.defaultLocale = defaultLocale;
+ }
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class MovieRecommender(private val customerPreferenceDao: CustomerPreferenceDao,
+ @Value("#{systemProperties['user.country']}") private val defaultLocale: String) {
+ // ...
+ }
+----
+======
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc b/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc
new file mode 100644
index 000000000000..79b3f260b915
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/evaluation.adoc
@@ -0,0 +1,511 @@
+[[expressions-evaluation]]
+= Evaluation
+
+This section introduces the simple use of SpEL interfaces and its expression language.
+The complete language reference can be found in
+xref:core/expressions/language-ref.adoc[Language Reference].
+
+The following code introduces the SpEL API to evaluate the literal string expression,
+`Hello World`.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ Expression exp = parser.parseExpression("'Hello World'"); // <1>
+ String message = (String) exp.getValue();
+----
+======
+<1> The value of the message variable is `'Hello World'`.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ val parser = SpelExpressionParser()
+ val exp = parser.parseExpression("'Hello World'") // <1>
+ val message = exp.value as String
+----
+<1> The value of the message variable is `'Hello World'`.
+
+
+The SpEL classes and interfaces you are most likely to use are located in the
+`org.springframework.expression` package and its sub-packages, such as `spel.support`.
+
+The `ExpressionParser` interface is responsible for parsing an expression string. In
+the preceding example, the expression string is a string literal denoted by the surrounding single
+quotation marks. The `Expression` interface is responsible for evaluating the previously defined
+expression string. Two exceptions that can be thrown, `ParseException` and
+`EvaluationException`, when calling `parser.parseExpression` and `exp.getValue`,
+respectively.
+
+SpEL supports a wide range of features, such as calling methods, accessing properties,
+and calling constructors.
+
+In the following example of method invocation, we call the `concat` method on the string literal:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ Expression exp = parser.parseExpression("'Hello World'.concat('!')"); // <1>
+ String message = (String) exp.getValue();
+----
+======
+<1> The value of `message` is now 'Hello World!'.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ val parser = SpelExpressionParser()
+ val exp = parser.parseExpression("'Hello World'.concat('!')") // <1>
+ val message = exp.value as String
+----
+<1> The value of `message` is now 'Hello World!'.
+
+The following example of calling a JavaBean property calls the `String` property `Bytes`:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+
+ // invokes 'getBytes()'
+ Expression exp = parser.parseExpression("'Hello World'.bytes"); // <1>
+ byte[] bytes = (byte[]) exp.getValue();
+----
+======
+<1> This line converts the literal to a byte array.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ val parser = SpelExpressionParser()
+
+ // invokes 'getBytes()'
+ val exp = parser.parseExpression("'Hello World'.bytes") // <1>
+ val bytes = exp.value as ByteArray
+----
+<1> This line converts the literal to a byte array.
+
+SpEL also supports nested properties by using the standard dot notation (such as
+`prop1.prop2.prop3`) and also the corresponding setting of property values.
+Public fields may also be accessed.
+
+The following example shows how to use dot notation to get the length of a literal:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+
+ // invokes 'getBytes().length'
+ Expression exp = parser.parseExpression("'Hello World'.bytes.length"); // <1>
+ int length = (Integer) exp.getValue();
+----
+======
+<1> `'Hello World'.bytes.length` gives the length of the literal.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ val parser = SpelExpressionParser()
+
+ // invokes 'getBytes().length'
+ val exp = parser.parseExpression("'Hello World'.bytes.length") // <1>
+ val length = exp.value as Int
+----
+<1> `'Hello World'.bytes.length` gives the length of the literal.
+
+The String's constructor can be called instead of using a string literal, as the following
+example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ Expression exp = parser.parseExpression("new String('hello world').toUpperCase()"); // <1>
+ String message = exp.getValue(String.class);
+----
+======
+<1> Construct a new `String` from the literal and make it be upper case.
+
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+.Kotlin
+----
+ val parser = SpelExpressionParser()
+ val exp = parser.parseExpression("new String('hello world').toUpperCase()") // <1>
+ val message = exp.getValue(String::class.java)
+----
+<1> Construct a new `String` from the literal and make it be upper case.
+
+
+Note the use of the generic method: `public T getValue(Class desiredResultType)`.
+Using this method removes the need to cast the value of the expression to the desired
+result type. An `EvaluationException` is thrown if the value cannot be cast to the
+type `T` or converted by using the registered type converter.
+
+The more common usage of SpEL is to provide an expression string that is evaluated
+against a specific object instance (called the root object). The following example shows
+how to retrieve the `name` property from an instance of the `Inventor` class or
+create a boolean condition:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // Create and set a calendar
+ GregorianCalendar c = new GregorianCalendar();
+ c.set(1856, 7, 9);
+
+ // The constructor arguments are name, birthday, and nationality.
+ Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
+
+ ExpressionParser parser = new SpelExpressionParser();
+
+ Expression exp = parser.parseExpression("name"); // Parse name as an expression
+ String name = (String) exp.getValue(tesla);
+ // name == "Nikola Tesla"
+
+ exp = parser.parseExpression("name == 'Nikola Tesla'");
+ boolean result = exp.getValue(tesla, Boolean.class);
+ // result == true
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // Create and set a calendar
+ val c = GregorianCalendar()
+ c.set(1856, 7, 9)
+
+ // The constructor arguments are name, birthday, and nationality.
+ val tesla = Inventor("Nikola Tesla", c.time, "Serbian")
+
+ val parser = SpelExpressionParser()
+
+ var exp = parser.parseExpression("name") // Parse name as an expression
+ val name = exp.getValue(tesla) as String
+ // name == "Nikola Tesla"
+
+ exp = parser.parseExpression("name == 'Nikola Tesla'")
+ val result = exp.getValue(tesla, Boolean::class.java)
+ // result == true
+----
+======
+
+
+
+
+[[expressions-evaluation-context]]
+== Understanding `EvaluationContext`
+
+The `EvaluationContext` interface is used when evaluating an expression to resolve
+properties, methods, or fields and to help perform type conversion. Spring provides two
+implementations.
+
+* `SimpleEvaluationContext`: Exposes a subset of essential SpEL language features and
+configuration options, for categories of expressions that do not require the full extent
+of the SpEL language syntax and should be meaningfully restricted. Examples include but
+are not limited to data binding expressions and property-based filters.
+
+* `StandardEvaluationContext`: Exposes the full set of SpEL language features and
+configuration options. You can use it to specify a default root object and to configure
+every available evaluation-related strategy.
+
+`SimpleEvaluationContext` is designed to support only a subset of the SpEL language syntax.
+It excludes Java type references, constructors, and bean references. It also requires
+you to explicitly choose the level of support for properties and methods in expressions.
+By default, the `create()` static factory method enables only read access to properties.
+You can also obtain a builder to configure the exact level of support needed, targeting
+one or some combination of the following:
+
+* Custom `PropertyAccessor` only (no reflection)
+* Data binding properties for read-only access
+* Data binding properties for read and write
+
+
+[[expressions-type-conversion]]
+=== Type Conversion
+
+By default, SpEL uses the conversion service available in Spring core
+(`org.springframework.core.convert.ConversionService`). This conversion service comes
+with many built-in converters for common conversions but is also fully extensible so that
+you can add custom conversions between types. Additionally, it is
+generics-aware. This means that, when you work with generic types in
+expressions, SpEL attempts conversions to maintain type correctness for any objects
+it encounters.
+
+What does this mean in practice? Suppose assignment, using `setValue()`, is being used
+to set a `List` property. The type of the property is actually `List`. SpEL
+recognizes that the elements of the list need to be converted to `Boolean` before
+being placed in it. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ class Simple {
+ public List booleanList = new ArrayList<>();
+ }
+
+ Simple simple = new Simple();
+ simple.booleanList.add(true);
+
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
+
+ // "false" is passed in here as a String. SpEL and the conversion service
+ // will recognize that it needs to be a Boolean and convert it accordingly.
+ parser.parseExpression("booleanList[0]").setValue(context, simple, "false");
+
+ // b is false
+ Boolean b = simple.booleanList.get(0);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class Simple {
+ var booleanList: MutableList = ArrayList()
+ }
+
+ val simple = Simple()
+ simple.booleanList.add(true)
+
+ val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
+
+ // "false" is passed in here as a String. SpEL and the conversion service
+ // will recognize that it needs to be a Boolean and convert it accordingly.
+ parser.parseExpression("booleanList[0]").setValue(context, simple, "false")
+
+ // b is false
+ val b = simple.booleanList[0]
+----
+======
+
+
+[[expressions-parser-configuration]]
+== Parser Configuration
+
+It is possible to configure the SpEL expression parser by using a parser configuration
+object (`org.springframework.expression.spel.SpelParserConfiguration`). The configuration
+object controls the behavior of some of the expression components. For example, if you
+index into an array or collection and the element at the specified index is `null`, SpEL
+can automatically create the element. This is useful when using expressions made up of a
+chain of property references. If you index into an array or list and specify an index
+that is beyond the end of the current size of the array or list, SpEL can automatically
+grow the array or list to accommodate that index. In order to add an element at the
+specified index, SpEL will try to create the element using the element type's default
+constructor before setting the specified value. If the element type does not have a
+default constructor, `null` will be added to the array or list. If there is no built-in
+or custom converter that knows how to set the value, `null` will remain in the array or
+list at the specified index. The following example demonstrates how to automatically grow
+the list:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ class Demo {
+ public List list;
+ }
+
+ // Turn on:
+ // - auto null reference initialization
+ // - auto collection growing
+ SpelParserConfiguration config = new SpelParserConfiguration(true, true);
+
+ ExpressionParser parser = new SpelExpressionParser(config);
+
+ Expression expression = parser.parseExpression("list[3]");
+
+ Demo demo = new Demo();
+
+ Object o = expression.getValue(demo);
+
+ // demo.list will now be a real collection of 4 entries
+ // Each entry is a new empty String
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class Demo {
+ var list: List? = null
+ }
+
+ // Turn on:
+ // - auto null reference initialization
+ // - auto collection growing
+ val config = SpelParserConfiguration(true, true)
+
+ val parser = SpelExpressionParser(config)
+
+ val expression = parser.parseExpression("list[3]")
+
+ val demo = Demo()
+
+ val o = expression.getValue(demo)
+
+ // demo.list will now be a real collection of 4 entries
+ // Each entry is a new empty String
+----
+======
+
+
+
+[[expressions-spel-compilation]]
+== SpEL Compilation
+
+Spring Framework 4.1 includes a basic expression compiler. Expressions are usually
+interpreted, which provides a lot of dynamic flexibility during evaluation but
+does not provide optimum performance. For occasional expression usage,
+this is fine, but, when used by other components such as Spring Integration,
+performance can be very important, and there is no real need for the dynamism.
+
+The SpEL compiler is intended to address this need. During evaluation, the compiler
+generates a Java class that embodies the expression behavior at runtime and uses that
+class to achieve much faster expression evaluation. Due to the lack of typing around
+expressions, the compiler uses information gathered during the interpreted evaluations
+of an expression when performing compilation. For example, it does not know the type
+of a property reference purely from the expression, but during the first interpreted
+evaluation, it finds out what it is. Of course, basing compilation on such derived
+information can cause trouble later if the types of the various expression elements
+change over time. For this reason, compilation is best suited to expressions whose
+type information is not going to change on repeated evaluations.
+
+Consider the following basic expression:
+
+----
+someArray[0].someProperty.someOtherProperty < 0.1
+----
+
+Because the preceding expression involves array access, some property de-referencing,
+and numeric operations, the performance gain can be very noticeable. In an example
+micro benchmark run of 50000 iterations, it took 75ms to evaluate by using the
+interpreter and only 3ms using the compiled version of the expression.
+
+
+[[expressions-compiler-configuration]]
+=== Compiler Configuration
+
+The compiler is not turned on by default, but you can turn it on in either of two
+different ways. You can turn it on by using the parser configuration process
+(xref:core/expressions/evaluation.adoc#expressions-parser-configuration[discussed earlier]) or by using a Spring property
+when SpEL usage is embedded inside another component. This section discusses both of
+these options.
+
+The compiler can operate in one of three modes, which are captured in the
+`org.springframework.expression.spel.SpelCompilerMode` enum. The modes are as follows:
+
+* `OFF` (default): The compiler is switched off.
+* `IMMEDIATE`: In immediate mode, the expressions are compiled as soon as possible. This
+is typically after the first interpreted evaluation. If the compiled expression fails
+(typically due to a type changing, as described earlier), the caller of the expression
+evaluation receives an exception.
+* `MIXED`: In mixed mode, the expressions silently switch between interpreted and compiled
+mode over time. After some number of interpreted runs, they switch to compiled
+form and, if something goes wrong with the compiled form (such as a type changing, as
+described earlier), the expression automatically switches back to interpreted form
+again. Sometime later, it may generate another compiled form and switch to it. Basically,
+the exception that the user gets in `IMMEDIATE` mode is instead handled internally.
+
+`IMMEDIATE` mode exists because `MIXED` mode could cause issues for expressions that
+have side effects. If a compiled expression blows up after partially succeeding, it
+may have already done something that has affected the state of the system. If this
+has happened, the caller may not want it to silently re-run in interpreted mode,
+since part of the expression may be running twice.
+
+After selecting a mode, use the `SpelParserConfiguration` to configure the parser. The
+following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
+ this.getClass().getClassLoader());
+
+ SpelExpressionParser parser = new SpelExpressionParser(config);
+
+ Expression expr = parser.parseExpression("payload");
+
+ MyMessage message = new MyMessage();
+
+ Object payload = expr.getValue(message);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val config = SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
+ this.javaClass.classLoader)
+
+ val parser = SpelExpressionParser(config)
+
+ val expr = parser.parseExpression("payload")
+
+ val message = MyMessage()
+
+ val payload = expr.getValue(message)
+----
+======
+
+When you specify the compiler mode, you can also specify a classloader (passing null is allowed).
+Compiled expressions are defined in a child classloader created under any that is supplied.
+It is important to ensure that, if a classloader is specified, it can see all the types involved in
+the expression evaluation process. If you do not specify a classloader, a default classloader is used
+(typically the context classloader for the thread that is running during expression evaluation).
+
+The second way to configure the compiler is for use when SpEL is embedded inside some
+other component and it may not be possible to configure it through a configuration
+object. In these cases, it is possible to set the `spring.expression.compiler.mode`
+property via a JVM system property (or via the
+xref:appendix.adoc#appendix-spring-properties[`SpringProperties`] mechanism) to one of the
+`SpelCompilerMode` enum values (`off`, `immediate`, or `mixed`).
+
+
+[[expressions-compiler-limitations]]
+=== Compiler Limitations
+
+Since Spring Framework 4.1, the basic compilation framework is in place. However, the framework
+does not yet support compiling every kind of expression. The initial focus has been on the
+common expressions that are likely to be used in performance-critical contexts. The following
+kinds of expression cannot be compiled at the moment:
+
+* Expressions involving assignment
+* Expressions relying on the conversion service
+* Expressions using custom resolvers or accessors
+* Expressions using selection or projection
+
+More types of expressions will be compilable in the future.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/example-classes.adoc b/framework-docs/modules/ROOT/pages/core/expressions/example-classes.adoc
new file mode 100644
index 000000000000..e94e3b8c091c
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/example-classes.adoc
@@ -0,0 +1,223 @@
+[[expressions-example-classes]]
+= Classes Used in the Examples
+
+This section lists the classes used in the examples throughout this chapter.
+
+[tabs]
+======
+Inventor.Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package org.spring.samples.spel.inventor;
+
+ import java.util.Date;
+ import java.util.GregorianCalendar;
+
+ public class Inventor {
+
+ private String name;
+ private String nationality;
+ private String[] inventions;
+ private Date birthdate;
+ private PlaceOfBirth placeOfBirth;
+
+ public Inventor(String name, String nationality) {
+ GregorianCalendar c= new GregorianCalendar();
+ this.name = name;
+ this.nationality = nationality;
+ this.birthdate = c.getTime();
+ }
+
+ public Inventor(String name, Date birthdate, String nationality) {
+ this.name = name;
+ this.nationality = nationality;
+ this.birthdate = birthdate;
+ }
+
+ public Inventor() {
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getNationality() {
+ return nationality;
+ }
+
+ public void setNationality(String nationality) {
+ this.nationality = nationality;
+ }
+
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+ public void setBirthdate(Date birthdate) {
+ this.birthdate = birthdate;
+ }
+
+ public PlaceOfBirth getPlaceOfBirth() {
+ return placeOfBirth;
+ }
+
+ public void setPlaceOfBirth(PlaceOfBirth placeOfBirth) {
+ this.placeOfBirth = placeOfBirth;
+ }
+
+ public void setInventions(String[] inventions) {
+ this.inventions = inventions;
+ }
+
+ public String[] getInventions() {
+ return inventions;
+ }
+ }
+----
+
+Inventor.kt::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package org.spring.samples.spel.inventor
+
+ class Inventor(
+ var name: String,
+ var nationality: String,
+ var inventions: Array? = null,
+ var birthdate: Date = GregorianCalendar().time,
+ var placeOfBirth: PlaceOfBirth? = null)
+----
+======
+
+[tabs]
+======
+PlaceOfBirth.java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package org.spring.samples.spel.inventor;
+
+ public class PlaceOfBirth {
+
+ private String city;
+ private String country;
+
+ public PlaceOfBirth(String city) {
+ this.city=city;
+ }
+
+ public PlaceOfBirth(String city, String country) {
+ this(city);
+ this.country = country;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String s) {
+ this.city = s;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+ }
+----
+
+PlaceOfBirth.kt::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package org.spring.samples.spel.inventor
+
+ class PlaceOfBirth(var city: String, var country: String? = null) {
+----
+======
+
+[tabs]
+======
+Society.java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package org.spring.samples.spel.inventor;
+
+ import java.util.*;
+
+ public class Society {
+
+ private String name;
+
+ public static String Advisors = "advisors";
+ public static String President = "president";
+
+ private List members = new ArrayList<>();
+ private Map officers = new HashMap();
+
+ public List getMembers() {
+ return members;
+ }
+
+ public Map getOfficers() {
+ return officers;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isMember(String name) {
+ for (Inventor inventor : members) {
+ if (inventor.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+----
+
+Society.kt::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package org.spring.samples.spel.inventor
+
+ import java.util.*
+
+ class Society {
+
+ val Advisors = "advisors"
+ val President = "president"
+
+ var name: String? = null
+
+ val members = ArrayList()
+ val officers = mapOf()
+
+ fun isMember(name: String): Boolean {
+ for (inventor in members) {
+ if (inventor.name == name) {
+ return true
+ }
+ }
+ return false
+ }
+ }
+----
+======
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc
new file mode 100644
index 000000000000..f920ac60470e
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc
@@ -0,0 +1,25 @@
+[[expressions-language-ref]]
+= Language Reference
+:page-section-summary-toc: 1
+
+This section describes how the Spring Expression Language works. It covers the following
+topics:
+
+* xref:core/expressions/language-ref/literal.adoc[Literal Expressions]
+* xref:core/expressions/language-ref/properties-arrays.adoc[Properties, Arrays, Lists, Maps, and Indexers]
+* xref:core/expressions/language-ref/inline-lists.adoc[Inline Lists]
+* xref:core/expressions/language-ref/inline-maps.adoc[Inline Maps]
+* xref:core/expressions/language-ref/array-construction.adoc[Array Construction]
+* xref:core/expressions/language-ref/methods.adoc[Methods]
+* xref:core/expressions/language-ref/operators.adoc[Operators]
+* xref:core/expressions/language-ref/types.adoc[Types]
+* xref:core/expressions/language-ref/constructors.adoc[Constructors]
+* xref:core/expressions/language-ref/variables.adoc[Variables]
+* xref:core/expressions/language-ref/functions.adoc[Functions]
+* xref:core/expressions/language-ref/bean-references.adoc[Bean References]
+* xref:core/expressions/language-ref/operator-ternary.adoc[Ternary Operator (If-Then-Else)]
+* xref:core/expressions/language-ref/operator-elvis.adoc[The Elvis Operator]
+* xref:core/expressions/language-ref/operator-safe-navigation.adoc[Safe Navigation Operator]
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/array-construction.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/array-construction.adoc
new file mode 100644
index 000000000000..01e181ae3017
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/array-construction.adoc
@@ -0,0 +1,39 @@
+[[expressions-array-construction]]
+= Array Construction
+
+You can build arrays by using the familiar Java syntax, optionally supplying an initializer
+to have the array populated at construction time. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context);
+
+ // Array with initializer
+ int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context);
+
+ // Multi dimensional array
+ int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val numbers1 = parser.parseExpression("new int[4]").getValue(context) as IntArray
+
+ // Array with initializer
+ val numbers2 = parser.parseExpression("new int[]{1,2,3}").getValue(context) as IntArray
+
+ // Multi dimensional array
+ val numbers3 = parser.parseExpression("new int[4][5]").getValue(context) as Array
+----
+======
+
+You cannot currently supply an initializer when you construct a multi-dimensional array.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/bean-references.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/bean-references.adoc
new file mode 100644
index 000000000000..82e68876b1f0
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/bean-references.adoc
@@ -0,0 +1,65 @@
+[[expressions-bean-references]]
+= Bean References
+
+If the evaluation context has been configured with a bean resolver, you can
+look up beans from an expression by using the `@` symbol. The following example shows how
+to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ StandardEvaluationContext context = new StandardEvaluationContext();
+ context.setBeanResolver(new MyBeanResolver());
+
+ // This will end up calling resolve(context,"something") on MyBeanResolver during evaluation
+ Object bean = parser.parseExpression("@something").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+ val context = StandardEvaluationContext()
+ context.setBeanResolver(MyBeanResolver())
+
+ // This will end up calling resolve(context,"something") on MyBeanResolver during evaluation
+ val bean = parser.parseExpression("@something").getValue(context)
+----
+======
+
+To access a factory bean itself, you should instead prefix the bean name with an `&` symbol.
+The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ StandardEvaluationContext context = new StandardEvaluationContext();
+ context.setBeanResolver(new MyBeanResolver());
+
+ // This will end up calling resolve(context,"&foo") on MyBeanResolver during evaluation
+ Object bean = parser.parseExpression("&foo").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+ val context = StandardEvaluationContext()
+ context.setBeanResolver(MyBeanResolver())
+
+ // This will end up calling resolve(context,"&foo") on MyBeanResolver during evaluation
+ val bean = parser.parseExpression("&foo").getValue(context)
+----
+======
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/collection-projection.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/collection-projection.adoc
new file mode 100644
index 000000000000..83f492766dd0
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/collection-projection.adoc
@@ -0,0 +1,36 @@
+[[expressions-collection-projection]]
+= Collection Projection
+
+Projection lets a collection drive the evaluation of a sub-expression, and the result is
+a new collection. The syntax for projection is `.![projectionExpression]`. For example,
+suppose we have a list of inventors but want the list of cities where they were born.
+Effectively, we want to evaluate 'placeOfBirth.city' for every entry in the inventor
+list. The following example uses projection to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // returns ['Smiljan', 'Idvor' ]
+ List placesOfBirth = (List)parser.parseExpression("members.![placeOfBirth.city]");
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // returns ['Smiljan', 'Idvor' ]
+ val placesOfBirth = parser.parseExpression("members.![placeOfBirth.city]") as List<*>
+----
+======
+
+Projection is supported for arrays and anything that implements `java.lang.Iterable` or
+`java.util.Map`. When using a map to drive projection, the projection expression is
+evaluated against each entry in the map (represented as a Java `Map.Entry`). The result
+of a projection across a map is a list that consists of the evaluation of the projection
+expression against each map entry.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/collection-selection.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/collection-selection.adoc
new file mode 100644
index 000000000000..3f87541a81cb
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/collection-selection.adoc
@@ -0,0 +1,62 @@
+[[expressions-collection-selection]]
+= Collection Selection
+
+Selection is a powerful expression language feature that lets you transform a
+source collection into another collection by selecting from its entries.
+
+Selection uses a syntax of `.?[selectionExpression]`. It filters the collection and
+returns a new collection that contains a subset of the original elements. For example,
+selection lets us easily get a list of Serbian inventors, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ List list = (List) parser.parseExpression(
+ "members.?[nationality == 'Serbian']").getValue(societyContext);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val list = parser.parseExpression(
+ "members.?[nationality == 'Serbian']").getValue(societyContext) as List
+----
+======
+
+Selection is supported for arrays and anything that implements `java.lang.Iterable` or
+`java.util.Map`. For a list or array, the selection criteria is evaluated against each
+individual element. Against a map, the selection criteria is evaluated against each map
+entry (objects of the Java type `Map.Entry`). Each map entry has its `key` and `value`
+accessible as properties for use in the selection.
+
+The following expression returns a new map that consists of those elements of the
+original map where the entry's value is less than 27:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Map newMap = parser.parseExpression("map.?[value<27]").getValue();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val newMap = parser.parseExpression("map.?[value<27]").getValue()
+----
+======
+
+In addition to returning all the selected elements, you can retrieve only the first or
+the last element. To obtain the first element matching the selection, the syntax is
+`.^[selectionExpression]`. To obtain the last matching selection, the syntax is
+`.$[selectionExpression]`.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/constructors.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/constructors.adoc
new file mode 100644
index 000000000000..a35513c9c1ec
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/constructors.adoc
@@ -0,0 +1,41 @@
+[[expressions-constructors]]
+= Constructors
+
+You can invoke constructors by using the `new` operator. You should use the fully
+qualified class name for all types except those located in the `java.lang` package
+(`Integer`, `Float`, `String`, and so on). The following example shows how to use the
+`new` operator to invoke constructors:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Inventor einstein = p.parseExpression(
+ "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')")
+ .getValue(Inventor.class);
+
+ // create new Inventor instance within the add() method of List
+ p.parseExpression(
+ "Members.add(new org.spring.samples.spel.inventor.Inventor(
+ 'Albert Einstein', 'German'))").getValue(societyContext);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val einstein = p.parseExpression(
+ "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')")
+ .getValue(Inventor::class.java)
+
+ // create new Inventor instance within the add() method of List
+ p.parseExpression(
+ "Members.add(new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German'))")
+ .getValue(societyContext)
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc
new file mode 100644
index 000000000000..014d6e8b8c44
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc
@@ -0,0 +1,98 @@
+[[expressions-ref-functions]]
+= Functions
+
+You can extend SpEL by registering user-defined functions that can be called within the
+expression string. The function is registered through the `EvaluationContext`. The
+following example shows how to register a user-defined function:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Method method = ...;
+
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
+ context.setVariable("myFunction", method);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val method: Method = ...
+
+ val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
+ context.setVariable("myFunction", method)
+----
+======
+
+For example, consider the following utility method that reverses a string:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public abstract class StringUtils {
+
+ public static String reverseString(String input) {
+ StringBuilder backwards = new StringBuilder(input.length());
+ for (int i = 0; i < input.length(); i++) {
+ backwards.append(input.charAt(input.length() - 1 - i));
+ }
+ return backwards.toString();
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ fun reverseString(input: String): String {
+ val backwards = StringBuilder(input.length)
+ for (i in 0 until input.length) {
+ backwards.append(input[input.length - 1 - i])
+ }
+ return backwards.toString()
+ }
+----
+======
+
+You can then register and use the preceding method, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
+ context.setVariable("reverseString",
+ StringUtils.class.getDeclaredMethod("reverseString", String.class));
+
+ String helloWorldReversed = parser.parseExpression(
+ "#reverseString('hello')").getValue(context, String.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+
+ val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
+ context.setVariable("reverseString", ::reverseString::javaMethod)
+
+ val helloWorldReversed = parser.parseExpression(
+ "#reverseString('hello')").getValue(context, String::class.java)
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/inline-lists.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/inline-lists.adoc
new file mode 100644
index 000000000000..463d54d80955
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/inline-lists.adoc
@@ -0,0 +1,34 @@
+[[expressions-inline-lists]]
+= Inline Lists
+
+You can directly express lists in an expression by using `{}` notation.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // evaluates to a Java list containing the four numbers
+ List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context);
+
+ List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // evaluates to a Java list containing the four numbers
+ val numbers = parser.parseExpression("{1,2,3,4}").getValue(context) as List<*>
+
+ val listOfLists = parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context) as List<*>
+----
+======
+
+`{}` by itself means an empty list. For performance reasons, if the list is itself
+entirely composed of fixed literals, a constant list is created to represent the
+expression (rather than building a new list on each evaluation).
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/inline-maps.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/inline-maps.adoc
new file mode 100644
index 000000000000..2b972329cd8b
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/inline-maps.adoc
@@ -0,0 +1,37 @@
+[[expressions-inline-maps]]
+= Inline Maps
+
+You can also directly express maps in an expression by using `{key:value}` notation. The
+following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // evaluates to a Java map containing the two entries
+ Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context);
+
+ Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim",role="secondary"]
+----
+ // evaluates to a Java map containing the two entries
+ val inventorInfo = parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context) as Map<*, *>
+
+ val mapOfMaps = parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context) as Map<*, *>
+----
+======
+
+`{:}` by itself means an empty map. For performance reasons, if the map is itself
+composed of fixed literals or other nested constant structures (lists or maps), a
+constant map is created to represent the expression (rather than building a new map on
+each evaluation). Quoting of the map keys is optional (unless the key contains a period
+(`.`)). The examples above do not use quoted keys.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/literal.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/literal.adoc
new file mode 100644
index 000000000000..c133af0f367a
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/literal.adoc
@@ -0,0 +1,74 @@
+[[expressions-ref-literal]]
+= Literal Expressions
+
+SpEL supports the following types of literal expressions.
+
+- strings
+- numeric values: integer (`int` or `long`), hexadecimal (`int` or `long`), real (`float`
+ or `double`)
+- boolean values: `true` or `false`
+- null
+
+Strings can delimited by single quotation marks (`'`) or double quotation marks (`"`). To
+include a single quotation mark within a string literal enclosed in single quotation
+marks, use two adjacent single quotation mark characters. Similarly, to include a double
+quotation mark within a string literal enclosed in double quotation marks, use two
+adjacent double quotation mark characters.
+
+Numbers support the use of the negative sign, exponential notation, and decimal points.
+By default, real numbers are parsed by using `Double.parseDouble()`.
+
+The following listing shows simple usage of literals. Typically, they are not used in
+isolation like this but, rather, as part of a more complex expression -- for example,
+using a literal on one side of a logical comparison operator or as an argument to a
+method.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+
+ // evaluates to "Hello World"
+ String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
+
+ // evaluates to "Tony's Pizza"
+ String pizzaParlor = (String) parser.parseExpression("'Tony''s Pizza'").getValue();
+
+ double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();
+
+ // evaluates to 2147483647
+ int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();
+
+ boolean trueValue = (Boolean) parser.parseExpression("true").getValue();
+
+ Object nullValue = parser.parseExpression("null").getValue();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+
+ // evaluates to "Hello World"
+ val helloWorld = parser.parseExpression("'Hello World'").value as String
+
+ // evaluates to "Tony's Pizza"
+ val pizzaParlor = parser.parseExpression("'Tony''s Pizza'").value as String
+
+ val avogadrosNumber = parser.parseExpression("6.0221415E+23").value as Double
+
+ // evaluates to 2147483647
+ val maxValue = parser.parseExpression("0x7FFFFFFF").value as Int
+
+ val trueValue = parser.parseExpression("true").value as Boolean
+
+ val nullValue = parser.parseExpression("null").value
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/methods.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/methods.adoc
new file mode 100644
index 000000000000..46c91b836254
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/methods.adoc
@@ -0,0 +1,35 @@
+[[expressions-methods]]
+= Methods
+
+You can invoke methods by using typical Java programming syntax. You can also invoke methods
+on literals. Variable arguments are also supported. The following examples show how to
+invoke methods:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // string literal, evaluates to "bc"
+ String bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class);
+
+ // evaluates to true
+ boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
+ societyContext, Boolean.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // string literal, evaluates to "bc"
+ val bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String::class.java)
+
+ // evaluates to true
+ val isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
+ societyContext, Boolean::class.java)
+----
+======
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-elvis.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-elvis.adoc
new file mode 100644
index 000000000000..8f7e69a0b6cb
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-elvis.adoc
@@ -0,0 +1,91 @@
+[[expressions-operator-elvis]]
+= The Elvis Operator
+
+The Elvis operator is a shortening of the ternary operator syntax and is used in the
+https://www.groovy-lang.org/operators.html#_elvis_operator[Groovy] language.
+With the ternary operator syntax, you usually have to repeat a variable twice, as the
+following example shows:
+
+[source,groovy,indent=0,subs="verbatim,quotes"]
+----
+ String name = "Elvis Presley";
+ String displayName = (name != null ? name : "Unknown");
+----
+
+Instead, you can use the Elvis operator (named for the resemblance to Elvis' hair style).
+The following example shows how to use the Elvis operator:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+
+ String name = parser.parseExpression("name?:'Unknown'").getValue(new Inventor(), String.class);
+ System.out.println(name); // 'Unknown'
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+
+ val name = parser.parseExpression("name?:'Unknown'").getValue(Inventor(), String::class.java)
+ println(name) // 'Unknown'
+----
+======
+
+The following listing shows a more complex example:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
+
+ Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
+ String name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String.class);
+ System.out.println(name); // Nikola Tesla
+
+ tesla.setName(null);
+ name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String.class);
+ System.out.println(name); // Elvis Presley
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+ val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
+
+ val tesla = Inventor("Nikola Tesla", "Serbian")
+ var name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String::class.java)
+ println(name) // Nikola Tesla
+
+ tesla.setName(null)
+ name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String::class.java)
+ println(name) // Elvis Presley
+----
+======
+
+[NOTE]
+=====
+You can use the Elvis operator to apply default values in expressions. The following
+example shows how to use the Elvis operator in a `@Value` expression:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ @Value("#{systemProperties['pop3.port'] ?: 25}")
+----
+
+This will inject a system property `pop3.port` if it is defined or 25 if not.
+=====
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-safe-navigation.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-safe-navigation.adoc
new file mode 100644
index 000000000000..0691cf2de87a
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-safe-navigation.adoc
@@ -0,0 +1,51 @@
+[[expressions-operator-safe-navigation]]
+= Safe Navigation Operator
+
+The safe navigation operator is used to avoid a `NullPointerException` and comes from
+the https://www.groovy-lang.org/operators.html#_safe_navigation_operator[Groovy]
+language. Typically, when you have a reference to an object, you might need to verify that
+it is not null before accessing methods or properties of the object. To avoid this, the
+safe navigation operator returns null instead of throwing an exception. The following
+example shows how to use the safe navigation operator:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
+
+ Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
+ tesla.setPlaceOfBirth(new PlaceOfBirth("Smiljan"));
+
+ String city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String.class);
+ System.out.println(city); // Smiljan
+
+ tesla.setPlaceOfBirth(null);
+ city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String.class);
+ System.out.println(city); // null - does not throw NullPointerException!!!
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+ val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
+
+ val tesla = Inventor("Nikola Tesla", "Serbian")
+ tesla.setPlaceOfBirth(PlaceOfBirth("Smiljan"))
+
+ var city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String::class.java)
+ println(city) // Smiljan
+
+ tesla.setPlaceOfBirth(null)
+ city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String::class.java)
+ println(city) // null - does not throw NullPointerException!!!
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-ternary.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-ternary.adoc
new file mode 100644
index 000000000000..0a834d195fd6
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operator-ternary.adoc
@@ -0,0 +1,65 @@
+[[expressions-operator-ternary]]
+= Ternary Operator (If-Then-Else)
+
+You can use the ternary operator for performing if-then-else conditional logic inside
+the expression. The following listing shows a minimal example:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ String falseString = parser.parseExpression(
+ "false ? 'trueExp' : 'falseExp'").getValue(String.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val falseString = parser.parseExpression(
+ "false ? 'trueExp' : 'falseExp'").getValue(String::class.java)
+----
+======
+
+In this case, the boolean `false` results in returning the string value `'falseExp'`. A more
+realistic example follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ parser.parseExpression("name").setValue(societyContext, "IEEE");
+ societyContext.setVariable("queryName", "Nikola Tesla");
+
+ expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +
+ "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";
+
+ String queryResultString = parser.parseExpression(expression)
+ .getValue(societyContext, String.class);
+ // queryResultString = "Nikola Tesla is a member of the IEEE Society"
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ parser.parseExpression("name").setValue(societyContext, "IEEE")
+ societyContext.setVariable("queryName", "Nikola Tesla")
+
+ expression = "isMember(#queryName)? #queryName + ' is a member of the ' " + "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'"
+
+ val queryResultString = parser.parseExpression(expression)
+ .getValue(societyContext, String::class.java)
+ // queryResultString = "Nikola Tesla is a member of the IEEE Society"
+----
+======
+
+See the next section on the Elvis operator for an even shorter syntax for the
+ternary operator.
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc
new file mode 100644
index 000000000000..7d9d6ece8e4e
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/operators.adoc
@@ -0,0 +1,327 @@
+[[expressions-operators]]
+= Operators
+
+The Spring Expression Language supports the following kinds of operators:
+
+* xref:core/expressions/language-ref/operators.adoc#expressions-operators-relational[Relational Operators]
+* xref:core/expressions/language-ref/operators.adoc#expressions-operators-logical[Logical Operators]
+* xref:core/expressions/language-ref/operators.adoc#expressions-operators-mathematical[Mathematical Operators]
+* xref:core/expressions/language-ref/operators.adoc#expressions-assignment[The Assignment Operator]
+
+
+[[expressions-operators-relational]]
+== Relational Operators
+
+The relational operators (equal, not equal, less than, less than or equal, greater than,
+and greater than or equal) are supported by using standard operator notation.
+These operators work on `Number` types as well as types implementing `Comparable`.
+The following listing shows a few examples of operators:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // evaluates to true
+ boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);
+
+ // evaluates to false
+ boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
+
+ // evaluates to true
+ boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
+
+ // uses CustomValue:::compareTo
+ boolean trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // evaluates to true
+ val trueValue = parser.parseExpression("2 == 2").getValue(Boolean::class.java)
+
+ // evaluates to false
+ val falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean::class.java)
+
+ // evaluates to true
+ val trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean::class.java)
+
+ // uses CustomValue:::compareTo
+ val trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean::class.java);
+----
+======
+
+[NOTE]
+====
+Greater-than and less-than comparisons against `null` follow a simple rule: `null` is treated as
+nothing (that is NOT as zero). As a consequence, any other value is always greater
+than `null` (`X > null` is always `true`) and no other value is ever less than nothing
+(`X < null` is always `false`).
+
+If you prefer numeric comparisons instead, avoid number-based `null` comparisons
+in favor of comparisons against zero (for example, `X > 0` or `X < 0`).
+====
+
+In addition to the standard relational operators, SpEL supports the `instanceof` and regular
+expression-based `matches` operator. The following listing shows examples of both:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // evaluates to false
+ boolean falseValue = parser.parseExpression(
+ "'xyz' instanceof T(Integer)").getValue(Boolean.class);
+
+ // evaluates to true
+ boolean trueValue = parser.parseExpression(
+ "'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
+
+ // evaluates to false
+ boolean falseValue = parser.parseExpression(
+ "'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // evaluates to false
+ val falseValue = parser.parseExpression(
+ "'xyz' instanceof T(Integer)").getValue(Boolean::class.java)
+
+ // evaluates to true
+ val trueValue = parser.parseExpression(
+ "'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
+
+ // evaluates to false
+ val falseValue = parser.parseExpression(
+ "'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
+----
+======
+
+CAUTION: Be careful with primitive types, as they are immediately boxed up to their
+wrapper types. For example, `1 instanceof T(int)` evaluates to `false`, while
+`1 instanceof T(Integer)` evaluates to `true`, as expected.
+
+Each symbolic operator can also be specified as a purely alphabetic equivalent. This
+avoids problems where the symbols used have special meaning for the document type in
+which the expression is embedded (such as in an XML document). The textual equivalents are:
+
+* `lt` (`<`)
+* `gt` (`>`)
+* `le` (`\<=`)
+* `ge` (`>=`)
+* `eq` (`==`)
+* `ne` (`!=`)
+* `div` (`/`)
+* `mod` (`%`)
+* `not` (`!`).
+
+All of the textual operators are case-insensitive.
+
+
+[[expressions-operators-logical]]
+== Logical Operators
+
+SpEL supports the following logical operators:
+
+* `and` (`&&`)
+* `or` (`||`)
+* `not` (`!`)
+
+The following example shows how to use the logical operators:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // -- AND --
+
+ // evaluates to false
+ boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class);
+
+ // evaluates to true
+ String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')";
+ boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
+
+ // -- OR --
+
+ // evaluates to true
+ boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class);
+
+ // evaluates to true
+ String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')";
+ boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
+
+ // -- NOT --
+
+ // evaluates to false
+ boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class);
+
+ // -- AND and NOT --
+ String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";
+ boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // -- AND --
+
+ // evaluates to false
+ val falseValue = parser.parseExpression("true and false").getValue(Boolean::class.java)
+
+ // evaluates to true
+ val expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"
+ val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
+
+ // -- OR --
+
+ // evaluates to true
+ val trueValue = parser.parseExpression("true or false").getValue(Boolean::class.java)
+
+ // evaluates to true
+ val expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')"
+ val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
+
+ // -- NOT --
+
+ // evaluates to false
+ val falseValue = parser.parseExpression("!true").getValue(Boolean::class.java)
+
+ // -- AND and NOT --
+ val expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"
+ val falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
+----
+======
+
+
+[[expressions-operators-mathematical]]
+== Mathematical Operators
+
+You can use the addition operator (`+`) on both numbers and strings. You can use the
+subtraction (`-`), multiplication (`*`), and division (`/`) operators only on numbers.
+You can also use the modulus (`%`) and exponential power (`^`) operators on numbers.
+Standard operator precedence is enforced. The following example shows the mathematical
+operators in use:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // Addition
+ int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
+
+ String testString = parser.parseExpression(
+ "'test' + ' ' + 'string'").getValue(String.class); // 'test string'
+
+ // Subtraction
+ int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4
+
+ double d = parser.parseExpression("1000.00 - 1e4").getValue(Double.class); // -9000
+
+ // Multiplication
+ int six = parser.parseExpression("-2 * -3").getValue(Integer.class); // 6
+
+ double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); // 24.0
+
+ // Division
+ int minusTwo = parser.parseExpression("6 / -3").getValue(Integer.class); // -2
+
+ double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class); // 1.0
+
+ // Modulus
+ int three = parser.parseExpression("7 % 4").getValue(Integer.class); // 3
+
+ int one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class); // 1
+
+ // Operator precedence
+ int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class); // -21
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // Addition
+ val two = parser.parseExpression("1 + 1").getValue(Int::class.java) // 2
+
+ val testString = parser.parseExpression(
+ "'test' + ' ' + 'string'").getValue(String::class.java) // 'test string'
+
+ // Subtraction
+ val four = parser.parseExpression("1 - -3").getValue(Int::class.java) // 4
+
+ val d = parser.parseExpression("1000.00 - 1e4").getValue(Double::class.java) // -9000
+
+ // Multiplication
+ val six = parser.parseExpression("-2 * -3").getValue(Int::class.java) // 6
+
+ val twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double::class.java) // 24.0
+
+ // Division
+ val minusTwo = parser.parseExpression("6 / -3").getValue(Int::class.java) // -2
+
+ val one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double::class.java) // 1.0
+
+ // Modulus
+ val three = parser.parseExpression("7 % 4").getValue(Int::class.java) // 3
+
+ val one = parser.parseExpression("8 / 5 % 2").getValue(Int::class.java) // 1
+
+ // Operator precedence
+ val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java) // -21
+----
+======
+
+
+[[expressions-assignment]]
+== The Assignment Operator
+
+To set a property, use the assignment operator (`=`). This is typically done within a
+call to `setValue` but can also be done inside a call to `getValue`. The following
+listing shows both ways to use the assignment operator:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Inventor inventor = new Inventor();
+ EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
+
+ parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic");
+
+ // alternatively
+ String aleks = parser.parseExpression(
+ "name = 'Aleksandar Seovic'").getValue(context, inventor, String.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val inventor = Inventor()
+ val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
+
+ parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic")
+
+ // alternatively
+ val aleks = parser.parseExpression(
+ "name = 'Aleksandar Seovic'").getValue(context, inventor, String::class.java)
+----
+======
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/properties-arrays.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/properties-arrays.adoc
new file mode 100644
index 000000000000..3066b54dec7b
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/properties-arrays.adoc
@@ -0,0 +1,142 @@
+[[expressions-properties-arrays]]
+= Properties, Arrays, Lists, Maps, and Indexers
+
+Navigating with property references is easy. To do so, use a period to indicate a nested
+property value. The instances of the `Inventor` class, `pupin` and `tesla`, were
+populated with data listed in the xref:core/expressions/example-classes.adoc[Classes used in the examples]
+ section. To navigate "down" the object graph and get Tesla's year of birth and
+Pupin's city of birth, we use the following expressions:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // evaluates to 1856
+ int year = (Integer) parser.parseExpression("birthdate.year + 1900").getValue(context);
+
+ String city = (String) parser.parseExpression("placeOfBirth.city").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // evaluates to 1856
+ val year = parser.parseExpression("birthdate.year + 1900").getValue(context) as Int
+
+ val city = parser.parseExpression("placeOfBirth.city").getValue(context) as String
+----
+======
+
+[NOTE]
+====
+Case insensitivity is allowed for the first letter of property names. Thus, the
+expressions in the above example may be written as `Birthdate.Year + 1900` and
+`PlaceOfBirth.City`, respectively. In addition, properties may optionally be accessed via
+method invocations -- for example, `getPlaceOfBirth().getCity()` instead of
+`placeOfBirth.city`.
+====
+
+The contents of arrays and lists are obtained by using square bracket notation, as the
+following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ ExpressionParser parser = new SpelExpressionParser();
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
+
+ // Inventions Array
+
+ // evaluates to "Induction motor"
+ String invention = parser.parseExpression("inventions[3]").getValue(
+ context, tesla, String.class);
+
+ // Members List
+
+ // evaluates to "Nikola Tesla"
+ String name = parser.parseExpression("members[0].name").getValue(
+ context, ieee, String.class);
+
+ // List and Array navigation
+ // evaluates to "Wireless communication"
+ String invention = parser.parseExpression("members[0].inventions[6]").getValue(
+ context, ieee, String.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val parser = SpelExpressionParser()
+ val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
+
+ // Inventions Array
+
+ // evaluates to "Induction motor"
+ val invention = parser.parseExpression("inventions[3]").getValue(
+ context, tesla, String::class.java)
+
+ // Members List
+
+ // evaluates to "Nikola Tesla"
+ val name = parser.parseExpression("members[0].name").getValue(
+ context, ieee, String::class.java)
+
+ // List and Array navigation
+ // evaluates to "Wireless communication"
+ val invention = parser.parseExpression("members[0].inventions[6]").getValue(
+ context, ieee, String::class.java)
+----
+======
+
+The contents of maps are obtained by specifying the literal key value within the
+brackets. In the following example, because keys for the `officers` map are strings, we can specify
+string literals:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // Officer's Dictionary
+
+ Inventor pupin = parser.parseExpression("officers['president']").getValue(
+ societyContext, Inventor.class);
+
+ // evaluates to "Idvor"
+ String city = parser.parseExpression("officers['president'].placeOfBirth.city").getValue(
+ societyContext, String.class);
+
+ // setting values
+ parser.parseExpression("officers['advisors'][0].placeOfBirth.country").setValue(
+ societyContext, "Croatia");
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // Officer's Dictionary
+
+ val pupin = parser.parseExpression("officers['president']").getValue(
+ societyContext, Inventor::class.java)
+
+ // evaluates to "Idvor"
+ val city = parser.parseExpression("officers['president'].placeOfBirth.city").getValue(
+ societyContext, String::class.java)
+
+ // setting values
+ parser.parseExpression("officers['advisors'][0].placeOfBirth.country").setValue(
+ societyContext, "Croatia")
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/templating.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/templating.adoc
new file mode 100644
index 000000000000..2b4a02d24f41
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/templating.adoc
@@ -0,0 +1,84 @@
+[[expressions-templating]]
+= Expression templating
+
+Expression templates allow mixing literal text with one or more evaluation blocks.
+Each evaluation block is delimited with prefix and suffix characters that you can
+define. A common choice is to use `#{ }` as the delimiters, as the following example
+shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ String randomPhrase = parser.parseExpression(
+ "random number is #{T(java.lang.Math).random()}",
+ new TemplateParserContext()).getValue(String.class);
+
+ // evaluates to "random number is 0.7038186818312008"
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val randomPhrase = parser.parseExpression(
+ "random number is #{T(java.lang.Math).random()}",
+ TemplateParserContext()).getValue(String::class.java)
+
+ // evaluates to "random number is 0.7038186818312008"
+----
+======
+
+The string is evaluated by concatenating the literal text `'random number is '` with the
+result of evaluating the expression inside the `#{ }` delimiter (in this case, the result
+of calling that `random()` method). The second argument to the `parseExpression()` method
+is of the type `ParserContext`. The `ParserContext` interface is used to influence how
+the expression is parsed in order to support the expression templating functionality.
+The definition of `TemplateParserContext` follows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class TemplateParserContext implements ParserContext {
+
+ public String getExpressionPrefix() {
+ return "#{";
+ }
+
+ public String getExpressionSuffix() {
+ return "}";
+ }
+
+ public boolean isTemplate() {
+ return true;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class TemplateParserContext : ParserContext {
+
+ override fun getExpressionPrefix(): String {
+ return "#{"
+ }
+
+ override fun getExpressionSuffix(): String {
+ return "}"
+ }
+
+ override fun isTemplate(): Boolean {
+ return true
+ }
+ }
+----
+======
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc
new file mode 100644
index 000000000000..df4d9cc3e0c7
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc
@@ -0,0 +1,42 @@
+[[expressions-types]]
+= Types
+
+You can use the special `T` operator to specify an instance of `java.lang.Class` (the
+type). Static methods are invoked by using this operator as well. The
+`StandardEvaluationContext` uses a `TypeLocator` to find types, and the
+`StandardTypeLocator` (which can be replaced) is built with an understanding of the
+`java.lang` package. This means that `T()` references to types within the `java.lang`
+package do not need to be fully qualified, but all other type references must be. The
+following example shows how to use the `T` operator:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.class);
+
+ Class stringClass = parser.parseExpression("T(String)").getValue(Class.class);
+
+ boolean trueValue = parser.parseExpression(
+ "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
+ .getValue(Boolean.class);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class::class.java)
+
+ val stringClass = parser.parseExpression("T(String)").getValue(Class::class.java)
+
+ val trueValue = parser.parseExpression(
+ "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
+ .getValue(Boolean::class.java)
+----
+======
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/variables.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/variables.adoc
new file mode 100644
index 000000000000..6f7ac6e971e9
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/variables.adoc
@@ -0,0 +1,101 @@
+[[expressions-ref-variables]]
+= Variables
+
+You can reference variables in the expression by using the `#variableName` syntax. Variables
+are set by using the `setVariable` method on `EvaluationContext` implementations.
+
+[NOTE]
+====
+Valid variable names must be composed of one or more of the following supported
+characters.
+
+* letters: `A` to `Z` and `a` to `z`
+* digits: `0` to `9`
+* underscore: `_`
+* dollar sign: `$`
+====
+
+The following example shows how to use variables.
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
+
+ EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
+ context.setVariable("newName", "Mike Tesla");
+
+ parser.parseExpression("name = #newName").getValue(context, tesla);
+ System.out.println(tesla.getName()) // "Mike Tesla"
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val tesla = Inventor("Nikola Tesla", "Serbian")
+
+ val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
+ context.setVariable("newName", "Mike Tesla")
+
+ parser.parseExpression("name = #newName").getValue(context, tesla)
+ println(tesla.name) // "Mike Tesla"
+----
+======
+
+
+[[expressions-this-root]]
+== The `#this` and `#root` Variables
+
+The `#this` variable is always defined and refers to the current evaluation object
+(against which unqualified references are resolved). The `#root` variable is always
+defined and refers to the root context object. Although `#this` may vary as components of
+an expression are evaluated, `#root` always refers to the root. The following examples
+show how to use the `#this` and `#root` variables:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ // create an array of integers
+ List primes = new ArrayList<>();
+ primes.addAll(Arrays.asList(2,3,5,7,11,13,17));
+
+ // create parser and set variable 'primes' as the array of integers
+ ExpressionParser parser = new SpelExpressionParser();
+ EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataAccess();
+ context.setVariable("primes", primes);
+
+ // all prime numbers > 10 from the list (using selection ?{...})
+ // evaluates to [11, 13, 17]
+ List primesGreaterThanTen = (List) parser.parseExpression(
+ "#primes.?[#this>10]").getValue(context);
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ // create an array of integers
+ val primes = ArrayList()
+ primes.addAll(listOf(2, 3, 5, 7, 11, 13, 17))
+
+ // create parser and set variable 'primes' as the array of integers
+ val parser = SpelExpressionParser()
+ val context = SimpleEvaluationContext.forReadOnlyDataAccess()
+ context.setVariable("primes", primes)
+
+ // all prime numbers > 10 from the list (using selection ?{...})
+ // evaluates to [11, 13, 17]
+ val primesGreaterThanTen = parser.parseExpression(
+ "#primes.?[#this>10]").getValue(context) as List
+----
+======
+
+
+
diff --git a/framework-docs/src/docs/asciidoc/core/core-null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc
similarity index 95%
rename from framework-docs/src/docs/asciidoc/core/core-null-safety.adoc
rename to framework-docs/modules/ROOT/pages/core/null-safety.adoc
index ffed936d8407..f64cef9b34a4 100644
--- a/framework-docs/src/docs/asciidoc/core/core-null-safety.adoc
+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc
@@ -30,6 +30,7 @@ Spring application developers.
+[[use-cases]]
== Use cases
In addition to providing an explicit declaration for Spring Framework API nullability,
@@ -38,11 +39,12 @@ warnings related to null-safety in order to avoid `NullPointerException` at runt
They are also used to make Spring API null-safe in Kotlin projects, since Kotlin natively
supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details
-are available in the <>.
+are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].
+[[jsr-305-meta-annotations]]
== JSR-305 meta-annotations
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
diff --git a/framework-docs/src/docs/asciidoc/core/core-resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc
similarity index 92%
rename from framework-docs/src/docs/asciidoc/core/core-resources.adoc
rename to framework-docs/modules/ROOT/pages/core/resources.adoc
index 4aaa4575c875..3bfc74aeb33f 100644
--- a/framework-docs/src/docs/asciidoc/core/core-resources.adoc
+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc
@@ -4,14 +4,14 @@
This chapter covers how Spring handles resources and how you can work with resources in
Spring. It includes the following topics:
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
+* xref:core/resources.adoc#resources-introduction[Introduction]
+* xref:core/resources.adoc#resources-resource[The `Resource` Interface]
+* xref:core/resources.adoc#resources-implementations[Built-in `Resource` Implementations]
+* xref:core/resources.adoc#resources-resourceloader[The `ResourceLoader` Interface]
+* xref:core/resources.adoc#resources-resourcepatternresolver[The `ResourcePatternResolver` Interface]
+* xref:core/resources.adoc#resources-resourceloaderaware[The `ResourceLoaderAware` Interface]
+* xref:core/resources.adoc#resources-as-dependencies[Resources as Dependencies]
+* xref:core/resources.adoc#resources-app-ctx[Application Contexts and Resource Paths]
@@ -133,13 +133,13 @@ work.
Spring includes several built-in `Resource` implementations:
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
+* xref:core/resources.adoc#resources-implementations-urlresource[`UrlResource`]
+* xref:core/resources.adoc#resources-implementations-classpathresource[`ClassPathResource`]
+* xref:core/resources.adoc#resources-implementations-filesystemresource[`FileSystemResource`]
+* xref:core/resources.adoc#resources-implementations-pathresource[`PathResource`]
+* xref:core/resources.adoc#resources-implementations-servletcontextresource[`ServletContextResource`]
+* xref:core/resources.adoc#resources-implementations-inputstreamresource[`InputStreamResource`]
+* xref:core/resources.adoc#resources-implementations-bytearrayresource[`ByteArrayResource`]
For a complete list of `Resource` implementations available in Spring, consult the
"All Known Implementing Classes" section of the
@@ -276,16 +276,22 @@ specified doesn't have a specific prefix, you get back a `Resource` type that is
appropriate to that particular application context. For example, assume the following
snippet of code was run against a `ClassPathXmlApplicationContext` instance:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val template = ctx.getResource("some/resource/path/myTemplate.txt")
----
+======
Against a `ClassPathXmlApplicationContext`, that code returns a `ClassPathResource`. If
the same method were run against a `FileSystemXmlApplicationContext` instance, it would
@@ -299,41 +305,59 @@ On the other hand, you may also force `ClassPathResource` to be used, regardless
application context type, by specifying the special `classpath:` prefix, as the following
example shows:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val template = ctx.getResource("classpath:some/resource/path/myTemplate.txt")
----
+======
Similarly, you can force a `UrlResource` to be used by specifying any of the standard
`java.net.URL` prefixes. The following examples use the `file` and `https` prefixes:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val template = ctx.getResource("file:///some/resource/path/myTemplate.txt")
----
+======
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt")
----
+======
The following table summarizes the strategy for converting `String` objects to `Resource`
objects:
@@ -349,7 +373,7 @@ objects:
| file:
| `\file:///data/config.xml`
-| Loaded as a `URL` from the filesystem. See also <>.
+| Loaded as a `URL` from the filesystem. See also xref:core/resources.adoc#resources-filesystemresource-caveats[`FileSystemResource` Caveats].
| https:
| `\https://myserver/logo.png`
@@ -385,11 +409,11 @@ for all matching resources from the class path. Note that the resource location
expected to be a path without placeholders in this case -- for example,
`classpath*:/config/beans.xml`. JAR files or different directories in the class path can
contain multiple files with the same path and the same name. See
-<> and its subsections for further details
+xref:core/resources.adoc#resources-app-ctx-wildcards-in-resource-paths[Wildcards in Application Context Constructor Resource Paths] and its subsections for further details
on wildcard support with the `classpath*:` resource prefix.
A passed-in `ResourceLoader` (for example, one supplied via
-<> semantics) can be checked whether
+xref:core/resources.adoc#resources-resourceloaderaware[`ResourceLoaderAware`] semantics) can be checked whether
it implements this extended interface too.
`PathMatchingResourcePatternResolver` is a standalone implementation that is usable
@@ -444,18 +468,18 @@ interface (which can be considered a utility interface) and not to the whole Spr
In application components, you may also rely upon autowiring of the `ResourceLoader` as
an alternative to implementing the `ResourceLoaderAware` interface. The _traditional_
-`constructor` and `byType` autowiring modes (as described in <>)
+`constructor` and `byType` autowiring modes (as described in xref:core/beans/dependencies/factory-autowire.adoc[Autowiring Collaborators])
are capable of providing a `ResourceLoader` for either a constructor argument or a
setter method parameter, respectively. For more flexibility (including the ability to
autowire fields and multiple parameter methods), consider using the annotation-based
autowiring features. In that case, the `ResourceLoader` is autowired into a field,
constructor argument, or method parameter that expects the `ResourceLoader` type as long
as the field, constructor, or method in question carries the `@Autowired` annotation.
-For more information, see <>.
+For more information, see xref:core/beans/annotation-config/autowired.adoc[Using `@Autowired`].
NOTE: To load one or more `Resource` objects for a resource path that contains wildcards
or makes use of the special `classpath*:` resource prefix, consider having an instance of
-<> autowired into your
+xref:core/resources.adoc#resources-resourcepatternresolver[`ResourcePatternResolver`] autowired into your
application components instead of `ResourceLoader`.
@@ -477,8 +501,11 @@ register and use a special JavaBeans `PropertyEditor`, which can convert `String
to `Resource` objects. For example, the following `MyBean` class has a `template`
property of type `Resource`.
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
package example;
@@ -493,11 +520,14 @@ property of type `Resource`.
// ...
}
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
class MyBean(var template: Resource)
----
+======
In an XML configuration file, the `template` property can be configured with a simple
string for that resource, as the following example shows:
@@ -531,14 +561,17 @@ latter being used to access a file in the filesystem):
If the `MyBean` class is refactored for use with annotation-driven configuration, the
path to `myTemplate.txt` can be stored under a key named `template.path` -- for example,
in a properties file made available to the Spring `Environment` (see
-<>). The template path can then be referenced via the `@Value`
-annotation using a property placeholder (see <>). Spring will
+xref:core/beans/environment.adoc[Environment Abstraction]). The template path can then be referenced via the `@Value`
+annotation using a property placeholder (see xref:core/beans/annotation-config/value-annotations.adoc[Using `@Value`]). Spring will
retrieve the value of the template path as a string, and a special `PropertyEditor` will
convert the string to a `Resource` object to be injected into the `MyBean` constructor.
The following example demonstrates how to achieve this.
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
@Component
public class MyBean {
@@ -552,12 +585,15 @@ The following example demonstrates how to achieve this.
// ...
}
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
@Component
class MyBean(@Value("\${template.path}") private val template: Resource)
----
+======
If we want to support multiple templates discovered under the same path in multiple
locations in the classpath -- for example, in multiple jars in the classpath -- we can
@@ -566,8 +602,11 @@ use the special `classpath*:` prefix and wildcarding to define a `templates.path
Spring will convert the template path pattern into an array of `Resource` objects that
can be injected into the `MyBean` constructor.
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
@Component
public class MyBean {
@@ -581,12 +620,15 @@ can be injected into the `MyBean` constructor.
// ...
}
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
@Component
class MyBean(@Value("\${templates.path}") private val templates: Resource[])
----
+======
@@ -611,31 +653,43 @@ that path and used to load the bean definitions depends on and is appropriate to
specific application context. For example, consider the following example, which creates a
`ClassPathXmlApplicationContext`:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = ClassPathXmlApplicationContext("conf/appContext.xml")
----
+======
The bean definitions are loaded from the classpath, because a `ClassPathResource` is
used. However, consider the following example, which creates a `FileSystemXmlApplicationContext`:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = FileSystemXmlApplicationContext("conf/appContext.xml")
----
+======
Now the bean definitions are loaded from a filesystem location (in this case, relative to
the current working directory).
@@ -644,17 +698,23 @@ Note that the use of the special `classpath` prefix or a standard URL prefix on
location path overrides the default type of `Resource` created to load the bean
definitions. Consider the following example:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = FileSystemXmlApplicationContext("classpath:conf/appContext.xml")
----
+======
Using `FileSystemXmlApplicationContext` loads the bean definitions from the classpath.
However, it is still a `FileSystemXmlApplicationContext`. If it is subsequently used as a
@@ -685,17 +745,23 @@ The following example shows how a `ClassPathXmlApplicationContext` instance comp
the beans defined in files named `services.xml` and `repositories.xml` (which are on the
classpath) can be instantiated:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "repositories.xml"}, MessengerService.class);
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = ClassPathXmlApplicationContext(arrayOf("services.xml", "repositories.xml"), MessengerService::class.java)
----
+======
See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]
javadoc for details on the various constructors.
@@ -773,17 +839,23 @@ coming from jars be thoroughly tested in your specific environment before you re
When constructing an XML-based application context, a location string may use the
special `classpath*:` prefix, as the following example shows:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = ClassPathXmlApplicationContext("classpath*:conf/appContext.xml")
----
+======
This special prefix specifies that all classpath resources that match the given name
must be obtained (internally, this essentially happens through a call to
@@ -879,87 +951,123 @@ For backwards compatibility (historical) reasons however, this changes when the
to treat all location paths as relative, whether they start with a leading slash or not.
In practice, this means the following examples are equivalent:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/context.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = FileSystemXmlApplicationContext("conf/context.xml")
----
+======
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
ApplicationContext ctx =
new FileSystemXmlApplicationContext("/conf/context.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx = FileSystemXmlApplicationContext("/conf/context.xml")
----
+======
The following examples are also equivalent (even though it would make sense for them to be different, as one
case is relative and the other absolute):
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("some/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx: FileSystemXmlApplicationContext = ...
ctx.getResource("some/resource/path/myTemplate.txt")
----
+======
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("/some/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
val ctx: FileSystemXmlApplicationContext = ...
ctx.getResource("/some/resource/path/myTemplate.txt")
----
+======
In practice, if you need true absolute filesystem paths, you should avoid using
absolute paths with `FileSystemResource` or `FileSystemXmlApplicationContext` and
force the use of a `UrlResource` by using the `file:` URL prefix. The following examples
show how to do so:
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt")
----
+======
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:///conf/context.xml");
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
val ctx = FileSystemXmlApplicationContext("file:///conf/context.xml")
----
+======
diff --git a/framework-docs/src/docs/asciidoc/core/core-spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc
similarity index 97%
rename from framework-docs/src/docs/asciidoc/core/core-spring-jcl.adoc
rename to framework-docs/modules/ROOT/pages/core/spring-jcl.adoc
index fee802ed1834..768af0c34345 100644
--- a/framework-docs/src/docs/asciidoc/core/core-spring-jcl.adoc
+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc
@@ -23,19 +23,25 @@ For logging needs within application code, prefer direct use of Log4j 2.x, SLF4J
A `Log` implementation may be retrieved via `org.apache.commons.logging.LogFactory` as in
the following example.
+[tabs]
+======
+Java::
++
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
-.Java
----
public class MyBean {
private final Log log = LogFactory.getLog(getClass());
// ...
}
----
+
+Kotlin::
++
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
-.Kotlin
----
class MyBean {
private val log = LogFactory.getLog(javaClass)
// ...
}
----
+======
diff --git a/framework-docs/modules/ROOT/pages/core/validation.adoc b/framework-docs/modules/ROOT/pages/core/validation.adoc
new file mode 100644
index 000000000000..cc55989412c0
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/validation.adoc
@@ -0,0 +1,40 @@
+[[validation]]
+= Validation, Data Binding, and Type Conversion
+
+There are pros and cons for considering validation as business logic, and Spring offers
+a design for validation and data binding that does not exclude either one of them.
+Specifically, validation should not be tied to the web tier and should be easy to localize,
+and it should be possible to plug in any available validator. Considering these concerns,
+Spring provides a `Validator` contract that is both basic and eminently usable
+in every layer of an application.
+
+Data binding is useful for letting user input be dynamically bound to the domain
+model of an application (or whatever objects you use to process user input). Spring
+provides the aptly named `DataBinder` to do exactly that. The `Validator` and the
+`DataBinder` make up the `validation` package, which is primarily used in but not
+limited to the web layer.
+
+The `BeanWrapper` is a fundamental concept in the Spring Framework and is used in a lot
+of places. However, you probably do not need to use the `BeanWrapper` directly. Because
+this is reference documentation, however, we feel that some explanation might be in
+order. We explain the `BeanWrapper` in this chapter, since, if you are going to use it at
+all, you are most likely do so when trying to bind data to objects.
+
+Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport`
+implementations to parse and format property values. The `PropertyEditor` and
+`PropertyEditorSupport` types are part of the JavaBeans specification and are also
+explained in this chapter. Spring's `core.convert` package provides a general type
+conversion facility, as well as a higher-level `format` package for formatting UI field
+values. You can use these packages as simpler alternatives to `PropertyEditorSupport`
+implementations. They are also discussed in this chapter.
+
+Spring supports Java Bean Validation through setup infrastructure and an adaptor to
+Spring's own `Validator` contract. Applications can enable Bean Validation once globally,
+as described in xref:core/validation/beanvalidation.adoc[Java Bean Validation], and use it exclusively for all validation
+needs. In the web layer, applications can further register controller-local Spring
+`Validator` instances per `DataBinder`, as described in xref:core/validation/beanvalidation.adoc#validation-binder[Configuring a `DataBinder`], which can
+be useful for plugging in custom validation logic.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc
new file mode 100644
index 000000000000..db58aaa11e3b
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc
@@ -0,0 +1,660 @@
+[[beans-beans]]
+= Bean Manipulation and the `BeanWrapper`
+
+The `org.springframework.beans` package adheres to the JavaBeans standard.
+A JavaBean is a class with a default no-argument constructor and that follows
+a naming convention where (for example) a property named `bingoMadness` would
+have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For
+more information about JavaBeans and the specification, see
+https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].
+
+One quite important class in the beans package is the `BeanWrapper` interface and its
+corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the
+`BeanWrapper` offers functionality to set and get property values (individually or in
+bulk), get property descriptors, and query properties to determine if they are
+readable or writable. Also, the `BeanWrapper` offers support for nested properties,
+enabling the setting of properties on sub-properties to an unlimited depth. The
+`BeanWrapper` also supports the ability to add standard JavaBeans `PropertyChangeListeners`
+and `VetoableChangeListeners`, without the need for supporting code in the target class.
+Last but not least, the `BeanWrapper` provides support for setting indexed properties.
+The `BeanWrapper` usually is not used by application code directly but is used by the
+`DataBinder` and the `BeanFactory`.
+
+The way the `BeanWrapper` works is partly indicated by its name: it wraps a bean to
+perform actions on that bean, such as setting and retrieving properties.
+
+
+
+[[beans-beans-conventions]]
+== Setting and Getting Basic and Nested Properties
+
+Setting and getting properties is done through the `setPropertyValue` and
+`getPropertyValue` overloaded method variants of `BeanWrapper`. See their Javadoc for
+details. The below table shows some examples of these conventions:
+
+[[beans-beans-conventions-properties-tbl]]
+.Examples of properties
+|===
+| Expression| Explanation
+
+| `name`
+| Indicates the property `name` that corresponds to the `getName()` or `isName()`
+ and `setName(..)` methods.
+
+| `account.name`
+| Indicates the nested property `name` of the property `account` that corresponds to
+ (for example) the `getAccount().setName()` or `getAccount().getName()` methods.
+
+| `account[2]`
+| Indicates the _third_ element of the indexed property `account`. Indexed properties
+ can be of type `array`, `list`, or other naturally ordered collection.
+
+| `account[COMPANYNAME]`
+| Indicates the value of the map entry indexed by the `COMPANYNAME` key of the `account` `Map`
+ property.
+|===
+
+(This next section is not vitally important to you if you do not plan to work with
+the `BeanWrapper` directly. If you use only the `DataBinder` and the `BeanFactory`
+and their default implementations, you should skip ahead to the
+xref:core/validation/beans-beans.adoc#beans-beans-conversion[section on `PropertyEditors`].)
+
+The following two example classes use the `BeanWrapper` to get and set
+properties:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class Company {
+
+ private String name;
+ private Employee managingDirector;
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Employee getManagingDirector() {
+ return this.managingDirector;
+ }
+
+ public void setManagingDirector(Employee managingDirector) {
+ this.managingDirector = managingDirector;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class Company {
+ var name: String? = null
+ var managingDirector: Employee? = null
+ }
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class Employee {
+
+ private String name;
+
+ private float salary;
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public float getSalary() {
+ return salary;
+ }
+
+ public void setSalary(float salary) {
+ this.salary = salary;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class Employee {
+ var name: String? = null
+ var salary: Float? = null
+ }
+----
+======
+
+The following code snippets show some examples of how to retrieve and manipulate some of
+the properties of instantiated ``Company``s and ``Employee``s:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ BeanWrapper company = new BeanWrapperImpl(new Company());
+ // setting the company name..
+ company.setPropertyValue("name", "Some Company Inc.");
+ // ... can also be done like this:
+ PropertyValue value = new PropertyValue("name", "Some Company Inc.");
+ company.setPropertyValue(value);
+
+ // ok, let's create the director and tie it to the company:
+ BeanWrapper jim = new BeanWrapperImpl(new Employee());
+ jim.setPropertyValue("name", "Jim Stravinsky");
+ company.setPropertyValue("managingDirector", jim.getWrappedInstance());
+
+ // retrieving the salary of the managingDirector through the company
+ Float salary = (Float) company.getPropertyValue("managingDirector.salary");
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val company = BeanWrapperImpl(Company())
+ // setting the company name..
+ company.setPropertyValue("name", "Some Company Inc.")
+ // ... can also be done like this:
+ val value = PropertyValue("name", "Some Company Inc.")
+ company.setPropertyValue(value)
+
+ // ok, let's create the director and tie it to the company:
+ val jim = BeanWrapperImpl(Employee())
+ jim.setPropertyValue("name", "Jim Stravinsky")
+ company.setPropertyValue("managingDirector", jim.wrappedInstance)
+
+ // retrieving the salary of the managingDirector through the company
+ val salary = company.getPropertyValue("managingDirector.salary") as Float?
+----
+======
+
+
+
+[[beans-beans-conversion]]
+== Built-in `PropertyEditor` Implementations
+
+Spring uses the concept of a `PropertyEditor` to effect the conversion between an
+`Object` and a `String`. It can be handy
+to represent properties in a different way than the object itself. For example, a `Date`
+can be represented in a human readable way (as the `String`: `'2007-14-09'`), while
+we can still convert the human readable form back to the original date (or, even
+better, convert any date entered in a human readable form back to `Date` objects). This
+behavior can be achieved by registering custom editors of type
+`java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,
+alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it
+the knowledge of how to convert properties to the desired type. For more about
+`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].
+
+A couple of examples where property editing is used in Spring:
+
+* Setting properties on beans is done by using `PropertyEditor` implementations.
+ When you use `String` as the value of a property of some bean that you declare
+ in an XML file, Spring (if the setter of the corresponding property has a `Class`
+ parameter) uses `ClassEditor` to try to resolve the parameter to a `Class` object.
+* Parsing HTTP request parameters in Spring's MVC framework is done by using all kinds
+ of `PropertyEditor` implementations that you can manually bind in all subclasses of the
+ `CommandController`.
+
+Spring has a number of built-in `PropertyEditor` implementations to make life easy.
+They are all located in the `org.springframework.beans.propertyeditors`
+package. Most, (but not all, as indicated in the following table) are, by default, registered by
+`BeanWrapperImpl`. Where the property editor is configurable in some fashion, you can
+still register your own variant to override the default one. The following table describes
+the various `PropertyEditor` implementations that Spring provides:
+
+[[beans-beans-property-editors-tbl]]
+.Built-in `PropertyEditor` Implementations
+[cols="30%,70%"]
+|===
+| Class| Explanation
+
+| `ByteArrayPropertyEditor`
+| Editor for byte arrays. Converts strings to their corresponding byte
+ representations. Registered by default by `BeanWrapperImpl`.
+
+| `ClassEditor`
+| Parses Strings that represent classes to actual classes and vice-versa. When a
+ class is not found, an `IllegalArgumentException` is thrown. By default, registered by
+ `BeanWrapperImpl`.
+
+| `CustomBooleanEditor`
+| Customizable property editor for `Boolean` properties. By default, registered by
+ `BeanWrapperImpl` but can be overridden by registering a custom instance of it as a
+ custom editor.
+
+| `CustomCollectionEditor`
+| Property editor for collections, converting any source `Collection` to a given target
+ `Collection` type.
+
+| `CustomDateEditor`
+| Customizable property editor for `java.util.Date`, supporting a custom `DateFormat`. NOT
+ registered by default. Must be user-registered with the appropriate format as needed.
+
+| `CustomNumberEditor`
+| Customizable property editor for any `Number` subclass, such as `Integer`, `Long`, `Float`, or
+ `Double`. By default, registered by `BeanWrapperImpl` but can be overridden by
+ registering a custom instance of it as a custom editor.
+
+| `FileEditor`
+| Resolves strings to `java.io.File` objects. By default, registered by
+ `BeanWrapperImpl`.
+
+| `InputStreamEditor`
+| One-way property editor that can take a string and produce (through an
+ intermediate `ResourceEditor` and `Resource`) an `InputStream` so that `InputStream`
+ properties may be directly set as strings. Note that the default usage does not close
+ the `InputStream` for you. By default, registered by `BeanWrapperImpl`.
+
+| `LocaleEditor`
+| Can resolve strings to `Locale` objects and vice-versa (the string format is
+ `[language]\_[country]_[variant]`, same as the `toString()` method of
+ `Locale`). Also accepts spaces as separators, as an alternative to underscores.
+ By default, registered by `BeanWrapperImpl`.
+
+| `PatternEditor`
+| Can resolve strings to `java.util.regex.Pattern` objects and vice-versa.
+
+| `PropertiesEditor`
+| Can convert strings (formatted with the format defined in the javadoc of the
+ `java.util.Properties` class) to `Properties` objects. By default, registered
+ by `BeanWrapperImpl`.
+
+| `StringTrimmerEditor`
+| Property editor that trims strings. Optionally allows transforming an empty string
+ into a `null` value. NOT registered by default -- must be user-registered.
+
+| `URLEditor`
+| Can resolve a string representation of a URL to an actual `URL` object.
+ By default, registered by `BeanWrapperImpl`.
+|===
+
+Spring uses the `java.beans.PropertyEditorManager` to set the search path for property
+editors that might be needed. The search path also includes `sun.bean.editors`, which
+includes `PropertyEditor` implementations for types such as `Font`, `Color`, and most of
+the primitive types. Note also that the standard JavaBeans infrastructure
+automatically discovers `PropertyEditor` classes (without you having to register them
+explicitly) if they are in the same package as the class they handle and have the same
+name as that class, with `Editor` appended. For example, one could have the following
+class and package structure, which would be sufficient for the `SomethingEditor` class to be
+recognized and used as the `PropertyEditor` for `Something`-typed properties.
+
+[literal,subs="verbatim,quotes"]
+----
+com
+ chank
+ pop
+ Something
+ SomethingEditor // the PropertyEditor for the Something class
+----
+
+Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well
+(described to some extent
+https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The
+following example uses the `BeanInfo` mechanism to explicitly register one or more
+`PropertyEditor` instances with the properties of an associated class:
+
+[literal,subs="verbatim,quotes"]
+----
+com
+ chank
+ pop
+ Something
+ SomethingBeanInfo // the BeanInfo for the Something class
+----
+
+The following Java source code for the referenced `SomethingBeanInfo` class
+associates a `CustomNumberEditor` with the `age` property of the `Something` class:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class SomethingBeanInfo extends SimpleBeanInfo {
+
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ try {
+ final PropertyEditor numberPE = new CustomNumberEditor(Integer.class, true);
+ PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", Something.class) {
+ @Override
+ public PropertyEditor createPropertyEditor(Object bean) {
+ return numberPE;
+ }
+ };
+ return new PropertyDescriptor[] { ageDescriptor };
+ }
+ catch (IntrospectionException ex) {
+ throw new Error(ex.toString());
+ }
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class SomethingBeanInfo : SimpleBeanInfo() {
+
+ override fun getPropertyDescriptors(): Array {
+ try {
+ val numberPE = CustomNumberEditor(Int::class.java, true)
+ val ageDescriptor = object : PropertyDescriptor("age", Something::class.java) {
+ override fun createPropertyEditor(bean: Any): PropertyEditor {
+ return numberPE
+ }
+ }
+ return arrayOf(ageDescriptor)
+ } catch (ex: IntrospectionException) {
+ throw Error(ex.toString())
+ }
+
+ }
+ }
+----
+======
+
+
+[[beans-beans-conversion-customeditor-registration]]
+=== Registering Additional Custom `PropertyEditor` Implementations
+
+When setting bean properties as string values, a Spring IoC container ultimately uses
+standard JavaBeans `PropertyEditor` implementations to convert these strings to the complex type of the
+property. Spring pre-registers a number of custom `PropertyEditor` implementations (for example, to
+convert a class name expressed as a string into a `Class` object). Additionally,
+Java's standard JavaBeans `PropertyEditor` lookup mechanism lets a `PropertyEditor`
+for a class be named appropriately and placed in the same package as the class
+for which it provides support, so that it can be found automatically.
+
+If there is a need to register other custom `PropertyEditors`, several mechanisms are
+available. The most manual approach, which is not normally convenient or
+recommended, is to use the `registerCustomEditor()` method of the
+`ConfigurableBeanFactory` interface, assuming you have a `BeanFactory` reference.
+Another (slightly more convenient) mechanism is to use a special bean factory
+post-processor called `CustomEditorConfigurer`. Although you can use bean factory post-processors
+with `BeanFactory` implementations, the `CustomEditorConfigurer` has a
+nested property setup, so we strongly recommend that you use it with the
+`ApplicationContext`, where you can deploy it in similar fashion to any other bean and
+where it can be automatically detected and applied.
+
+Note that all bean factories and application contexts automatically use a number of
+built-in property editors, through their use of a `BeanWrapper` to
+handle property conversions. The standard property editors that the `BeanWrapper`
+registers are listed in the xref:core/validation/beans-beans.adoc#beans-beans-conversion[previous section].
+Additionally, ``ApplicationContext``s also override or add additional editors to handle
+resource lookups in a manner appropriate to the specific application context type.
+
+Standard JavaBeans `PropertyEditor` instances are used to convert property values
+expressed as strings to the actual complex type of the property. You can use
+`CustomEditorConfigurer`, a bean factory post-processor, to conveniently add
+support for additional `PropertyEditor` instances to an `ApplicationContext`.
+
+Consider the following example, which defines a user class called `ExoticType` and
+another class called `DependsOnExoticType`, which needs `ExoticType` set as a property:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package example;
+
+ public class ExoticType {
+
+ private String name;
+
+ public ExoticType(String name) {
+ this.name = name;
+ }
+ }
+
+ public class DependsOnExoticType {
+
+ private ExoticType type;
+
+ public void setType(ExoticType type) {
+ this.type = type;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package example
+
+ class ExoticType(val name: String)
+
+ class DependsOnExoticType {
+
+ var type: ExoticType? = null
+ }
+----
+======
+
+When things are properly set up, we want to be able to assign the type property as a
+string, which a `PropertyEditor` converts into an actual
+`ExoticType` instance. The following bean definition shows how to set up this relationship:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+----
+
+The `PropertyEditor` implementation could look similar to the following:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package example;
+
+ import java.beans.PropertyEditorSupport;
+
+ // converts string representation to ExoticType object
+ public class ExoticTypeEditor extends PropertyEditorSupport {
+
+ public void setAsText(String text) {
+ setValue(new ExoticType(text.toUpperCase()));
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package example
+
+ import java.beans.PropertyEditorSupport
+
+ // converts string representation to ExoticType object
+ class ExoticTypeEditor : PropertyEditorSupport() {
+
+ override fun setAsText(text: String) {
+ value = ExoticType(text.toUpperCase())
+ }
+ }
+----
+======
+
+Finally, the following example shows how to use `CustomEditorConfigurer` to register the new `PropertyEditor` with the
+`ApplicationContext`, which will then be able to use it as needed:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+----
+
+[[beans-beans-conversion-customeditor-registration-per]]
+==== Using `PropertyEditorRegistrar`
+
+Another mechanism for registering property editors with the Spring container is to
+create and use a `PropertyEditorRegistrar`. This interface is particularly useful when
+you need to use the same set of property editors in several different situations.
+You can write a corresponding registrar and reuse it in each case.
+`PropertyEditorRegistrar` instances work in conjunction with an interface called
+`PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper`
+(and `DataBinder`). `PropertyEditorRegistrar` instances are particularly convenient
+when used in conjunction with `CustomEditorConfigurer` (described
+xref:core/validation/beans-beans.adoc#beans-beans-conversion-customeditor-registration[here]), which exposes a property
+called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added
+to a `CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and
+Spring MVC controllers. Furthermore, it avoids the need for synchronization on custom
+editors: A `PropertyEditorRegistrar` is expected to create fresh `PropertyEditor`
+instances for each bean creation attempt.
+
+The following example shows how to create your own `PropertyEditorRegistrar` implementation:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary",chomp="-packages"]
+----
+ package com.foo.editors.spring;
+
+ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
+
+ public void registerCustomEditors(PropertyEditorRegistry registry) {
+
+ // it is expected that new PropertyEditor instances are created
+ registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
+
+ // you could register as many custom property editors as are required here...
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary",chomp="-packages"]
+----
+ package com.foo.editors.spring
+
+ import org.springframework.beans.PropertyEditorRegistrar
+ import org.springframework.beans.PropertyEditorRegistry
+
+ class CustomPropertyEditorRegistrar : PropertyEditorRegistrar {
+
+ override fun registerCustomEditors(registry: PropertyEditorRegistry) {
+
+ // it is expected that new PropertyEditor instances are created
+ registry.registerCustomEditor(ExoticType::class.java, ExoticTypeEditor())
+
+ // you could register as many custom property editors as are required here...
+ }
+ }
+----
+======
+
+See also the `org.springframework.beans.support.ResourceEditorRegistrar` for an example
+`PropertyEditorRegistrar` implementation. Notice how in its implementation of the
+`registerCustomEditors(..)` method, it creates new instances of each property editor.
+
+The next example shows how to configure a `CustomEditorConfigurer` and inject an instance
+of our `CustomPropertyEditorRegistrar` into it:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+----
+
+Finally (and in a bit of a departure from the focus of this chapter) for those of you
+using xref:web/webmvc.adoc#mvc[Spring's MVC web framework], using a `PropertyEditorRegistrar` in
+conjunction with data-binding web controllers can be very convenient. The following
+example uses a `PropertyEditorRegistrar` in the implementation of an `@InitBinder` method:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Controller
+ public class RegisterUserController {
+
+ private final PropertyEditorRegistrar customPropertyEditorRegistrar;
+
+ RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
+ this.customPropertyEditorRegistrar = propertyEditorRegistrar;
+ }
+
+ @InitBinder
+ void initBinder(WebDataBinder binder) {
+ this.customPropertyEditorRegistrar.registerCustomEditors(binder);
+ }
+
+ // other methods related to registering a User
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Controller
+ class RegisterUserController(
+ private val customPropertyEditorRegistrar: PropertyEditorRegistrar) {
+
+ @InitBinder
+ fun initBinder(binder: WebDataBinder) {
+ this.customPropertyEditorRegistrar.registerCustomEditors(binder)
+ }
+
+ // other methods related to registering a User
+ }
+----
+======
+
+This style of `PropertyEditor` registration can lead to concise code (the implementation
+of the `@InitBinder` method is only one line long) and lets common `PropertyEditor`
+registration code be encapsulated in a class and then shared amongst as many controllers
+as needed.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc
new file mode 100644
index 000000000000..3837d50a355c
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc
@@ -0,0 +1,397 @@
+[[validation-beanvalidation]]
+= Java Bean Validation
+
+The Spring Framework provides support for the
+https://beanvalidation.org/[Java Bean Validation] API.
+
+
+
+[[validation-beanvalidation-overview]]
+== Overview of Bean Validation
+
+Bean Validation provides a common way of validation through constraint declaration and
+metadata for Java applications. To use it, you annotate domain model properties with
+declarative validation constraints which are then enforced by the runtime. There are
+built-in constraints, and you can also define your own custom constraints.
+
+Consider the following example, which shows a simple `PersonForm` model with two properties:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class PersonForm {
+ private String name;
+ private int age;
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class PersonForm(
+ private val name: String,
+ private val age: Int
+ )
+----
+======
+
+Bean Validation lets you declare constraints as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ public class PersonForm {
+
+ @NotNull
+ @Size(max=64)
+ private String name;
+
+ @Min(0)
+ private int age;
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ class PersonForm(
+ @get:NotNull @get:Size(max=64)
+ private val name: String,
+ @get:Min(0)
+ private val age: Int
+ )
+----
+======
+
+A Bean Validation validator then validates instances of this class based on the declared
+constraints. See https://beanvalidation.org/[Bean Validation] for general information about
+the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for
+specific constraints. To learn how to set up a bean validation provider as a Spring
+bean, keep reading.
+
+
+
+[[validation-beanvalidation-spring]]
+== Configuring a Bean Validation Provider
+
+Spring provides full support for the Bean Validation API including the bootstrapping of a
+Bean Validation provider as a Spring bean. This lets you inject a
+`jakarta.validation.ValidatorFactory` or `jakarta.validation.Validator` wherever validation
+is needed in your application.
+
+You can use the `LocalValidatorFactoryBean` to configure a default Validator as a Spring
+bean, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public LocalValidatorFactoryBean validator() {
+ return new LocalValidatorFactoryBean();
+ }
+ }
+----
+
+XML::
++
+[source,xml,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+
+----
+======
+
+The basic configuration in the preceding example triggers bean validation to initialize by
+using its default bootstrap mechanism. A Bean Validation provider, such as the Hibernate
+Validator, is expected to be present in the classpath and is automatically detected.
+
+
+[[validation-beanvalidation-spring-inject]]
+=== Injecting a Validator
+
+`LocalValidatorFactoryBean` implements both `jakarta.validation.ValidatorFactory` and
+`jakarta.validation.Validator`, as well as Spring's `org.springframework.validation.Validator`.
+You can inject a reference to either of these interfaces into beans that need to invoke
+validation logic.
+
+You can inject a reference to `jakarta.validation.Validator` if you prefer to work with the Bean
+Validation API directly, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.validation.Validator;
+
+ @Service
+ public class MyService {
+
+ @Autowired
+ private Validator validator;
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.validation.Validator;
+
+ @Service
+ class MyService(@Autowired private val validator: Validator)
+----
+======
+
+You can inject a reference to `org.springframework.validation.Validator` if your bean
+requires the Spring Validation API, as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import org.springframework.validation.Validator;
+
+ @Service
+ public class MyService {
+
+ @Autowired
+ private Validator validator;
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import org.springframework.validation.Validator
+
+ @Service
+ class MyService(@Autowired private val validator: Validator)
+----
+======
+
+
+[[validation-beanvalidation-spring-constraints]]
+=== Configuring Custom Constraints
+
+Each bean validation constraint consists of two parts:
+
+* A `@Constraint` annotation that declares the constraint and its configurable properties.
+* An implementation of the `jakarta.validation.ConstraintValidator` interface that implements
+the constraint's behavior.
+
+To associate a declaration with an implementation, each `@Constraint` annotation
+references a corresponding `ConstraintValidator` implementation class. At runtime, a
+`ConstraintValidatorFactory` instantiates the referenced implementation when the
+constraint annotation is encountered in your domain model.
+
+By default, the `LocalValidatorFactoryBean` configures a `SpringConstraintValidatorFactory`
+that uses Spring to create `ConstraintValidator` instances. This lets your custom
+`ConstraintValidators` benefit from dependency injection like any other Spring bean.
+
+The following example shows a custom `@Constraint` declaration followed by an associated
+`ConstraintValidator` implementation that uses Spring for dependency injection:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Target({ElementType.METHOD, ElementType.FIELD})
+ @Retention(RetentionPolicy.RUNTIME)
+ @Constraint(validatedBy=MyConstraintValidator.class)
+ public @interface MyConstraint {
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.FIELD)
+ @Retention(AnnotationRetention.RUNTIME)
+ @Constraint(validatedBy = MyConstraintValidator::class)
+ annotation class MyConstraint
+----
+======
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import jakarta.validation.ConstraintValidator;
+
+ public class MyConstraintValidator implements ConstraintValidator {
+
+ @Autowired;
+ private Foo aDependency;
+
+ // ...
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ import jakarta.validation.ConstraintValidator
+
+ class MyConstraintValidator(private val aDependency: Foo) : ConstraintValidator {
+
+ // ...
+ }
+----
+======
+
+
+As the preceding example shows, a `ConstraintValidator` implementation can have its dependencies
+`@Autowired` as any other Spring bean.
+
+
+[[validation-beanvalidation-spring-method]]
+=== Spring-driven Method Validation
+
+You can integrate the method validation feature supported by Bean Validation 1.1 (and, as
+a custom extension, also by Hibernate Validator 4.3) into a Spring context through a
+`MethodValidationPostProcessor` bean definition:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
+
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public MethodValidationPostProcessor validationPostProcessor() {
+ return new MethodValidationPostProcessor();
+ }
+ }
+
+----
+
+XML::
++
+[source,xml,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+
+----
+======
+
+To be eligible for Spring-driven method validation, all target classes need to be annotated
+with Spring's `@Validated` annotation, which can optionally also declare the validation
+groups to use. See
+{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]
+for setup details with the Hibernate Validator and Bean Validation 1.1 providers.
+
+[TIP]
+====
+Method validation relies on xref:core/aop/introduction-proxies.adoc[AOP Proxies] around the
+target classes, either JDK dynamic proxies for methods on interfaces or CGLIB proxies.
+There are certain limitations with the use of proxies, some of which are described in
+xref:core/aop/proxying.adoc#aop-understanding-aop-proxies[Understanding AOP Proxies]. In addition remember
+to always use methods and accessors on proxied classes; direct field access will not work.
+====
+
+
+
+
+[[validation-beanvalidation-spring-other]]
+=== Additional Configuration Options
+
+The default `LocalValidatorFactoryBean` configuration suffices for most
+cases. There are a number of configuration options for various Bean Validation
+constructs, from message interpolation to traversal resolution. See the
+{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]
+javadoc for more information on these options.
+
+
+
+[[validation-binder]]
+== Configuring a `DataBinder`
+
+You can configure a `DataBinder` instance with a `Validator`. Once configured, you can
+invoke the `Validator` by calling `binder.validate()`. Any validation `Errors` are
+automatically added to the binder's `BindingResult`.
+
+The following example shows how to use a `DataBinder` programmatically to invoke validation
+logic after binding to a target object:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ Foo target = new Foo();
+ DataBinder binder = new DataBinder(target);
+ binder.setValidator(new FooValidator());
+
+ // bind to the target object
+ binder.bind(propertyValues);
+
+ // validate the target object
+ binder.validate();
+
+ // get BindingResult that includes any validation errors
+ BindingResult results = binder.getBindingResult();
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val target = Foo()
+ val binder = DataBinder(target)
+ binder.validator = FooValidator()
+
+ // bind to the target object
+ binder.bind(propertyValues)
+
+ // validate the target object
+ binder.validate()
+
+ // get BindingResult that includes any validation errors
+ val results = binder.bindingResult
+----
+======
+
+You can also configure a `DataBinder` with multiple `Validator` instances through
+`dataBinder.addValidators` and `dataBinder.replaceValidators`. This is useful when
+combining globally configured bean validation with a Spring `Validator` configured
+locally on a DataBinder instance. See
+xref:web/webmvc/mvc-config/validation.adoc[Spring MVC Validation Configuration].
+
+
+
+[[validation-mvc]]
+== Spring MVC 3 Validation
+
+See xref:web/webmvc/mvc-config/validation.adoc[Validation] in the Spring MVC chapter.
diff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc
new file mode 100644
index 000000000000..49deddde0c33
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc
@@ -0,0 +1,28 @@
+[[validation-conversion]]
+= Resolving Codes to Error Messages
+
+We covered databinding and validation. This section covers outputting messages that correspond
+to validation errors. In the example shown in the xref:core/validation/validator.adoc[preceding section],
+we rejected the `name` and `age` fields. If we want to output the error messages by using a
+`MessageSource`, we can do so using the error code we provide when rejecting the field
+('name' and 'age' in this case). When you call (either directly, or indirectly, by using,
+for example, the `ValidationUtils` class) `rejectValue` or one of the other `reject` methods
+from the `Errors` interface, the underlying implementation not only registers the code you
+passed in but also registers a number of additional error codes. The `MessageCodesResolver`
+determines which error codes the `Errors` interface registers. By default, the
+`DefaultMessageCodesResolver` is used, which (for example) not only registers a message
+with the code you gave but also registers messages that include the field name you passed
+to the reject method. So, if you reject a field by using `rejectValue("age", "too.darn.old")`,
+apart from the `too.darn.old` code, Spring also registers `too.darn.old.age` and
+`too.darn.old.age.int` (the first includes the field name and the second includes the type
+of the field). This is done as a convenience to aid developers when targeting error messages.
+
+More information on the `MessageCodesResolver` and the default strategy can be found
+in the javadoc of
+{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and
+{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],
+respectively.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/validation/convert.adoc b/framework-docs/modules/ROOT/pages/core/validation/convert.adoc
new file mode 100644
index 000000000000..4d6c6391ab40
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/validation/convert.adoc
@@ -0,0 +1,342 @@
+[[core-convert]]
+= Spring Type Conversion
+
+The `core.convert` package provides a general type conversion system. The system defines
+an SPI to implement type conversion logic and an API to perform type conversions at
+runtime. Within a Spring container, you can use this system as an alternative to
+`PropertyEditor` implementations to convert externalized bean property value strings to
+the required property types. You can also use the public API anywhere in your application
+where type conversion is needed.
+
+
+
+[[core-convert-Converter-API]]
+== Converter SPI
+
+The SPI to implement type conversion logic is simple and strongly typed, as the following
+interface definition shows:
+
+[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
+----
+ package org.springframework.core.convert.converter;
+
+ public interface Converter {
+
+ T convert(S source);
+ }
+----
+
+To create your own converter, implement the `Converter` interface and parameterize `S`
+as the type you are converting from and `T` as the type you are converting to. You can also transparently apply such a
+converter if a collection or array of `S` needs to be
+converted to an array or collection of `T`, provided that a delegating array or collection
+converter has been registered as well (which `DefaultConversionService` does by default).
+
+For each call to `convert(S)`, the source argument is guaranteed to not be null. Your
+`Converter` may throw any unchecked exception if conversion fails. Specifically, it should throw an
+`IllegalArgumentException` to report an invalid source value.
+Take care to ensure that your `Converter` implementation is thread-safe.
+
+Several converter implementations are provided in the `core.convert.support` package as
+a convenience. These include converters from strings to numbers and other common types.
+The following listing shows the `StringToInteger` class, which is a typical `Converter` implementation:
+
+[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
+----
+ package org.springframework.core.convert.support;
+
+ final class StringToInteger implements Converter {
+
+ public Integer convert(String source) {
+ return Integer.valueOf(source);
+ }
+ }
+----
+
+
+
+[[core-convert-ConverterFactory-SPI]]
+== Using `ConverterFactory`
+
+When you need to centralize the conversion logic for an entire class hierarchy
+(for example, when converting from `String` to `Enum` objects), you can implement
+`ConverterFactory`, as the following example shows:
+
+[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
+----
+ package org.springframework.core.convert.converter;
+
+ public interface ConverterFactory {
+
+ Converter getConverter(Class targetType);
+ }
+----
+
+Parameterize S to be the type you are converting from and R to be the base type defining
+the __range__ of classes you can convert to. Then implement `getConverter(Class)`,
+where T is a subclass of R.
+
+Consider the `StringToEnumConverterFactory` as an example:
+
+[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
+----
+ package org.springframework.core.convert.support;
+
+ final class StringToEnumConverterFactory implements ConverterFactory {
+
+ public Converter getConverter(Class targetType) {
+ return new StringToEnumConverter(targetType);
+ }
+
+ private final class StringToEnumConverter implements Converter {
+
+ private Class enumType;
+
+ public StringToEnumConverter(Class enumType) {
+ this.enumType = enumType;
+ }
+
+ public T convert(String source) {
+ return (T) Enum.valueOf(this.enumType, source.trim());
+ }
+ }
+ }
+----
+
+
+[[core-convert-GenericConverter-SPI]]
+== Using `GenericConverter`
+
+When you require a sophisticated `Converter` implementation, consider using the
+`GenericConverter` interface. With a more flexible but less strongly typed signature
+than `Converter`, a `GenericConverter` supports converting between multiple source and
+target types. In addition, a `GenericConverter` makes available source and target field
+context that you can use when you implement your conversion logic. Such context lets a
+type conversion be driven by a field annotation or by generic information declared on a
+field signature. The following listing shows the interface definition of `GenericConverter`:
+
+[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
+----
+ package org.springframework.core.convert.converter;
+
+ public interface GenericConverter {
+
+ public Set getConvertibleTypes();
+
+ Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
+ }
+----
+
+To implement a `GenericConverter`, have `getConvertibleTypes()` return the supported
+source->target type pairs. Then implement `convert(Object, TypeDescriptor,
+TypeDescriptor)` to contain your conversion logic. The source `TypeDescriptor` provides
+access to the source field that holds the value being converted. The target `TypeDescriptor`
+provides access to the target field where the converted value is to be set.
+
+A good example of a `GenericConverter` is a converter that converts between a Java array
+and a collection. Such an `ArrayToCollectionConverter` introspects the field that declares
+the target collection type to resolve the collection's element type. This lets each
+element in the source array be converted to the collection element type before the
+collection is set on the target field.
+
+NOTE: Because `GenericConverter` is a more complex SPI interface, you should use
+it only when you need it. Favor `Converter` or `ConverterFactory` for basic type
+conversion needs.
+
+
+[[core-convert-ConditionalGenericConverter-SPI]]
+=== Using `ConditionalGenericConverter`
+
+Sometimes, you want a `Converter` to run only if a specific condition holds true. For
+example, you might want to run a `Converter` only if a specific annotation is present
+on the target field, or you might want to run a `Converter` only if a specific method
+(such as a `static valueOf` method) is defined on the target class.
+`ConditionalGenericConverter` is the union of the `GenericConverter` and
+`ConditionalConverter` interfaces that lets you define such custom matching criteria:
+
+[source,java,indent=0,subs="verbatim,quotes"]
+----
+ public interface ConditionalConverter {
+
+ boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
+ }
+
+ public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
+ }
+----
+
+A good example of a `ConditionalGenericConverter` is an `IdToEntityConverter` that converts
+between a persistent entity identifier and an entity reference. Such an `IdToEntityConverter`
+might match only if the target entity type declares a static finder method (for example,
+`findAccount(Long)`). You might perform such a finder method check in the implementation of
+`matches(TypeDescriptor, TypeDescriptor)`.
+
+
+
+[[core-convert-ConversionService-API]]
+== The `ConversionService` API
+
+`ConversionService` defines a unified API for executing type conversion logic at
+runtime. Converters are often run behind the following facade interface:
+
+[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
+----
+ package org.springframework.core.convert;
+
+ public interface ConversionService {
+
+ boolean canConvert(Class> sourceType, Class> targetType);
+
+ T convert(Object source, Class targetType);
+
+ boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
+
+ Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
+ }
+----
+
+Most `ConversionService` implementations also implement `ConverterRegistry`, which
+provides an SPI for registering converters. Internally, a `ConversionService`
+implementation delegates to its registered converters to carry out type conversion logic.
+
+A robust `ConversionService` implementation is provided in the `core.convert.support`
+package. `GenericConversionService` is the general-purpose implementation suitable for
+use in most environments. `ConversionServiceFactory` provides a convenient factory for
+creating common `ConversionService` configurations.
+
+
+
+[[core-convert-Spring-config]]
+== Configuring a `ConversionService`
+
+A `ConversionService` is a stateless object designed to be instantiated at application
+startup and then shared between multiple threads. In a Spring application, you typically
+configure a `ConversionService` instance for each Spring container (or `ApplicationContext`).
+Spring picks up that `ConversionService` and uses it whenever a type
+conversion needs to be performed by the framework. You can also inject this
+`ConversionService` into any of your beans and invoke it directly.
+
+NOTE: If no `ConversionService` is registered with Spring, the original `PropertyEditor`-based
+system is used.
+
+To register a default `ConversionService` with Spring, add the following bean definition
+with an `id` of `conversionService`:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+----
+
+A default `ConversionService` can convert between strings, numbers, enums, collections,
+maps, and other common types. To supplement or override the default converters with your
+own custom converters, set the `converters` property. Property values can implement
+any of the `Converter`, `ConverterFactory`, or `GenericConverter` interfaces.
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+----
+
+It is also common to use a `ConversionService` within a Spring MVC application. See
+xref:web/webmvc/mvc-config/conversion.adoc[Conversion and Formatting] in the Spring MVC chapter.
+
+In certain situations, you may wish to apply formatting during conversion. See
+xref:core/validation/format.adoc#format-FormatterRegistry-SPI[The `FormatterRegistry` SPI] for details on using `FormattingConversionServiceFactoryBean`.
+
+
+
+[[core-convert-programmatic-usage]]
+== Using a `ConversionService` Programmatically
+
+To work with a `ConversionService` instance programmatically, you can inject a reference to
+it like you would for any other bean. The following example shows how to do so:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Service
+ public class MyService {
+
+ public MyService(ConversionService conversionService) {
+ this.conversionService = conversionService;
+ }
+
+ public void doIt() {
+ this.conversionService.convert(...)
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Service
+ class MyService(private val conversionService: ConversionService) {
+
+ fun doIt() {
+ conversionService.convert(...)
+ }
+ }
+----
+======
+
+For most use cases, you can use the `convert` method that specifies the `targetType`, but it
+does not work with more complex types, such as a collection of a parameterized element.
+For example, if you want to convert a `List` of `Integer` to a `List` of `String` programmatically,
+you need to provide a formal definition of the source and target types.
+
+Fortunately, `TypeDescriptor` provides various options to make doing so straightforward,
+as the following example shows:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ DefaultConversionService cs = new DefaultConversionService();
+
+ List input = ...
+ cs.convert(input,
+ TypeDescriptor.forObject(input), // List type descriptor
+ TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class)));
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ val cs = DefaultConversionService()
+
+ val input: List = ...
+ cs.convert(input,
+ TypeDescriptor.forObject(input), // List type descriptor
+ TypeDescriptor.collection(List::class.java, TypeDescriptor.valueOf(String::class.java)))
+----
+======
+
+Note that `DefaultConversionService` automatically registers converters that are
+appropriate for most environments. This includes collection converters, scalar
+converters, and basic `Object`-to-`String` converters. You can register the same converters
+with any `ConverterRegistry` by using the static `addDefaultConverters`
+method on the `DefaultConversionService` class.
+
+Converters for value types are reused for arrays and collections, so there is
+no need to create a specific converter to convert from a `Collection` of `S` to a
+`Collection` of `T`, assuming that standard collection handling is appropriate.
+
+
+
+
diff --git a/framework-docs/modules/ROOT/pages/core/validation/format-configuring-formatting-globaldatetimeformat.adoc b/framework-docs/modules/ROOT/pages/core/validation/format-configuring-formatting-globaldatetimeformat.adoc
new file mode 100644
index 000000000000..82fc655f1310
--- /dev/null
+++ b/framework-docs/modules/ROOT/pages/core/validation/format-configuring-formatting-globaldatetimeformat.adoc
@@ -0,0 +1,121 @@
+[[format-configuring-formatting-globaldatetimeformat]]
+= Configuring a Global Date and Time Format
+
+By default, date and time fields not annotated with `@DateTimeFormat` are converted from
+strings by using the `DateFormat.SHORT` style. If you prefer, you can change this by
+defining your own global format.
+
+To do that, ensure that Spring does not register default formatters. Instead, register
+formatters manually with the help of:
+
+* `org.springframework.format.datetime.standard.DateTimeFormatterRegistrar`
+* `org.springframework.format.datetime.DateFormatterRegistrar`
+
+For example, the following Java configuration registers a global `yyyyMMdd` format:
+
+[tabs]
+======
+Java::
++
+[source,java,indent=0,subs="verbatim,quotes",role="primary"]
+----
+ @Configuration
+ public class AppConfig {
+
+ @Bean
+ public FormattingConversionService conversionService() {
+
+ // Use the DefaultFormattingConversionService but do not register defaults
+ DefaultFormattingConversionService conversionService =
+ new DefaultFormattingConversionService(false);
+
+ // Ensure @NumberFormat is still supported
+ conversionService.addFormatterForFieldAnnotation(
+ new NumberFormatAnnotationFormatterFactory());
+
+ // Register JSR-310 date conversion with a specific global format
+ DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
+ dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"));
+ dateTimeRegistrar.registerFormatters(conversionService);
+
+ // Register date conversion with a specific global format
+ DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
+ dateRegistrar.setFormatter(new DateFormatter("yyyyMMdd"));
+ dateRegistrar.registerFormatters(conversionService);
+
+ return conversionService;
+ }
+ }
+----
+
+Kotlin::
++
+[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+ @Configuration
+ class AppConfig {
+
+ @Bean
+ fun conversionService(): FormattingConversionService {
+ // Use the DefaultFormattingConversionService but do not register defaults
+ return DefaultFormattingConversionService(false).apply {
+
+ // Ensure @NumberFormat is still supported
+ addFormatterForFieldAnnotation(NumberFormatAnnotationFormatterFactory())
+
+ // Register JSR-310 date conversion with a specific global format
+ val dateTimeRegistrar = DateTimeFormatterRegistrar()
+ dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"))
+ dateTimeRegistrar.registerFormatters(this)
+
+ // Register date conversion with a specific global format
+ val dateRegistrar = DateFormatterRegistrar()
+ dateRegistrar.setFormatter(DateFormatter("yyyyMMdd"))
+ dateRegistrar.registerFormatters(this)
+ }
+ }
+ }
+----
+======
+
+If you prefer XML-based configuration, you can use a
+`FormattingConversionServiceFactoryBean`. The following example shows how to do so:
+
+[source,xml,indent=0,subs="verbatim,quotes"]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+