Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
+ */
+ @AliasFor(annotation = Scope.class)
+ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
+
+}
+```
+
+Kotlin
+
+```
+@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:
+
+Java
+
+```
+@Service
+@SessionScope
+public class SessionScopedService {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Service
+@SessionScope
+class SessionScopedService {
+ // ...
+}
+```
+
+You can also override the value for the `proxyMode`, as the following example shows:
+
+Java
+
+```
+@Service
+@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
+public class SessionScopedUserService implements UserService {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Service
+@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
+class SessionScopedUserService : UserService {
+ // ...
+}
+```
+
+For further details, see the[Spring Annotation Programming Model](https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model)wiki page.
+
+#### [](#beans-scanning-autodetection)1.10.3. 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:
+
+Java
+
+```
+@Service
+public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ public SimpleMovieLister(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+}
+```
+
+Kotlin
+
+```
+@Service
+class SimpleMovieLister(private val movieFinder: MovieFinder)
+```
+
+Java
+
+```
+@Repository
+public class JpaMovieFinder implements MovieFinder {
+ // implementation elided for clarity
+}
+```
+
+Kotlin
+
+```
+@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.)
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example")
+public class AppConfig {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = ["org.example"])
+class AppConfig {
+ // ...
+}
+```
+
+| |For brevity, the preceding example could have used the `value` attribute of the
annotation (that is, `@ComponentScan("org.example")`).|
+|---|------------------------------------------------------------------------------------------------------------------------------------------|
+
+The following alternative uses XML:
+
+```
+
+
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](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.
+
+| |You can disable the registration of `AutowiredAnnotationBeanPostProcessor` and`CommonAnnotationBeanPostProcessor` by including the `annotation-config` attribute
with a value of `false`.|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-scanning-filters)1.10.4. 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 `
annotation or by providing `use-default-filters="false"` as an attribute of the`
annotated or meta-annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,`@RestController`, or `@Configuration`.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-factorybeans-annotations)1.10.5. 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:
+
+Java
+
+```
+@Component
+public class FactoryMethodComponent {
+
+ @Bean
+ @Qualifier("public")
+ public TestBean publicInstance() {
+ return new TestBean("publicInstance");
+ }
+
+ public void doWork() {
+ // Component method implementation omitted
+ }
+}
+```
+
+Kotlin
+
+```
+@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.
+
+| |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
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)1.10.6. 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`:
+
+Java
+
+```
+@Service("myMovieLister")
+public class SimpleMovieLister {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Service("myMovieLister")
+class SimpleMovieLister {
+ // ...
+}
+```
+
+Java
+
+```
+@Repository
+public class MovieFinderImpl implements MovieFinder {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@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[`BeanNameGenerator`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/support/BeanNameGenerator.html)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.
+
+| |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.|
+|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
+public class AppConfig {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = ["org.example"], nameGenerator = MyNameGenerator::class)
+class AppConfig {
+ // ...
+}
+```
+
+```
+
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 [Request, Session, Application, and WebSocket Scopes](#beans-factory-scopes-other). 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.
+
+| |To provide a custom strategy for scope resolution rather than relying on the
annotation-based approach, you can implement the[`ScopeMetadataResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/ScopeMetadataResolver.html)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:|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
+public class AppConfig {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = ["org.example"], scopeResolver = MyScopeResolver::class)
+class AppConfig {
+ // ...
+}
+```
+
+```
+
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)1.10.9. 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.
+
+| |Your existing `@ComponentScan` or `
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:
+
+```
+
registered as an annotation processor to make sure the index is up-to-date when
candidate components are updated.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+| |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[`SpringProperties`](appendix.html#appendix-spring-properties) mechanism.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#beans-standard-annotations)1.11. Using JSR 330 Standard Annotations ###
+
+Starting with Spring 3.0, 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.
+
+| |If you use Maven, the `javax.inject` artifact is available in the standard Maven
repository ([https://repo1.maven.org/maven2/javax/inject/javax.inject/1/](https://repo1.maven.org/maven2/javax/inject/javax.inject/1/)).
You can add the following dependency to your file pom.xml:
```
```|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-inject-named)1.11.1. Dependency Injection with `@Inject` and `@Named` ####
+
+Instead of `@Autowired`, you can use `@javax.inject.Inject` as follows:
+
+Java
+
+```
+import javax.inject.Inject;
+
+public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ public void listMovies() {
+ this.movieFinder.findMovies(...);
+ // ...
+ }
+}
+```
+
+Kotlin
+
+```
+import javax.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:
+
+Java
+
+```
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+public class SimpleMovieLister {
+
+ private Provider
custom component annotations.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-standard-annotations-limitations)1.11.3. 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:
+
+| Spring | javax.inject.\* | javax.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. `javax.inject` also provides a[@Scope](https://download.oracle.com/javaee/6/api/javax/inject/Scope.html) annotation.
Nevertheless, this one is only intended to be used for creating your own annotations.|
+| @Qualifier | @Qualifier / @Named | `javax.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 `javax.inject.Named`. |
+| @Value | \- | no equivalent |
+| @Required | \- | no equivalent |
+| @Lazy | \- | no equivalent |
+| ObjectFactory | Provider | `javax.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. |
+
+### [](#beans-java)1.12. Java-based Container Configuration ###
+
+This section covers how to use annotations in your Java code to configure the Spring
+container. It includes the following topics:
+
+* [Basic Concepts: `@Bean` and `@Configuration`](#beans-java-basic-concepts)
+
+* [Instantiating the Spring Container by Using `AnnotationConfigApplicationContext`](#beans-java-instantiating-container)
+
+* [Using the `@Bean` Annotation](#beans-java-bean-annotation)
+
+* [Using the `@Configuration` annotation](#beans-java-configuration-annotation)
+
+* [Composing Java-based Configurations](#beans-java-composing-configuration-classes)
+
+* [Bean Definition Profiles](#beans-definition-profiles)
+
+* [`PropertySource` Abstraction](#beans-property-source-abstraction)
+
+* [Using `@PropertySource`](#beans-using-propertysource)
+
+* [Placeholder Resolution in Statements](#beans-placeholder-resolution-in-statements)
+
+#### [](#beans-java-basic-concepts)1.12.1. Basic Concepts: `@Bean` and `@Configuration` ####
+
+The central artifacts in Spring’s new 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 `
Spring’s `context:` namespace, shown in the following example:
```
```|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+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:
+
+Java
+
+```
+public static void main(String[] args) {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.scan("com.acme");
+ ctx.refresh();
+ MyService myService = ctx.getBean(MyService.class);
+}
+```
+
+Kotlin
+
+```
+fun main() {
+ val ctx = AnnotationConfigApplicationContext()
+ ctx.scan("com.acme")
+ ctx.refresh()
+ val myService = ctx.getBean
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):
+
+```
+
alternative to `AnnotationConfigWebApplicationContext`. See the[`GenericWebApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/context/support/GenericWebApplicationContext.html)javadoc for details.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-java-bean-annotation)1.12.3. Using the `@Bean` Annotation ####
+
+`@Bean` is a method-level annotation and a direct analog of the XML `
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:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public TransferService transferService(AccountRepository accountRepository) {
+ return new TransferServiceImpl(accountRepository);
+ }
+}
+```
+
+Kotlin
+
+```
+@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 [the relevant section](#beans-constructor-injection) 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[JSR-250 annotations](#beans-postconstruct-and-predestroy-annotations) for further
+details.
+
+The regular Spring [lifecycle](#beans-factory-nature) 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 [BeanFactoryAware](#beans-beanfactory),[BeanNameAware](#beans-factory-aware),[MessageSourceAware](#context-functionality-messagesource),[ApplicationContextAware](#beans-factory-aware), 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:
+
+Java
+
+```
+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
+
+```
+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()
+}
+```
+
+| |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 Java EE application servers.
The following example shows how to prevent an automatic destruction callback for a`DataSource`:
Java
```
@Bean(destroyMethod="")
public DataSource dataSource() throws NamingException {
return (DataSource) jndiTemplate.lookup("MyDS");
}
```
Kotlin
```
@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:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public BeanOne beanOne() {
+ BeanOne beanOne = new BeanOne();
+ beanOne.init();
+ return beanOne;
+ }
+
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean
+ fun beanOne() = BeanOne().apply {
+ init()
+ }
+
+ // ...
+}
+```
+
+| |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[Bean Scopes](#beans-factory-scopes) section.
+
+The default scope is `singleton`, but you can override this with the `@Scope` annotation,
+as the following example shows:
+
+Java
+
+```
+@Configuration
+public class MyConfiguration {
+
+ @Bean
+ @Scope("prototype")
+ public Encryptor encryptor() {
+ // ...
+ }
+}
+```
+
+Kotlin
+
+```
+@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[scoped proxies](#beans-factory-scopes-other-injection). The easiest way to create
+such a proxy when using the XML configuration is the `
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, [lookup method injection](#beans-factory-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:
+
+Java
+
+```
+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
+
+```
+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:
+
+Java
+
+```
+@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
+
+```
+@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:
+
+Java
+
+```
+@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
+
+```
+@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.
+
+| |The behavior could be different according to the scope of your bean. We are talking
about singletons here.|
+|---|--------------------------------------------------------------------------------------------------------------|
+
+| |As of Spring 3.2, it is no longer necessary to add CGLIB to your classpath because CGLIB
classes have been repackaged under `org.springframework.cglib` and included directly
within the spring-core JAR.|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+| |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, as
of 4.3, 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).
Cross-method calls between `@Bean` methods are not then intercepted, so you have
to exclusively rely on dependency injection at the constructor or method level there.|
+|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-java-composing-configuration-classes)1.12.5. 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 `
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 [we already discussed](#beans-java-dependencies),
+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:
+
+Java
+
+```
+@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
+
+```
+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
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[`AutowiredAnnotationBeanPostProcessor`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html).|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+The following example shows how one bean can be autowired to another bean:
+
+Java
+
+```
+@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
+
+```
+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
Framework 4.3. Note also that there is no need to specify `@Autowired` if the target
bean defines only one constructor.|
+|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+[]()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[Spring Tools for Eclipse](https://spring.io/tools) 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:
+
+Java
+
+```
+@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
+
+```
+@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:
+
+Java
+
+```
+@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
+
+```
+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
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 [Bean Definition Profiles](#beans-definition-profiles)for details).
+
+The `@Profile` annotation is actually implemented by using a much more flexible annotation
+called [`@Conditional`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Conditional.html).
+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`:
+
+Java
+
+```
+@Override
+public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ // Read the @Profile annotation attributes
+ MultiValueMap
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.|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+[]() Using \
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
+
+| |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 [meta-annotation](#beans-meta-annotations) 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")`:
+
+Java
+
+```
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Profile("production")
+public @interface Production {
+}
+```
+
+Kotlin
+
+```
+@Target(AnnotationTarget.TYPE)
+@Retention(AnnotationRetention.RUNTIME)
+@Profile("production")
+annotation class Production
+```
+
+| |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:
+
+Java
+
+```
+@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. |
+
+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. |
+
+| |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 `
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:
```
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">
```
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:
+
+Java
+
+```
+AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ctx.getEnvironment().setActiveProfiles("development");
+ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
+ctx.refresh();
+```
+
+Kotlin
+
+```
+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 [`PropertySource` Abstraction](#beans-property-source-abstraction)). In integration tests, active
+profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test`module (see [context configuration with environment profiles](testing.html#testcontext-ctx-management-env-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:
+
+Java
+
+```
+ctx.getEnvironment().setActiveProfiles("profile1", "profile2");
+```
+
+Kotlin
+
+```
+ctx.getEnvironment().setActiveProfiles("profile1", "profile2")
+```
+
+Declaratively, `spring.profiles.active` may accept a comma-separated list of profile names,
+as the following example shows:
+
+```
+ -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:
+
+Java
+
+```
+@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
+
+```
+@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)1.13.2. `PropertySource` Abstraction ####
+
+Spring’s `Environment` abstraction provides search operations over a configurable
+hierarchy of property sources. Consider the following listing:
+
+Java
+
+```
+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
+
+```
+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 [`PropertySource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/env/PropertySource.html)objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and
+Spring’s [`StandardEnvironment`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/env/StandardEnvironment.html)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()`).
+
+| |These default property sources are present for `StandardEnvironment`, for use in standalone
applications. [`StandardServletEnvironment`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/context/support/StandardServletEnvironment.html)is populated with additional default property sources including servlet config and servlet
context parameters. It can optionally enable a [`JndiPropertySource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jndi/JndiPropertySource.html).
See the javadoc for details.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+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.
+
+| |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:
1. ServletConfig parameters (if applicable — for example, in case of a `DispatcherServlet` context)
2. ServletContext parameters (web.xml context-param entries)
3. JNDI environment variables (`java:comp/env/` entries)
4. JVM system properties (`-D` command-line arguments)
5. 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:
+
+Java
+
+```
+ConfigurableApplicationContext ctx = new GenericApplicationContext();
+MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
+sources.addFirst(new MyPropertySource());
+```
+
+Kotlin
+
+```
+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[`MutablePropertySources`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/env/MutablePropertySources.html)API exposes a number of methods that allow for precise manipulation of the set of
+property sources.
+
+#### [](#beans-using-propertysource)1.13.3. Using `@PropertySource` ####
+
+The [`@PropertySource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/PropertySource.html)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`:
+
+Java
+
+```
+@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
+
+```
+@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:
+
+Java
+
+```
+@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
+
+```
+@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.
+
+| |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)1.13.4. 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`:
+
+```
+
+
+
bundles with the same base name, but will only use the first bundle found.
Subsequent message bundles with the same base name are ignored.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+| |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 [`ReloadableResourceBundleMessageSource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html)javadoc for details.|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#context-functionality-events)1.15.2. 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.
+
+| |As of Spring 4.2, the event infrastructure has been significantly improved and offers
an [annotation-based model](#context-functionality-events-annotation) 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:
+
+| 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:
+
+Java
+
+```
+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
+
+```
+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:
+
+Java
+
+```
+public class EmailService implements ApplicationEventPublisherAware {
+
+ private List
+
+
within the same application context. However, for more sophisticated enterprise
integration needs, the separately maintained[Spring Integration](https://projects.spring.io/spring-integration/) project provides
complete support for building lightweight,[pattern-oriented](https://www.enterpriseintegrationpatterns.com), 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:
+
+Java
+
+```
+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
+
+```
+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:
+
+Java
+
+```
+@EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})
+public void handleContextStart() {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@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 [`SpEL` expression](#expressions), 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`:
+
+Java
+
+```
+@EventListener(condition = "#blEvent.content == 'my-event'")
+public void processBlockedListEvent(BlockedListEvent blEvent) {
+ // notify appropriate parties via notificationAddress...
+}
+```
+
+Kotlin
+
+```
+@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:
+
+| 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:
+
+Java
+
+```
+@EventListener
+public ListUpdateEvent handleBlockedListEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress and
+ // then publish a ListUpdateEvent...
+}
+```
+
+Kotlin
+
+```
+@EventListener
+fun handleBlockedListEvent(event: BlockedListEvent): ListUpdateEvent {
+ // notify appropriate parties via notificationAddress and
+ // then publish a ListUpdateEvent...
+}
+```
+
+| |This feature is not supported for[asynchronous listeners](#context-functionality-events-async).|
+|---|-----------------------------------------------------------------------------------------------|
+
+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[regular `@Async` support](integration.html#scheduling-annotation-support-async).
+The following example shows how to do so:
+
+Java
+
+```
+@EventListener
+@Async
+public void processBlockedListEvent(BlockedListEvent event) {
+ // BlockedListEvent is processed in a separate thread
+}
+```
+
+Kotlin
+
+```
+@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[`AsyncUncaughtExceptionHandler`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html)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[`ApplicationEventPublisher`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/ApplicationEventPublisher.html)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:
+
+Java
+
+```
+@EventListener
+@Order(42)
+public void processBlockedListEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress...
+}
+```
+
+Kotlin
+
+```
+@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
an event.|
+|---|--------------------------------------------------------------------------------------------------|
+
+#### [](#context-functionality-resources)1.15.3. 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 [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)1.15.4. 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`:
+
+Java
+
+```
+// 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
+
+```
+// 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[dedicated appendix section](#application-startup-steps).
+
+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.
+
+| |`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 [Micrometer](https://micrometer.io).|
+|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+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.
+
+| |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)1.15.5. 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:
+
+```
+
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.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#beans-beanfactory)1.16. The `BeanFactory` ###
+
+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)1.16.1. `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 [`BeanPostProcessor` extension point](#beans-factory-extension-bpp) 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.
+
+| 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:
+
+Java
+
+```
+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
+
+```
+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:
+
+Java
+
+```
+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
+
+```
+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.
+
+| |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.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+[](#resources)2. Resources
+----------
+
+This chapter covers how Spring handles resources and how you can work with resources in
+Spring. It includes the following topics:
+
+* [Introduction](#resources-introduction)
+
+* [The `Resource` Interface](#resources-resource)
+
+* [Built-in `Resource` Implementations](#resources-implementations)
+
+* [The `ResourceLoader` Interface](#resources-resourceloader)
+
+* [The `ResourcePatternResolver` Interface](#resources-resourcepatternresolver)
+
+* [The `ResourceLoaderAware` Interface](#resources-resourceloaderaware)
+
+* [Resources as Dependencies](#resources-as-dependencies)
+
+* [Application Contexts and Resource Paths](#resources-app-ctx)
+
+### [](#resources-introduction)2.1. Introduction ###
+
+Java’s standard `java.net.URL` class and standard handlers for various URL prefixes,
+unfortunately, are not quite adequate enough for all access to low-level resources. For
+example, there is no standardized `URL` implementation that may be used to access a
+resource that needs to be obtained from the classpath or relative to a`ServletContext`. While it is possible to register new handlers for specialized `URL`prefixes (similar to existing handlers for prefixes such as `http:`), this is generally
+quite complicated, and the `URL` interface still lacks some desirable functionality,
+such as a method to check for the existence of the resource being pointed to.
+
+### [](#resources-resource)2.2. The `Resource` Interface ###
+
+Spring’s `Resource` interface located in the `org.springframework.core.io.` package is
+meant to be a more capable interface for abstracting access to low-level resources. The
+following listing provides an overview of the `Resource` interface. See the[`Resource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/io/Resource.html) javadoc for further details.
+
+```
+public interface Resource extends InputStreamSource {
+
+ boolean exists();
+
+ boolean isReadable();
+
+ boolean isOpen();
+
+ boolean isFile();
+
+ URL getURL() throws IOException;
+
+ URI getURI() throws IOException;
+
+ File getFile() throws IOException;
+
+ ReadableByteChannel readableChannel() throws IOException;
+
+ long contentLength() throws IOException;
+
+ long lastModified() throws IOException;
+
+ Resource createRelative(String relativePath) throws IOException;
+
+ String getFilename();
+
+ String getDescription();
+}
+```
+
+As the definition of the `Resource` interface shows, it extends the `InputStreamSource`interface. The following listing shows the definition of the `InputStreamSource`interface:
+
+```
+public interface InputStreamSource {
+
+ InputStream getInputStream() throws IOException;
+}
+```
+
+Some of the most important methods from the `Resource` interface are:
+
+* `getInputStream()`: Locates and opens the resource, returning an `InputStream` for
+ reading from the resource. It is expected that each invocation returns a fresh`InputStream`. It is the responsibility of the caller to close the stream.
+
+* `exists()`: Returns a `boolean` indicating whether this resource actually exists in
+ physical form.
+
+* `isOpen()`: Returns a `boolean` indicating whether this resource represents a handle
+ with an open stream. If `true`, the `InputStream` cannot be read multiple times and
+ must be read once only and then closed to avoid resource leaks. Returns `false` for
+ all usual resource implementations, with the exception of `InputStreamResource`.
+
+* `getDescription()`: Returns a description for this resource, to be used for error
+ output when working with the resource. This is often the fully qualified file name or
+ the actual URL of the resource.
+
+Other methods let you obtain an actual `URL` or `File` object representing the
+resource (if the underlying implementation is compatible and supports that
+functionality).
+
+Some implementations of the `Resource` interface also implement the extended[`WritableResource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/io/WritableResource.html) interface
+for a resource that supports writing to it.
+
+Spring itself uses the `Resource` abstraction extensively, as an argument type in
+many method signatures when a resource is needed. Other methods in some Spring APIs
+(such as the constructors to various `ApplicationContext` implementations) take a`String` which in unadorned or simple form is used to create a `Resource` appropriate to
+that context implementation or, via special prefixes on the `String` path, let the
+caller specify that a specific `Resource` implementation must be created and used.
+
+While the `Resource` interface is used a lot with Spring and by Spring, it is actually
+very convenient to use as a general utility class by itself in your own code, for access
+to resources, even when your code does not know or care about any other parts of Spring.
+While this couples your code to Spring, it really only couples it to this small set of
+utility classes, which serves as a more capable replacement for `URL` and can be
+considered equivalent to any other library you would use for this purpose.
+
+| |The `Resource` abstraction does not replace functionality. It wraps it where
possible. For example, a `UrlResource` wraps a URL and uses the wrapped `URL` to do its
work.|
+|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#resources-implementations)2.3. Built-in `Resource` Implementations ###
+
+Spring includes several built-in `Resource` implementations:
+
+* [`UrlResource`](#resources-implementations-urlresource)
+
+* [`ClassPathResource`](#resources-implementations-classpathresource)
+
+* [`FileSystemResource`](#resources-implementations-filesystemresource)
+
+* [`PathResource`](#resources-implementations-pathresource)
+
+* [`ServletContextResource`](#resources-implementations-servletcontextresource)
+
+* [`InputStreamResource`](#resources-implementations-inputstreamresource)
+
+* [`ByteArrayResource`](#resources-implementations-bytearrayresource)
+
+For a complete list of `Resource` implementations available in Spring, consult the
+"All Known Implementing Classes" section of the[`Resource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/io/Resource.html) javadoc.
+
+#### [](#resources-implementations-urlresource)2.3.1. `UrlResource` ####
+
+`UrlResource` wraps a `java.net.URL` and can be used to access any object that is
+normally accessible with a URL, such as files, an HTTPS target, an FTP target, and
+others. All URLs have a standardized `String` representation, such that appropriate
+standardized prefixes are used to indicate one URL type from another. This includes`file:` for accessing filesystem paths, `https:` for accessing resources through the
+HTTPS protocol, `ftp:` for accessing resources through FTP, and others.
+
+A `UrlResource` is created by Java code by explicitly using the `UrlResource` constructor
+but is often created implicitly when you call an API method that takes a `String`argument meant to represent a path. For the latter case, a JavaBeans `PropertyEditor`ultimately decides which type of `Resource` to create. If the path string contains a
+well-known (to property editor, that is) prefix (such as `classpath:`), it creates an
+appropriate specialized `Resource` for that prefix. However, if it does not recognize the
+prefix, it assumes the string is a standard URL string and creates a `UrlResource`.
+
+#### [](#resources-implementations-classpathresource)2.3.2. `ClassPathResource` ####
+
+This class represents a resource that should be obtained from the classpath. It uses
+either the thread context class loader, a given class loader, or a given class for
+loading resources.
+
+This `Resource` implementation supports resolution as a `java.io.File` if the class path
+resource resides in the file system but not for classpath resources that reside in a
+jar and have not been expanded (by the servlet engine or whatever the environment is)
+to the filesystem. To address this, the various `Resource` implementations always support
+resolution as a `java.net.URL`.
+
+A `ClassPathResource` is created by Java code by explicitly using the `ClassPathResource`constructor but is often created implicitly when you call an API method that takes a`String` argument meant to represent a path. For the latter case, a JavaBeans`PropertyEditor` recognizes the special prefix, `classpath:`, on the string path and
+creates a `ClassPathResource` in that case.
+
+#### [](#resources-implementations-filesystemresource)2.3.3. `FileSystemResource` ####
+
+This is a `Resource` implementation for `java.io.File` handles. It also supports`java.nio.file.Path` handles, applying Spring’s standard String-based path
+transformations but performing all operations via the `java.nio.file.Files` API. For pure`java.nio.path.Path` based support use a `PathResource` instead. `FileSystemResource`supports resolution as a `File` and as a `URL`.
+
+#### [](#resources-implementations-pathresource)2.3.4. `PathResource` ####
+
+This is a `Resource` implementation for `java.nio.file.Path` handles, performing all
+operations and transformations via the `Path` API. It supports resolution as a `File` and
+as a `URL` and also implements the extended `WritableResource` interface. `PathResource`is effectively a pure `java.nio.path.Path` based alternative to `FileSystemResource` with
+different `createRelative` behavior.
+
+#### [](#resources-implementations-servletcontextresource)2.3.5. `ServletContextResource` ####
+
+This is a `Resource` implementation for `ServletContext` resources that interprets
+relative paths within the relevant web application’s root directory.
+
+It always supports stream access and URL access but allows `java.io.File` access only
+when the web application archive is expanded and the resource is physically on the
+filesystem. Whether or not it is expanded and on the filesystem or accessed
+directly from the JAR or somewhere else like a database (which is conceivable) is actually
+dependent on the Servlet container.
+
+#### [](#resources-implementations-inputstreamresource)2.3.6. `InputStreamResource` ####
+
+An `InputStreamResource` is a `Resource` implementation for a given `InputStream`. It
+should be used only if no specific `Resource` implementation is applicable. In
+particular, prefer `ByteArrayResource` or any of the file-based `Resource`implementations where possible.
+
+In contrast to other `Resource` implementations, this is a descriptor for an
+already-opened resource. Therefore, it returns `true` from `isOpen()`. Do not use it if
+you need to keep the resource descriptor somewhere or if you need to read a stream
+multiple times.
+
+#### [](#resources-implementations-bytearrayresource)2.3.7. `ByteArrayResource` ####
+
+This is a `Resource` implementation for a given byte array. It creates a`ByteArrayInputStream` for the given byte array.
+
+It is useful for loading content from any given byte array without having to resort to a
+single-use `InputStreamResource`.
+
+### [](#resources-resourceloader)2.4. The `ResourceLoader` Interface ###
+
+The `ResourceLoader` interface is meant to be implemented by objects that can return
+(that is, load) `Resource` instances. The following listing shows the `ResourceLoader`interface definition:
+
+```
+public interface ResourceLoader {
+
+ Resource getResource(String location);
+
+ ClassLoader getClassLoader();
+}
+```
+
+All application contexts implement the `ResourceLoader` interface. Therefore, all
+application contexts may be used to obtain `Resource` instances.
+
+When you call `getResource()` on a specific application context, and the location path
+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:
+
+Java
+
+```
+Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
+```
+
+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
+return a `FileSystemResource`. For a `WebApplicationContext`, it would return a`ServletContextResource`. It would similarly return appropriate objects for each context.
+
+As a result, you can load resources in a fashion appropriate to the particular application
+context.
+
+On the other hand, you may also force `ClassPathResource` to be used, regardless of the
+application context type, by specifying the special `classpath:` prefix, as the following
+example shows:
+
+Java
+
+```
+Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
+```
+
+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:
+
+Java
+
+```
+Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
+```
+
+Kotlin
+
+```
+val template = ctx.getResource("file:///some/resource/path/myTemplate.txt")
+```
+
+Java
+
+```
+Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
+```
+
+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:
+
+| Prefix | Example | Explanation |
+|----------|--------------------------------|----------------------------------------------------------------------------------------------------------------------|
+|classpath:|`classpath:com/myapp/config.xml`| Loaded from the classpath. |
+| file: | `file:///data/config.xml` |Loaded as a `URL` from the filesystem. See also [`FileSystemResource` Caveats](#resources-filesystemresource-caveats).|
+| https: | `https://myserver/logo.png` | Loaded as a `URL`. |
+| (none) | `/data/config.xml` | Depends on the underlying `ApplicationContext`. |
+
+### [](#resources-resourcepatternresolver)2.5. The `ResourcePatternResolver` Interface ###
+
+The `ResourcePatternResolver` interface is an extension to the `ResourceLoader` interface
+which defines a strategy for resolving a location pattern (for example, an Ant-style path
+pattern) into `Resource` objects.
+
+```
+public interface ResourcePatternResolver extends ResourceLoader {
+
+ String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
+
+ Resource[] getResources(String locationPattern) throws IOException;
+}
+```
+
+As can be seen above, this interface also defines a special `classpath*:` resource prefix
+for all matching resources from the class path. Note that the resource location is
+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[Wildcards in Application Context Constructor Resource Paths](#resources-app-ctx-wildcards-in-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[`ResourceLoaderAware`](#resources-resourceloaderaware) semantics) can be checked whether
+it implements this extended interface too.
+
+`PathMatchingResourcePatternResolver` is a standalone implementation that is usable
+outside an `ApplicationContext` and is also used by `ResourceArrayPropertyEditor` for
+populating `Resource[]` bean properties. `PathMatchingResourcePatternResolver` is able to
+resolve a specified resource location path into one or more matching `Resource` objects.
+The source path may be a simple path which has a one-to-one mapping to a target`Resource`, or alternatively may contain the special `classpath*:` prefix and/or internal
+Ant-style regular expressions (matched using Spring’s`org.springframework.util.AntPathMatcher` utility). Both of the latter are effectively
+wildcards.
+
+| |The default `ResourceLoader` in any standard `ApplicationContext` is in fact an instance
of `PathMatchingResourcePatternResolver` which implements the `ResourcePatternResolver`interface. The same is true for the `ApplicationContext` instance itself which also
implements the `ResourcePatternResolver` interface and delegates to the default`PathMatchingResourcePatternResolver`.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#resources-resourceloaderaware)2.6. The `ResourceLoaderAware` Interface ###
+
+The `ResourceLoaderAware` interface is a special callback interface which identifies
+components that expect to be provided a `ResourceLoader` reference. The following listing
+shows the definition of the `ResourceLoaderAware` interface:
+
+```
+public interface ResourceLoaderAware {
+
+ void setResourceLoader(ResourceLoader resourceLoader);
+}
+```
+
+When a class implements `ResourceLoaderAware` and is deployed into an application context
+(as a Spring-managed bean), it is recognized as `ResourceLoaderAware` by the application
+context. The application context then invokes `setResourceLoader(ResourceLoader)`,
+supplying itself as the argument (remember, all application contexts in Spring implement
+the `ResourceLoader` interface).
+
+Since an `ApplicationContext` is a `ResourceLoader`, the bean could also implement the`ApplicationContextAware` interface and use the supplied application context directly to
+load resources. However, in general, it is better to use the specialized `ResourceLoader`interface if that is all you need. The code would be coupled only to the resource loading
+interface (which can be considered a utility interface) and not to the whole Spring`ApplicationContext` interface.
+
+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 [Autowiring Collaborators](#beans-factory-autowire))
+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 [Using `@Autowired`](#beans-autowired-annotation).
+
+| |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[`ResourcePatternResolver`](#resources-resourcepatternresolver) autowired into your
application components instead of `ResourceLoader`.|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#resources-as-dependencies)2.7. Resources as Dependencies ###
+
+If the bean itself is going to determine and supply the resource path through some sort
+of dynamic process, it probably makes sense for the bean to use the `ResourceLoader` or`ResourcePatternResolver` interface to load resources. For example, consider the loading
+of a template of some sort, where the specific resource that is needed depends on the
+role of the user. If the resources are static, it makes sense to eliminate the use of the`ResourceLoader` interface (or `ResourcePatternResolver` interface) completely, have the
+bean expose the `Resource` properties it needs, and expect them to be injected into it.
+
+What makes it trivial to then inject these properties is that all application contexts
+register and use a special JavaBeans `PropertyEditor`, which can convert `String` paths
+to `Resource` objects. For example, the following `MyBean` class has a `template`property of type `Resource`.
+
+Java
+
+```
+package example;
+
+public class MyBean {
+
+ private Resource template;
+
+ public setTemplate(Resource template) {
+ this.template = template;
+ }
+
+ // ...
+}
+```
+
+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:
+
+```
+
simple test to check if `classpath*` works is to use the `ClassLoader` to load a file from
within a jar on the classpath:`getClass().getClassLoader().getResources("
files that have the same name but reside in two different locations — for example, files
with the same name and same path but in different jars on the classpath. In case an
inappropriate result is returned, check the application server documentation for settings
that might affect the `ClassLoader` behavior.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+You can also combine the `classpath*:` prefix with a `PathMatcher` pattern in the
+rest of the location path (for example, `classpath*:META-INF/*-beans.xml`). In this
+case, the resolution strategy is fairly simple: A `ClassLoader.getResources()` call is
+used on the last non-wildcard path segment to get all the matching resources in the
+class loader hierarchy and then, off each resource, the same `PathMatcher` resolution
+strategy described earlier is used for the wildcard subpath.
+
+##### [](#resources-wildcards-in-path-other-stuff)Other Notes Relating to Wildcards #####
+
+Note that `classpath*:`, when combined with Ant-style patterns, only works
+reliably with at least one root directory before the pattern starts, unless the actual
+target files reside in the file system. This means that a pattern such as`classpath*:*.xml` might not retrieve files from the root of jar files but rather only
+from the root of expanded directories.
+
+Spring’s ability to retrieve classpath entries originates from the JDK’s`ClassLoader.getResources()` method, which only returns file system locations for an
+empty string (indicating potential roots to search). Spring evaluates`URLClassLoader` runtime configuration and the `java.class.path` manifest in jar files
+as well, but this is not guaranteed to lead to portable behavior.
+
+| |The scanning of classpath packages requires the presence of corresponding directory
entries in the classpath. When you build JARs with Ant, do not activate the `files-only`switch of the JAR task. Also, classpath directories may not get exposed based on security
policies in some environments — for example, stand-alone applications on JDK 1.7.0\_45
and higher (which requires 'Trusted-Library' to be set up in your manifests. See[https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources](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.
Putting resources into a dedicated directory is highly recommendable here as well,
avoiding the aforementioned portability problems with searching the jar file root level.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+Ant-style patterns with `classpath:` resources are not guaranteed to find matching
+resources if the root package to search is available in multiple classpath locations.
+Consider the following example of a resource location:
+
+```
+com/mycompany/package1/service-context.xml
+```
+
+Now consider an Ant-style path that someone might use to try to find that file:
+
+```
+classpath:com/mycompany/**/service-context.xml
+```
+
+Such a resource may exist in only one location in the classpath, but when a path such as
+the preceding example is used to try to resolve it, the resolver works off the (first)
+URL returned by `getResource("com/mycompany");`. If this base package node exists in
+multiple `ClassLoader` locations, the desired resource may not exist in the first
+location found. Therefore, in such cases you should prefer using `classpath*:` with the
+same Ant-style pattern, which searches all classpath locations that contain the`com.mycompany` base package: `classpath*:com/mycompany/**/service-context.xml`.
+
+#### [](#resources-filesystemresource-caveats)2.8.3. `FileSystemResource` Caveats ####
+
+A `FileSystemResource` that is not attached to a `FileSystemApplicationContext` (that
+is, when a `FileSystemApplicationContext` is not the actual `ResourceLoader`) treats
+absolute and relative paths as you would expect. Relative paths are relative to the
+current working directory, while absolute paths are relative to the root of the
+filesystem.
+
+For backwards compatibility (historical) reasons however, this changes when the`FileSystemApplicationContext` is the `ResourceLoader`. The`FileSystemApplicationContext` forces all attached `FileSystemResource` instances
+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:
+
+Java
+
+```
+ApplicationContext ctx =
+ new FileSystemXmlApplicationContext("conf/context.xml");
+```
+
+Kotlin
+
+```
+val ctx = FileSystemXmlApplicationContext("conf/context.xml")
+```
+
+Java
+
+```
+ApplicationContext ctx =
+ new FileSystemXmlApplicationContext("/conf/context.xml");
+```
+
+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):
+
+Java
+
+```
+FileSystemXmlApplicationContext ctx = ...;
+ctx.getResource("some/resource/path/myTemplate.txt");
+```
+
+Kotlin
+
+```
+val ctx: FileSystemXmlApplicationContext = ...
+ctx.getResource("some/resource/path/myTemplate.txt")
+```
+
+Java
+
+```
+FileSystemXmlApplicationContext ctx = ...;
+ctx.getResource("/some/resource/path/myTemplate.txt");
+```
+
+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:
+
+Java
+
+```
+// actual context type doesn't matter, the Resource will always be UrlResource
+ctx.getResource("file:///some/resource/path/myTemplate.txt");
+```
+
+Kotlin
+
+```
+// actual context type doesn't matter, the Resource will always be UrlResource
+ctx.getResource("file:///some/resource/path/myTemplate.txt")
+```
+
+Java
+
+```
+// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
+ApplicationContext ctx =
+ new FileSystemXmlApplicationContext("file:///conf/context.xml");
+```
+
+Kotlin
+
+```
+// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
+val ctx = FileSystemXmlApplicationContext("file:///conf/context.xml")
+```
+
+[](#validation)3. 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 felt 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 3 introduced a `core.convert` package that 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 [Java Bean Validation](#validation-beanvalidation), 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 [Configuring a `DataBinder`](#validation-binder), which can
+be useful for plugging in custom validation logic.
+
+### [](#validator)3.1. Validation by Using Spring’s Validator Interface ###
+
+Spring features a `Validator` interface that you can use to validate objects. The`Validator` interface works by using an `Errors` object so that, while validating,
+validators can report validation failures to the `Errors` object.
+
+Consider the following example of a small data object:
+
+Java
+
+```
+public class Person {
+
+ private String name;
+ private int age;
+
+ // the usual getters and setters...
+}
+```
+
+Kotlin
+
+```
+class Person(val name: String, val age: Int)
+```
+
+The next example provides validation behavior for the `Person` class by implementing the
+following two methods of the `org.springframework.validation.Validator` interface:
+
+* `supports(Class)`: Can this `Validator` validate instances of the supplied `Class`?
+
+* `validate(Object, org.springframework.validation.Errors)`: Validates the given object
+ and, in case of validation errors, registers those with the given `Errors` object.
+
+Implementing a `Validator` is fairly straightforward, especially when you know of the`ValidationUtils` helper class that the Spring Framework also provides. The following
+example implements `Validator` for `Person` instances:
+
+Java
+
+```
+public class PersonValidator implements Validator {
+
+ /**
+ * This Validator validates only Person instances
+ */
+ public boolean supports(Class clazz) {
+ return Person.class.equals(clazz);
+ }
+
+ public void validate(Object obj, Errors e) {
+ ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
+ Person p = (Person) obj;
+ if (p.getAge() < 0) {
+ e.rejectValue("age", "negativevalue");
+ } else if (p.getAge() > 110) {
+ e.rejectValue("age", "too.darn.old");
+ }
+ }
+}
+```
+
+Kotlin
+
+```
+class PersonValidator : Validator {
+
+ /**
+ * This Validator validates only Person instances
+ */
+ override fun supports(clazz: Class<*>): Boolean {
+ return Person::class.java == clazz
+ }
+
+ override fun validate(obj: Any, e: Errors) {
+ ValidationUtils.rejectIfEmpty(e, "name", "name.empty")
+ val p = obj as Person
+ if (p.age < 0) {
+ e.rejectValue("age", "negativevalue")
+ } else if (p.age > 110) {
+ e.rejectValue("age", "too.darn.old")
+ }
+ }
+}
+```
+
+The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to
+reject the `name` property if it is `null` or the empty string. Have a look at the[`ValidationUtils`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/ValidationUtils.html) javadoc
+to see what functionality it provides besides the example shown previously.
+
+While it is certainly possible to implement a single `Validator` class to validate each
+of the nested objects in a rich object, it may be better to encapsulate the validation
+logic for each nested class of object in its own `Validator` implementation. A simple
+example of a “rich” object would be a `Customer` that is composed of two `String`properties (a first and a second name) and a complex `Address` object. `Address` objects
+may be used independently of `Customer` objects, so a distinct `AddressValidator`has been implemented. If you want your `CustomerValidator` to reuse the logic contained
+within the `AddressValidator` class without resorting to copy-and-paste, you can
+dependency-inject or instantiate an `AddressValidator` within your `CustomerValidator`,
+as the following example shows:
+
+Java
+
+```
+public class CustomerValidator implements Validator {
+
+ private final Validator addressValidator;
+
+ public CustomerValidator(Validator addressValidator) {
+ if (addressValidator == null) {
+ throw new IllegalArgumentException("The supplied [Validator] is " +
+ "required and must not be null.");
+ }
+ if (!addressValidator.supports(Address.class)) {
+ throw new IllegalArgumentException("The supplied [Validator] must " +
+ "support the validation of [Address] instances.");
+ }
+ this.addressValidator = addressValidator;
+ }
+
+ /**
+ * This Validator validates Customer instances, and any subclasses of Customer too
+ */
+ public boolean supports(Class clazz) {
+ return Customer.class.isAssignableFrom(clazz);
+ }
+
+ public void validate(Object target, Errors errors) {
+ ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required");
+ ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
+ Customer customer = (Customer) target;
+ try {
+ errors.pushNestedPath("address");
+ ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
+ } finally {
+ errors.popNestedPath();
+ }
+ }
+}
+```
+
+Kotlin
+
+```
+class CustomerValidator(private val addressValidator: Validator) : Validator {
+
+ init {
+ if (addressValidator == null) {
+ throw IllegalArgumentException("The supplied [Validator] is required and must not be null.")
+ }
+ if (!addressValidator.supports(Address::class.java)) {
+ throw IllegalArgumentException("The supplied [Validator] must support the validation of [Address] instances.")
+ }
+ }
+
+ /*
+ * This Validator validates Customer instances, and any subclasses of Customer too
+ */
+ override fun supports(clazz: Class<>): Boolean {
+ return Customer::class.java.isAssignableFrom(clazz)
+ }
+
+ override fun validate(target: Any, errors: Errors) {
+ ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required")
+ ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required")
+ val customer = target as Customer
+ try {
+ errors.pushNestedPath("address")
+ ValidationUtils.invokeValidator(this.addressValidator, customer.address, errors)
+ } finally {
+ errors.popNestedPath()
+ }
+ }
+}
+```
+
+Validation errors are reported to the `Errors` object passed to the validator. In the case
+of Spring Web MVC, you can use the `
(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[section on `PropertyEditors`](#beans-beans-conversion).)
+
+The following two example classes use the `BeanWrapper` to get and set
+properties:
+
+Java
+
+```
+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
+
+```
+class Company {
+ var name: String? = null
+ var managingDirector: Employee? = null
+}
+```
+
+Java
+
+```
+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
+
+```
+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:
+
+Java
+
+```
+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
+
+```
+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)3.3.2. 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 [the javadoc of the `java.beans` package from Oracle](https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html).
+
+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:
+
+| 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.
+
+```
+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[here](https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html)). The
+following example uses the `BeanInfo` mechanism to explicitly register one or more`PropertyEditor` instances with the properties of an associated class:
+
+```
+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:
+
+Java
+
+```
+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
+
+```
+class SomethingBeanInfo : SimpleBeanInfo() {
+
+ override fun getPropertyDescriptors(): Array {
+
+ 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:
+
+```
+package org.springframework.core.convert.support;
+
+final class StringToInteger implements Converter {
+
+ getConverter(Class
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:
+
+```
+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)3.4.4. The `ConversionService` API ####
+
+`ConversionService` defines a unified API for executing type conversion logic at
+runtime. Converters are often run behind the following facade interface:
+
+```
+package org.springframework.core.convert;
+
+public interface ConversionService {
+
+ boolean canConvert(Class> sourceType, Class> targetType);
+
+
system is used.|
+|---|------------------------------------------------------------------------------------------------------------|
+
+To register a default `ConversionService` with Spring, add the following bean definition
+with an `id` of `conversionService`:
+
+```
+