)
+```
+
+#### [](#beans-postconstruct-and-predestroy-annotations)1.9.9. Using `@PostConstruct` and `@PreDestroy` ####
+
+The `CommonAnnotationBeanPostProcessor` not only recognizes the `@Resource` annotation
+but also the JSR-250 lifecycle annotations: `javax.annotation.PostConstruct` and`javax.annotation.PreDestroy`. Introduced in Spring 2.5, the support for these
+annotations offers an alternative to the lifecycle callback mechanism described in[initialization callbacks](#beans-factory-lifecycle-initializingbean) and[destruction callbacks](#beans-factory-lifecycle-disposablebean). Provided that the`CommonAnnotationBeanPostProcessor` is registered within the Spring `ApplicationContext`,
+a method carrying one of these annotations is invoked at the same point in the lifecycle
+as the corresponding Spring lifecycle interface method or explicitly declared callback
+method. In the following example, the cache is pre-populated upon initialization and
+cleared upon destruction:
+
+Java
+
+```
+public class CachingMovieLister {
+
+ @PostConstruct
+ public void populateMovieCache() {
+ // populates the movie cache upon initialization...
+ }
+
+ @PreDestroy
+ public void clearMovieCache() {
+ // clears the movie cache upon destruction...
+ }
+}
+```
+
+Kotlin
+
+```
+class CachingMovieLister {
+
+ @PostConstruct
+ fun populateMovieCache() {
+ // populates the movie cache upon initialization...
+ }
+
+ @PreDestroy
+ fun clearMovieCache() {
+ // clears the movie cache upon destruction...
+ }
+}
+```
+
+For details about the effects of combining various lifecycle mechanisms, see[Combining Lifecycle Mechanisms](#beans-factory-lifecycle-combined-effects).
+
+| |Like `@Resource`, the `@PostConstruct` and `@PreDestroy` annotation types were a part
of the standard Java libraries from JDK 6 to 8. However, the entire `javax.annotation`package got separated from the core Java modules in JDK 9 and eventually removed in
JDK 11. If needed, the `javax.annotation-api` artifact needs to be obtained via Maven
Central now, simply to be added to the application’s classpath like any other library.|
+|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#beans-classpath-scanning)1.10. Classpath Scanning and Managed Components ###
+
+Most examples in this chapter use XML to specify the configuration metadata that produces
+each `BeanDefinition` within the Spring container. The previous section
+([Annotation-based Container Configuration](#beans-annotation-config)) demonstrates how to provide a lot of the configuration
+metadata through source-level annotations. Even in those examples, however, the “base”
+bean definitions are explicitly defined in the XML file, while the annotations drive only
+the dependency injection. This section describes an option for implicitly detecting the
+candidate components by scanning the classpath. Candidate components are classes that
+match against a filter criteria and have a corresponding bean definition registered with
+the container. This removes the need to use XML to perform bean registration. Instead, you
+can use annotations (for example, `@Component`), AspectJ type expressions, or your own
+custom filter criteria to select which classes have bean definitions registered with
+the container.
+
+| |Starting with Spring 3.0, many features provided by the Spring JavaConfig project are
part of the core Spring Framework. This allows you to define beans using Java rather
than using the traditional XML files. Take a look at the `@Configuration`, `@Bean`,`@Import`, and `@DependsOn` annotations for examples of how to use these new features.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-stereotype-annotations)1.10.1. `@Component` and Further Stereotype Annotations ####
+
+The `@Repository` annotation is a marker for any class that fulfills the role or
+stereotype of a repository (also known as Data Access Object or DAO). Among the uses
+of this marker is the automatic translation of exceptions, as described in[Exception Translation](data-access.html#orm-exception-translation).
+
+Spring provides further stereotype annotations: `@Component`, `@Service`, and`@Controller`. `@Component` is a generic stereotype for any Spring-managed component.`@Repository`, `@Service`, and `@Controller` are specializations of `@Component` for
+more specific use cases (in the persistence, service, and presentation
+layers, respectively). Therefore, you can annotate your component classes with`@Component`, but, by annotating them with `@Repository`, `@Service`, or `@Controller`instead, your classes are more properly suited for processing by tools or associating
+with aspects. For example, these stereotype annotations make ideal targets for
+pointcuts. `@Repository`, `@Service`, and `@Controller` can also
+carry additional semantics in future releases of the Spring Framework. Thus, if you are
+choosing between using `@Component` or `@Service` for your service layer, `@Service` is
+clearly the better choice. Similarly, as stated earlier, `@Repository` is already
+supported as a marker for automatic exception translation in your persistence layer.
+
+#### [](#beans-meta-annotations)1.10.2. Using Meta-annotations and Composed Annotations ####
+
+Many of the annotations provided by Spring can be used as meta-annotations in your
+own code. A meta-annotation is an annotation that can be applied to another annotation.
+For example, the `@Service` annotation mentioned [earlier](#beans-stereotype-annotations)is meta-annotated with `@Component`, as the following example shows:
+
+Java
+
+```
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Component (1)
+public @interface Service {
+
+ // ...
+}
+```
+
+|**1**|The `@Component` causes `@Service` to be treated in the same way as `@Component`.|
+|-----|---------------------------------------------------------------------------------|
+
+Kotlin
+
+```
+@Target(AnnotationTarget.TYPE)
+@Retention(AnnotationRetention.RUNTIME)
+@MustBeDocumented
+@Component (1)
+annotation class Service {
+
+ // ...
+}
+```
+
+|**1**|The `@Component` causes `@Service` to be treated in the same way as `@Component`.|
+|-----|---------------------------------------------------------------------------------|
+
+You can also combine meta-annotations to create “composed annotations”. For example,
+the `@RestController` annotation from Spring MVC is composed of `@Controller` and`@ResponseBody`.
+
+In addition, composed annotations can optionally redeclare attributes from
+meta-annotations to allow customization. This can be particularly useful when you
+want to only expose a subset of the meta-annotation’s attributes. For example, Spring’s`@SessionScope` annotation hardcodes the scope name to `session` but still allows
+customization of the `proxyMode`. The following listing shows the definition of the`SessionScope` annotation:
+
+Java
+
+```
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Scope(WebApplicationContext.SCOPE_SESSION)
+public @interface SessionScope {
+
+ /**
+ * Alias for {@link Scope#proxyMode}.
+ * Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
+ */
+ @AliasFor(annotation = Scope.class)
+ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
+
+}
+```
+
+Kotlin
+
+```
+@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:
+
+```
+
+
+
+
+
+
+```
+
+| |The use of `` implicitly enables the functionality of``. There is usually no need to include the`` element when using ``.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+| |The scanning of classpath packages requires the presence of corresponding directory
entries in the classpath. When you build JARs with Ant, make sure that you do not
activate the files-only switch of the JAR task. Also, classpath directories may not be
exposed based on security policies in some environments — for example, standalone apps on
JDK 1.7.0\_45 and higher (which requires 'Trusted-Library' setup in your manifests — see[https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources](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 `` or`` child elements of the `` element in
+XML configuration). Each filter element requires the `type` and `expression` attributes.
+The following table describes the filtering options:
+
+| Filter Type | Example Expression | Description |
+|--------------------|----------------------------|------------------------------------------------------------------------------------------|
+|annotation (default)|`org.example.SomeAnnotation`| An annotation to be *present* or *meta-present* at the type level in target components. |
+| assignable | `org.example.SomeClass` |A class (or interface) that the target components are assignable to (extend or implement).|
+| aspectj | `org.example..*Service+` | An AspectJ type expression to be matched by the target components. |
+| regex | `org\.example\.Default.*` | A regex expression to be matched by the target components' class names. |
+| custom | `org.example.MyTypeFilter` | A custom implementation of the `org.springframework.core.type.TypeFilter` interface. |
+
+The following example shows the configuration ignoring all `@Repository` annotations
+and using “stub” repositories instead:
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example",
+ includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
+ excludeFilters = @Filter(Repository.class))
+public class AppConfig {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example",
+ includeFilters = [Filter(type = FilterType.REGEX, pattern = [".*Stub.*Repository"])],
+ excludeFilters = [Filter(Repository::class)])
+class AppConfig {
+ // ...
+}
+```
+
+The following listing shows the equivalent XML:
+
+```
+
+
+
+
+
+
+```
+
+| |You can also disable the default filters by setting `useDefaultFilters=false` on the
annotation or by providing `use-default-filters="false"` as an attribute of the`` element. This effectively disables automatic detection of classes
annotated or meta-annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,`@RestController`, or `@Configuration`.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-factorybeans-annotations)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` instead.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+Autowired fields and methods are supported, as previously discussed, with additional
+support for autowiring of `@Bean` methods. The following example shows how to do so:
+
+Java
+
+```
+@Component
+public class FactoryMethodComponent {
+
+ private static int i;
+
+ @Bean
+ @Qualifier("public")
+ public TestBean publicInstance() {
+ return new TestBean("publicInstance");
+ }
+
+ // use of a custom qualifier and autowiring of method parameters
+ @Bean
+ protected TestBean protectedInstance(
+ @Qualifier("public") TestBean spouse,
+ @Value("#{privateInstance.age}") String country) {
+ TestBean tb = new TestBean("protectedInstance", 1);
+ tb.setSpouse(spouse);
+ tb.setCountry(country);
+ return tb;
+ }
+
+ @Bean
+ private TestBean privateInstance() {
+ return new TestBean("privateInstance", i++);
+ }
+
+ @Bean
+ @RequestScope
+ public TestBean requestScopedInstance() {
+ return new TestBean("requestScopedInstance", 3);
+ }
+}
+```
+
+Kotlin
+
+```
+@Component
+class FactoryMethodComponent {
+
+ companion object {
+ private var i: Int = 0
+ }
+
+ @Bean
+ @Qualifier("public")
+ fun publicInstance() = TestBean("publicInstance")
+
+ // use of a custom qualifier and autowiring of method parameters
+ @Bean
+ protected fun protectedInstance(
+ @Qualifier("public") spouse: TestBean,
+ @Value("#{privateInstance.age}") country: String) = TestBean("protectedInstance", 1).apply {
+ this.spouse = spouse
+ this.country = country
+ }
+
+ @Bean
+ private fun privateInstance() = TestBean("privateInstance", i++)
+
+ @Bean
+ @RequestScope
+ fun requestScopedInstance() = TestBean("requestScopedInstance", 3)
+}
+```
+
+The example autowires the `String` method parameter `country` to the value of the `age`property on another bean named `privateInstance`. A Spring Expression Language element
+defines the value of the property through the notation `#{ }`. For `@Value`annotations, an expression resolver is preconfigured to look for bean names when
+resolving expression text.
+
+As of Spring Framework 4.3, you may also declare a factory method parameter of type`InjectionPoint` (or its more specific subclass: `DependencyDescriptor`) to
+access the requesting injection point that triggers the creation of the current bean.
+Note that this applies only to the actual creation of bean instances, not to the
+injection of existing instances. As a consequence, this feature makes most sense for
+beans of prototype scope. For other scopes, the factory method only ever sees the
+injection point that triggered the creation of a new bean instance in the given scope
+(for example, the dependency that triggered the creation of a lazy singleton bean).
+You can use the provided injection point metadata with semantic care in such scenarios.
+The following example shows how to use `InjectionPoint`:
+
+Java
+
+```
+@Component
+public class FactoryMethodComponent {
+
+ @Bean @Scope("prototype")
+ public TestBean prototypeInstance(InjectionPoint injectionPoint) {
+ return new TestBean("prototypeInstance for " + injectionPoint.getMember());
+ }
+}
+```
+
+Kotlin
+
+```
+@Component
+class FactoryMethodComponent {
+
+ @Bean
+ @Scope("prototype")
+ fun prototypeInstance(injectionPoint: InjectionPoint) =
+ TestBean("prototypeInstance for ${injectionPoint.member}")
+}
+```
+
+The `@Bean` methods in a regular Spring component are processed differently than their
+counterparts inside a Spring `@Configuration` class. The difference is that `@Component`classes are not enhanced with CGLIB to intercept the invocation of methods and fields.
+CGLIB proxying is the means by which invoking methods or fields within `@Bean` methods
+in `@Configuration` classes creates bean metadata references to collaborating objects.
+Such methods are not invoked with normal Java semantics but rather go through the
+container in order to provide the usual lifecycle management and proxying of Spring
+beans, even when referring to other beans through programmatic calls to `@Bean` methods.
+In contrast, invoking a method or field in a `@Bean` method within a plain `@Component`class has standard Java semantics, with no special CGLIB processing or other
+constraints applying.
+
+| |You may declare `@Bean` methods as `static`, allowing for them to be called without
creating their containing configuration class as an instance. This makes particular
sense when defining post-processor beans (for example, of type `BeanFactoryPostProcessor`or `BeanPostProcessor`), since such beans get initialized early in the container
lifecycle and should avoid triggering other parts of the configuration at that point.
Calls to static `@Bean` methods never get intercepted by the container, not even within`@Configuration` classes (as described earlier in this section), due to technical
limitations: CGLIB subclassing can override only non-static methods. As a consequence,
a direct call to another `@Bean` method has standard Java semantics, resulting
in an independent instance being returned straight from the factory method itself.
The Java language visibility of `@Bean` methods does not have an immediate impact on
the resulting bean definition in Spring’s container. You can freely declare your
factory methods as you see fit in non-`@Configuration` classes and also for static
methods anywhere. However, regular `@Bean` methods in `@Configuration` classes need
to be overridable — that is, they must not be declared as `private` or `final`.
`@Bean` methods are also discovered on base classes of a given component or
configuration class, as well as on Java 8 default methods declared in interfaces
implemented by the component or configuration class. This allows for a lot of
flexibility in composing complex configuration arrangements, with even multiple
inheritance being possible through Java 8 default methods as of Spring 4.2.
Finally, a single class may hold multiple `@Bean` methods for the same
bean, as an arrangement of multiple factory methods to use depending on available
dependencies at runtime. This is the same algorithm as for choosing the “greediest”
constructor or factory method in other configuration scenarios: The variant with
the largest number of satisfiable dependencies is picked at construction time,
analogous to how the container selects between multiple `@Autowired` constructors.|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-scanning-name-generator)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 {
+ // ...
+}
+```
+
+```
+
+
+
+```
+
+As a general rule, consider specifying the name with the annotation whenever other
+components may be making explicit references to it. On the other hand, the
+auto-generated names are adequate whenever the container is responsible for wiring.
+
+#### [](#beans-scanning-scope-resolver)1.10.7. Providing a Scope for Autodetected Components ####
+
+As with Spring-managed components in general, the default and most common scope for
+autodetected components is `singleton`. However, sometimes you need a different scope
+that can be specified by the `@Scope` annotation. You can provide the name of the
+scope within the annotation, as the following example shows:
+
+Java
+
+```
+@Scope("prototype")
+@Repository
+public class MovieFinderImpl implements MovieFinder {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Scope("prototype")
+@Repository
+class MovieFinderImpl : MovieFinder {
+ // ...
+}
+```
+
+| |`@Scope` annotations are only introspected on the concrete bean class (for annotated
components) or the factory method (for `@Bean` methods). In contrast to XML bean
definitions, there is no notion of bean definition inheritance, and inheritance
hierarchies at the class level are irrelevant for metadata purposes.|
+|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+For details on web-specific scopes such as “request” or “session” in a Spring context,
+see [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 {
+ // ...
+}
+```
+
+```
+
+
+
+```
+
+When using certain non-singleton scopes, it may be necessary to generate proxies for the
+scoped objects. The reasoning is described in [Scoped Beans as Dependencies](#beans-factory-scopes-other-injection).
+For this purpose, a scoped-proxy attribute is available on the component-scan
+element. The three possible values are: `no`, `interfaces`, and `targetClass`. For example,
+the following configuration results in standard JDK dynamic proxies:
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
+public class AppConfig {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = ["org.example"], scopedProxy = ScopedProxyMode.INTERFACES)
+class AppConfig {
+ // ...
+}
+```
+
+```
+
+
+
+```
+
+#### [](#beans-scanning-qualifiers)1.10.8. Providing Qualifier Metadata with Annotations ####
+
+The `@Qualifier` annotation is discussed in [Fine-tuning Annotation-based Autowiring with Qualifiers](#beans-autowired-annotation-qualifiers).
+The examples in that section demonstrate the use of the `@Qualifier` annotation and
+custom qualifier annotations to provide fine-grained control when you resolve autowire
+candidates. Because those examples were based on XML bean definitions, the qualifier
+metadata was provided on the candidate bean definitions by using the `qualifier` or `meta`child elements of the `bean` element in the XML. When relying upon classpath scanning for
+auto-detection of components, you can provide the qualifier metadata with type-level
+annotations on the candidate class. The following three examples demonstrate this
+technique:
+
+Java
+
+```
+@Component
+@Qualifier("Action")
+public class ActionMovieCatalog implements MovieCatalog {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Component
+@Qualifier("Action")
+class ActionMovieCatalog : MovieCatalog
+```
+
+Java
+
+```
+@Component
+@Genre("Action")
+public class ActionMovieCatalog implements MovieCatalog {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Component
+@Genre("Action")
+class ActionMovieCatalog : MovieCatalog {
+ // ...
+}
+```
+
+Java
+
+```
+@Component
+@Offline
+public class CachingMovieCatalog implements MovieCatalog {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Component
+@Offline
+class CachingMovieCatalog : MovieCatalog {
+ // ...
+}
+```
+
+| |As with most annotation-based alternatives, keep in mind that the annotation metadata is
bound to the class definition itself, while the use of XML allows for multiple beans
of the same type to provide variations in their qualifier metadata, because that
metadata is provided per-instance rather than per-class.|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-scanning-index)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 `` directives must remain
unchanged to request the context to scan candidates in certain packages. When the`ApplicationContext` detects such an index, it automatically uses it rather than scanning
the classpath.|
+|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+To generate the index, add an additional dependency to each module that contains
+components that are targets for component scan directives. The following example shows
+how to do so with Maven:
+
+```
+
+
+ org.springframework
+ spring-context-indexer
+ 5.3.16
+ true
+
+
+```
+
+With Gradle 4.5 and earlier, the dependency should be declared in the `compileOnly`configuration, as shown in the following example:
+
+```
+dependencies {
+ compileOnly "org.springframework:spring-context-indexer:5.3.16"
+}
+```
+
+With Gradle 4.6 and later, the dependency should be declared in the `annotationProcessor`configuration, as shown in the following example:
+
+```
+dependencies {
+ annotationProcessor "org.springframework:spring-context-indexer:5.3.16"
+}
+```
+
+The `spring-context-indexer` artifact generates a `META-INF/spring.components` file that
+is included in the jar file.
+
+| |When working with this mode in your IDE, the `spring-context-indexer` must be
registered as an annotation processor to make sure the index is up-to-date when
candidate components are updated.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+| |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:
```
javax.inject
javax.inject
1
```|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#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 movieFinder;
+
+ @Inject
+ public void setMovieFinder(Provider movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ public void listMovies() {
+ this.movieFinder.get().findMovies(...);
+ // ...
+ }
+}
+```
+
+Kotlin
+
+```
+import javax.inject.Inject
+
+class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: MovieFinder
+
+ fun listMovies() {
+ movieFinder.findMovies(...)
+ // ...
+ }
+}
+```
+
+If you would like to use a qualified name for the dependency that should be injected,
+you should use the `@Named` annotation, as the following example shows:
+
+Java
+
+```
+import javax.inject.Inject;
+import javax.inject.Named;
+
+public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // ...
+}
+```
+
+Kotlin
+
+```
+import javax.inject.Inject
+import javax.inject.Named
+
+class SimpleMovieLister {
+
+ private lateinit var movieFinder: MovieFinder
+
+ @Inject
+ fun setMovieFinder(@Named("main") movieFinder: MovieFinder) {
+ this.movieFinder = movieFinder
+ }
+
+ // ...
+}
+```
+
+As with `@Autowired`, `@Inject` can also be used with `java.util.Optional` or`@Nullable`. This is even more applicable here, since `@Inject` does not have
+a `required` attribute. The following pair of examples show how to use `@Inject` and`@Nullable`:
+
+```
+public class SimpleMovieLister {
+
+ @Inject
+ public void setMovieFinder(Optional movieFinder) {
+ // ...
+ }
+}
+```
+
+Java
+
+```
+public class SimpleMovieLister {
+
+ @Inject
+ public void setMovieFinder(@Nullable MovieFinder movieFinder) {
+ // ...
+ }
+}
+```
+
+Kotlin
+
+```
+class SimpleMovieLister {
+
+ @Inject
+ var movieFinder: MovieFinder? = null
+}
+```
+
+#### [](#beans-named)1.11.2. `@Named` and `@ManagedBean`: Standard Equivalents to the `@Component` Annotation ####
+
+Instead of `@Component`, you can use `@javax.inject.Named` or `javax.annotation.ManagedBean`,
+as the following example shows:
+
+Java
+
+```
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Named("movieListener") // @ManagedBean("movieListener") could be used as well
+public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // ...
+}
+```
+
+Kotlin
+
+```
+import javax.inject.Inject
+import javax.inject.Named
+
+@Named("movieListener") // @ManagedBean("movieListener") could be used as well
+class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: MovieFinder
+
+ // ...
+}
+```
+
+It is very common to use `@Component` without specifying a name for the component.`@Named` can be used in a similar fashion, as the following example shows:
+
+Java
+
+```
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Named
+public class SimpleMovieLister {
+
+ private MovieFinder movieFinder;
+
+ @Inject
+ public void setMovieFinder(MovieFinder movieFinder) {
+ this.movieFinder = movieFinder;
+ }
+
+ // ...
+}
+```
+
+Kotlin
+
+```
+import javax.inject.Inject
+import javax.inject.Named
+
+@Named
+class SimpleMovieLister {
+
+ @Inject
+ lateinit var movieFinder: MovieFinder
+
+ // ...
+}
+```
+
+When you use `@Named` or `@ManagedBean`, you can use component scanning in the
+exact same way as when you use Spring annotations, as the following example shows:
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "org.example")
+public class AppConfig {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = ["org.example"])
+class AppConfig {
+ // ...
+}
+```
+
+| |In contrast to `@Component`, the JSR-330 `@Named` and the JSR-250 `@ManagedBean`annotations are not composable. You should use Spring’s stereotype model for building
custom component annotations.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+#### [](#beans-standard-annotations-limitations)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 `` XML configuration, the `@Bean` annotation plays the same role as
+the `` element. You can use `@Bean`-annotated methods with any Spring`@Component`. However, they are most often used with `@Configuration` beans.
+
+Annotating a class with `@Configuration` indicates that its primary purpose is as a
+source of bean definitions. Furthermore, `@Configuration` classes let inter-bean
+dependencies be defined by calling other `@Bean` methods in the same class.
+The simplest possible `@Configuration` class reads as follows:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public MyService myService() {
+ return new MyServiceImpl();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean
+ fun myService(): MyService {
+ return MyServiceImpl()
+ }
+}
+```
+
+The preceding `AppConfig` class is equivalent to the following Spring `` XML:
+
+```
+
+
+
+```
+
+Full @Configuration vs “lite” @Bean mode?
+
+When `@Bean` methods are declared within classes that are not annotated with`@Configuration`, they are referred to as being processed in a “lite” mode. Bean methods
+declared in a `@Component` or even in a plain old class are considered to be “lite”,
+with a different primary purpose of the containing class and a `@Bean` method
+being a sort of bonus there. For example, service components may expose management views
+to the container through an additional `@Bean` method on each applicable component class.
+In such scenarios, `@Bean` methods are a general-purpose factory method mechanism.
+
+Unlike full `@Configuration`, lite `@Bean` methods cannot declare inter-bean dependencies.
+Instead, they operate on their containing component’s internal state and, optionally, on
+arguments that they may declare. Such a `@Bean` method should therefore not invoke other`@Bean` methods. Each such method is literally only a factory method for a particular
+bean reference, without any special runtime semantics. The positive side-effect here is
+that no CGLIB subclassing has to be applied at runtime, so there are no limitations in
+terms of class design (that is, the containing class may be `final` and so forth).
+
+In common scenarios, `@Bean` methods are to be declared within `@Configuration` classes,
+ensuring that “full” mode is always used and that cross-method references therefore
+get redirected to the container’s lifecycle management. This prevents the same`@Bean` method from accidentally being invoked through a regular Java call, which helps
+to reduce subtle bugs that can be hard to track down when operating in “lite” mode.
+
+The `@Bean` and `@Configuration` annotations are discussed in depth in the following sections.
+First, however, we cover the various ways of creating a spring container by using
+Java-based configuration.
+
+#### [](#beans-java-instantiating-container)1.12.2. Instantiating the Spring Container by Using `AnnotationConfigApplicationContext` ####
+
+The following sections document Spring’s `AnnotationConfigApplicationContext`, introduced in Spring
+3.0. This versatile `ApplicationContext` implementation is capable of accepting not only`@Configuration` classes as input but also plain `@Component` classes and classes
+annotated with JSR-330 metadata.
+
+When `@Configuration` classes are provided as input, the `@Configuration` class itself
+is registered as a bean definition and all declared `@Bean` methods within the class
+are also registered as bean definitions.
+
+When `@Component` and JSR-330 classes are provided, they are registered as bean
+definitions, and it is assumed that DI metadata such as `@Autowired` or `@Inject` are
+used within those classes where necessary.
+
+##### [](#beans-java-instantiating-container-constructor)Simple Construction #####
+
+In much the same way that Spring XML files are used as input when instantiating a`ClassPathXmlApplicationContext`, you can use `@Configuration` classes as input when
+instantiating an `AnnotationConfigApplicationContext`. This allows for completely
+XML-free usage of the Spring container, as the following example shows:
+
+Java
+
+```
+public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+ MyService myService = ctx.getBean(MyService.class);
+ myService.doStuff();
+}
+```
+
+Kotlin
+
+```
+import org.springframework.beans.factory.getBean
+
+fun main() {
+ val ctx = AnnotationConfigApplicationContext(AppConfig::class.java)
+ val myService = ctx.getBean()
+ myService.doStuff()
+}
+```
+
+As mentioned earlier, `AnnotationConfigApplicationContext` is not limited to working only
+with `@Configuration` classes. Any `@Component` or JSR-330 annotated class may be supplied
+as input to the constructor, as the following example shows:
+
+Java
+
+```
+public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
+ MyService myService = ctx.getBean(MyService.class);
+ myService.doStuff();
+}
+```
+
+Kotlin
+
+```
+import org.springframework.beans.factory.getBean
+
+fun main() {
+ val ctx = AnnotationConfigApplicationContext(MyServiceImpl::class.java, Dependency1::class.java, Dependency2::class.java)
+ val myService = ctx.getBean()
+ myService.doStuff()
+}
+```
+
+The preceding example assumes that `MyServiceImpl`, `Dependency1`, and `Dependency2` use Spring
+dependency injection annotations such as `@Autowired`.
+
+##### [](#beans-java-instantiating-container-register)Building the Container Programmatically by Using `register(Class>…)` #####
+
+You can instantiate an `AnnotationConfigApplicationContext` by using a no-arg constructor
+and then configure it by using the `register()` method. This approach is particularly useful
+when programmatically building an `AnnotationConfigApplicationContext`. The following
+example shows how to do so:
+
+Java
+
+```
+public static void main(String[] args) {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(AppConfig.class, OtherConfig.class);
+ ctx.register(AdditionalConfig.class);
+ ctx.refresh();
+ MyService myService = ctx.getBean(MyService.class);
+ myService.doStuff();
+}
+```
+
+Kotlin
+
+```
+import org.springframework.beans.factory.getBean
+
+fun main() {
+ val ctx = AnnotationConfigApplicationContext()
+ ctx.register(AppConfig::class.java, OtherConfig::class.java)
+ ctx.register(AdditionalConfig::class.java)
+ ctx.refresh()
+ val myService = ctx.getBean()
+ myService.doStuff()
+}
+```
+
+##### [](#beans-java-instantiating-container-scan)Enabling Component Scanning with `scan(String…)` #####
+
+To enable component scanning, you can annotate your `@Configuration` class as follows:
+
+Java
+
+```
+@Configuration
+@ComponentScan(basePackages = "com.acme") (1)
+public class AppConfig {
+ // ...
+}
+```
+
+|**1**|This annotation enables component scanning.|
+|-----|-------------------------------------------|
+
+Kotlin
+
+```
+@Configuration
+@ComponentScan(basePackages = ["com.acme"]) (1)
+class AppConfig {
+ // ...
+}
+```
+
+|**1**|This annotation enables component scanning.|
+|-----|-------------------------------------------|
+
+| |Experienced Spring users may be familiar with the XML declaration equivalent from
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()
+}
+```
+
+| |Remember that `@Configuration` classes are [meta-annotated](#beans-meta-annotations)with `@Component`, so they are candidates for component-scanning. In the preceding example,
assuming that `AppConfig` is declared within the `com.acme` package (or any package
underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean`methods are processed and registered as bean definitions within the container.|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+##### [](#beans-java-instantiating-container-web)Support for Web Applications with `AnnotationConfigWebApplicationContext` #####
+
+A `WebApplicationContext` variant of `AnnotationConfigApplicationContext` is available
+with `AnnotationConfigWebApplicationContext`. You can use this implementation when
+configuring the Spring `ContextLoaderListener` servlet listener, Spring MVC`DispatcherServlet`, and so forth. The following `web.xml` snippet configures a typical
+Spring MVC web application (note the use of the `contextClass` context-param and
+init-param):
+
+```
+
+
+
+ contextClass
+
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+
+
+
+
+
+ contextConfigLocation
+ com.acme.AppConfig
+
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ dispatcher
+ org.springframework.web.servlet.DispatcherServlet
+
+
+ contextClass
+
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+
+
+
+
+ contextConfigLocation
+ com.acme.web.MvcConfig
+
+
+
+
+
+ dispatcher
+ /app/*
+
+
+```
+
+| |For programmatic use cases, a `GenericWebApplicationContext` can be used as an
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 `` element.
+The annotation supports some of the attributes offered by ``, such as:
+
+* [init-method](#beans-factory-lifecycle-initializingbean)
+
+* [destroy-method](#beans-factory-lifecycle-disposablebean)
+
+* [autowiring](#beans-factory-autowire)
+
+* `name`.
+
+You can use the `@Bean` annotation in a `@Configuration`-annotated or in a`@Component`-annotated class.
+
+##### [](#beans-java-declaring-a-bean)Declaring a Bean #####
+
+To declare a bean, you can annotate a method with the `@Bean` annotation. You use this
+method to register a bean definition within an `ApplicationContext` of the type
+specified as the method’s return value. By default, the bean name is the same as
+the method name. The following example shows a `@Bean` method declaration:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public TransferServiceImpl transferService() {
+ return new TransferServiceImpl();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean
+ fun transferService() = TransferServiceImpl()
+}
+```
+
+The preceding configuration is exactly equivalent to the following Spring XML:
+
+```
+
+
+
+```
+
+Both declarations make a bean named `transferService` available in the`ApplicationContext`, bound to an object instance of type `TransferServiceImpl`, as the
+following text image shows:
+
+```
+transferService -> com.acme.TransferServiceImpl
+```
+
+You can also use default methods to define beans. This allows composition of bean
+configurations by implementing interfaces with bean definitions on default methods.
+
+Java
+
+```
+public interface BaseConfig {
+
+ @Bean
+ default TransferServiceImpl transferService() {
+ return new TransferServiceImpl();
+ }
+}
+
+@Configuration
+public class AppConfig implements BaseConfig {
+
+}
+```
+
+You can also declare your `@Bean` method with an interface (or base class)
+return type, as the following example shows:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public TransferService transferService() {
+ return new TransferServiceImpl();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean
+ fun transferService(): TransferService {
+ return TransferServiceImpl()
+ }
+}
+```
+
+However, this limits the visibility for advance type prediction to the specified
+interface type (`TransferService`). Then, with the full type (`TransferServiceImpl`)
+known to the container only once the affected singleton bean has been instantiated.
+Non-lazy singleton beans get instantiated according to their declaration order,
+so you may see different type matching results depending on when another component
+tries to match by a non-declared type (such as `@Autowired TransferServiceImpl`,
+which resolves only once the `transferService` bean has been instantiated).
+
+| |If you consistently refer to your types by a declared service interface, your`@Bean` return types may safely join that design decision. However, for components
that implement several interfaces or for components potentially referred to by their
implementation type, it is safer to declare the most specific return type possible
(at least as specific as required by the injection points that refer to your bean).|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+##### [](#beans-java-dependencies)Bean Dependencies #####
+
+A `@Bean`-annotated method can have an arbitrary number of parameters that describe the
+dependencies required to build that bean. For instance, if our `TransferService`requires an `AccountRepository`, we can materialize that dependency with a method
+parameter, as the following example shows:
+
+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 `` element.
+Configuring your beans in Java with a `@Scope` annotation offers equivalent support
+with the `proxyMode` attribute. The default is `ScopedProxyMode.DEFAULT`, which
+typically indicates that no scoped proxy should be created unless a different default
+has been configured at the component-scan instruction level. You can specify`ScopedProxyMode.TARGET_CLASS`, `ScopedProxyMode.INTERFACES` or `ScopedProxyMode.NO`.
+
+If you port the scoped proxy example from the XML reference documentation (see[scoped proxies](#beans-factory-scopes-other-injection)) to our `@Bean` using Java,
+it resembles the following:
+
+Java
+
+```
+// an HTTP Session-scoped bean exposed as a proxy
+@Bean
+@SessionScope
+public UserPreferences userPreferences() {
+ return new UserPreferences();
+}
+
+@Bean
+public Service userService() {
+ UserService service = new SimpleUserService();
+ // a reference to the proxied userPreferences bean
+ service.setUserPreferences(userPreferences());
+ return service;
+}
+```
+
+Kotlin
+
+```
+// an HTTP Session-scoped bean exposed as a proxy
+@Bean
+@SessionScope
+fun userPreferences() = UserPreferences()
+
+@Bean
+fun userService(): Service {
+ return SimpleUserService().apply {
+ // a reference to the proxied userPreferences bean
+ setUserPreferences(userPreferences())
+ }
+}
+```
+
+##### [](#beans-java-customizing-bean-naming)Customizing Bean Naming #####
+
+By default, configuration classes use a `@Bean` method’s name as the name of the
+resulting bean. This functionality can be overridden, however, with the `name` attribute,
+as the following example shows:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean("myThing")
+ public Thing thing() {
+ return new Thing();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean("myThing")
+ fun thing() = Thing()
+}
+```
+
+##### [](#beans-java-bean-aliasing)Bean Aliasing #####
+
+As discussed in [Naming Beans](#beans-beanname), it is sometimes desirable to give a single bean
+multiple names, otherwise known as bean aliasing. The `name` attribute of the `@Bean`annotation accepts a String array for this purpose. The following example shows how to set
+a number of aliases for a bean:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
+ public DataSource dataSource() {
+ // instantiate, configure and return DataSource bean...
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean("dataSource", "subsystemA-dataSource", "subsystemB-dataSource")
+ fun dataSource(): DataSource {
+ // instantiate, configure and return DataSource bean...
+ }
+}
+```
+
+##### [](#beans-java-bean-description)Bean Description #####
+
+Sometimes, it is helpful to provide a more detailed textual description of a bean. This can
+be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.
+
+To add a description to a `@Bean`, you can use the[`@Description`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Description.html)annotation, as the following example shows:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ @Description("Provides a basic example of a bean")
+ public Thing thing() {
+ return new Thing();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean
+ @Description("Provides a basic example of a bean")
+ fun thing() = Thing()
+}
+```
+
+#### [](#beans-java-configuration-annotation)1.12.4. Using the `@Configuration` annotation ####
+
+`@Configuration` is a class-level annotation indicating that an object is a source of
+bean definitions. `@Configuration` classes declare beans through `@Bean`-annotated
+methods. Calls to `@Bean` methods on `@Configuration` classes can also be used to define
+inter-bean dependencies. See [Basic Concepts: `@Bean` and `@Configuration`](#beans-java-basic-concepts) for a general introduction.
+
+##### [](#beans-java-injecting-dependencies)Injecting Inter-bean Dependencies #####
+
+When beans have dependencies on one another, expressing that dependency is as simple
+as having one bean method call another, as the following example shows:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public BeanOne beanOne() {
+ return new BeanOne(beanTwo());
+ }
+
+ @Bean
+ public BeanTwo beanTwo() {
+ return new BeanTwo();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Bean
+ fun beanOne() = BeanOne(beanTwo())
+
+ @Bean
+ fun beanTwo() = BeanTwo()
+}
+```
+
+In the preceding example, `beanOne` receives a reference to `beanTwo` through constructor
+injection.
+
+| |This method of declaring inter-bean dependencies works only when the `@Bean` method
is declared within a `@Configuration` class. You cannot declare inter-bean dependencies
by using plain `@Component` classes.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+##### [](#beans-java-method-injection)Lookup Method Injection #####
+
+As noted earlier, [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 `` element is used within Spring XML files to aid in modularizing
+configurations, the `@Import` annotation allows for loading `@Bean` definitions from
+another configuration class, as the following example shows:
+
+Java
+
+```
+@Configuration
+public class ConfigA {
+
+ @Bean
+ public A a() {
+ return new A();
+ }
+}
+
+@Configuration
+@Import(ConfigA.class)
+public class ConfigB {
+
+ @Bean
+ public B b() {
+ return new B();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class ConfigA {
+
+ @Bean
+ fun a() = A()
+}
+
+@Configuration
+@Import(ConfigA::class)
+class ConfigB {
+
+ @Bean
+ fun b() = B()
+}
+```
+
+Now, rather than needing to specify both `ConfigA.class` and `ConfigB.class` when
+instantiating the context, only `ConfigB` needs to be supplied explicitly, as the
+following example shows:
+
+Java
+
+```
+public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
+
+ // now both beans A and B will be available...
+ A a = ctx.getBean(A.class);
+ B b = ctx.getBean(B.class);
+}
+```
+
+Kotlin
+
+```
+import org.springframework.beans.factory.getBean
+
+fun main() {
+ val ctx = AnnotationConfigApplicationContext(ConfigB::class.java)
+
+ // now both beans A and B will be available...
+ val a = ctx.getBean()
+ val b = ctx.getBean()
+}
+```
+
+This approach simplifies container instantiation, as only one class needs to be dealt
+with, rather than requiring you to remember a potentially large number of`@Configuration` classes during construction.
+
+| |As of Spring Framework 4.2, `@Import` also supports references to regular component
classes, analogous to the `AnnotationConfigApplicationContext.register` method.
This is particularly useful if you want to avoid component scanning, by using a few
configuration classes as entry points to explicitly define all your components.|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+###### [](#beans-java-injecting-imported-beans)Injecting Dependencies on Imported `@Bean` Definitions ######
+
+The preceding example works but is simplistic. In most practical scenarios, beans have
+dependencies on one another across configuration classes. When using XML, this is not an
+issue, because no compiler is involved, and you can declare`ref="someBean"` and trust Spring to work it out during container initialization.
+When using `@Configuration` classes, the Java compiler places constraints on
+the configuration model, in that references to other beans must be valid Java syntax.
+
+Fortunately, solving this problem is simple. As [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()
+ transferService.transfer(100.00, "A123", "C456")
+}
+```
+
+There is another way to achieve the same result. Remember that `@Configuration` classes are
+ultimately only another bean in the container: This means that they can take advantage of`@Autowired` and `@Value` injection and other features the same as any other bean.
+
+| |Make sure that the dependencies you inject that way are of the simplest kind only. `@Configuration`classes are processed quite early during the initialization of the context, and forcing a dependency
to be injected this way may lead to unexpected early initialization. Whenever possible, resort to
parameter-based injection, as in the preceding example.
Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProcessor` definitions
through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the
instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not
work on the configuration class itself, since it is possible to create it as a bean instance earlier than[`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()
+ transferService.transfer(100.00, "A123", "C456")
+}
+```
+
+| |Constructor injection in `@Configuration` classes is only supported as of Spring
Framework 4.3. Note also that there is no need to specify `@Autowired` if the target
bean defines only one constructor.|
+|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+[]()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()
+ transferService.transfer(100.00, "A123", "C456")
+}
+```
+
+Now `ServiceConfig` is loosely coupled with respect to the concrete`DefaultRepositoryConfig`, and built-in IDE tooling is still useful: You can easily
+get a type hierarchy of `RepositoryConfig` implementations. In this
+way, navigating `@Configuration` classes and their dependencies becomes no different
+than the usual process of navigating interface-based code.
+
+| |If you want to influence the startup creation order of certain beans, consider
declaring some of them as `@Lazy` (for creation on first access instead of on startup)
or as `@DependsOn` certain other beans (making sure that specific other beans are
created before the current bean, beyond what the latter’s direct dependencies imply).|
+|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+##### [](#beans-java-conditional)Conditionally Include `@Configuration` Classes or `@Bean` Methods #####
+
+It is often useful to conditionally enable or disable a complete `@Configuration` class
+or even individual `@Bean` methods, based on some arbitrary system state. One common
+example of this is to use the `@Profile` annotation to activate beans only when a specific
+profile has been enabled in the Spring `Environment` (see [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 attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
+ if (attrs != null) {
+ for (Object value : attrs.get("value")) {
+ if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+```
+
+Kotlin
+
+```
+override fun matches(context: ConditionContext, metadata: AnnotatedTypeMetadata): Boolean {
+ // Read the @Profile annotation attributes
+ val attrs = metadata.getAllAnnotationAttributes(Profile::class.java.name)
+ if (attrs != null) {
+ for (value in attrs["value"]!!) {
+ if (context.environment.acceptsProfiles(Profiles.of(*value as Array))) {
+ return true
+ }
+ }
+ return false
+ }
+ return true
+}
+```
+
+See the [`@Conditional`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Conditional.html)javadoc for more detail.
+
+##### [](#beans-java-combining)Combining Java and XML Configuration #####
+
+Spring’s `@Configuration` class support does not aim to be a 100% complete replacement
+for Spring XML. Some facilities, such as Spring XML namespaces, remain an ideal way to
+configure the container. In cases where XML is convenient or necessary, you have a
+choice: either instantiate the container in an “XML-centric” way by using, for example,`ClassPathXmlApplicationContext`, or instantiate it in a “Java-centric” way by using`AnnotationConfigApplicationContext` and the `@ImportResource` annotation to import XML
+as needed.
+
+###### [](#beans-java-combining-xml-centric)XML-centric Use of `@Configuration` Classes ######
+
+It may be preferable to bootstrap the Spring container from XML and include`@Configuration` classes in an ad-hoc fashion. For example, in a large existing codebase
+that uses Spring XML, it is easier to create `@Configuration` classes on an
+as-needed basis and include them from the existing XML files. Later in this section, we cover the
+options for using `@Configuration` classes in this kind of “XML-centric” situation.
+
+[]()Declaring `@Configuration` classes as plain Spring `` elements
+
+Remember that `@Configuration` classes are ultimately bean definitions in the
+container. In this series examples, we create a `@Configuration` class named `AppConfig` and
+include it within `system-test-config.xml` as a `` definition. Because`` is switched on, the container recognizes the`@Configuration` annotation and processes the `@Bean` methods declared in `AppConfig`properly.
+
+The following example shows an ordinary configuration class in Java:
+
+Java
+
+```
+@Configuration
+public class AppConfig {
+
+ @Autowired
+ private DataSource dataSource;
+
+ @Bean
+ public AccountRepository accountRepository() {
+ return new JdbcAccountRepository(dataSource);
+ }
+
+ @Bean
+ public TransferService transferService() {
+ return new TransferService(accountRepository());
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+class AppConfig {
+
+ @Autowired
+ private lateinit var dataSource: DataSource
+
+ @Bean
+ fun accountRepository(): AccountRepository {
+ return JdbcAccountRepository(dataSource)
+ }
+
+ @Bean
+ fun transferService() = TransferService(accountRepository())
+}
+```
+
+The following example shows part of a sample `system-test-config.xml` file:
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+The following example shows a possible `jdbc.properties` file:
+
+```
+jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
+jdbc.username=sa
+jdbc.password=
+```
+
+Java
+
+```
+public static void main(String[] args) {
+ ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml");
+ TransferService transferService = ctx.getBean(TransferService.class);
+ // ...
+}
+```
+
+Kotlin
+
+```
+fun main() {
+ val ctx = ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml")
+ val transferService = ctx.getBean()
+ // ...
+}
+```
+
+| |In `system-test-config.xml` file, the `AppConfig` `` does not declare an `id`element. While it would be acceptable to do so, it is unnecessary, given that no other bean
ever refers to it, and it is unlikely to be explicitly fetched from the container by name.
Similarly, the `DataSource` bean is only ever autowired by type, so an explicit bean `id`is not strictly required.|
+|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+[]() Using \ to pick up `@Configuration` classes
+
+Because `@Configuration` is meta-annotated with `@Component`, `@Configuration`-annotated
+classes are automatically candidates for component scanning. Using the same scenario as
+describe in the previous example, we can redefine `system-test-config.xml` to take advantage of component-scanning.
+Note that, in this case, we need not explicitly declare``, because `` enables the same
+functionality.
+
+The following example shows the modified `system-test-config.xml` file:
+
+```
+
+
+
+
+
+
+
+
+
+
+
+```
+
+###### [](#beans-java-combining-java-centric)`@Configuration` Class-centric Use of XML with `@ImportResource` ######
+
+In applications where `@Configuration` classes are the primary mechanism for configuring
+the container, it is still likely necessary to use at least some XML. In these
+scenarios, you can use `@ImportResource` and define only as much XML as you need. Doing
+so achieves a “Java-centric” approach to configuring the container and keeps XML to a
+bare minimum. The following example (which includes a configuration class, an XML file
+that defines a bean, a properties file, and the `main` class) shows how to use
+the `@ImportResource` annotation to achieve “Java-centric” configuration that uses XML
+as needed:
+
+Java
+
+```
+@Configuration
+@ImportResource("classpath:/com/acme/properties-config.xml")
+public class AppConfig {
+
+ @Value("${jdbc.url}")
+ private String url;
+
+ @Value("${jdbc.username}")
+ private String username;
+
+ @Value("${jdbc.password}")
+ private String password;
+
+ @Bean
+ public DataSource dataSource() {
+ return new DriverManagerDataSource(url, username, password);
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@ImportResource("classpath:/com/acme/properties-config.xml")
+class AppConfig {
+
+ @Value("\${jdbc.url}")
+ private lateinit var url: String
+
+ @Value("\${jdbc.username}")
+ private lateinit var username: String
+
+ @Value("\${jdbc.password}")
+ private lateinit var password: String
+
+ @Bean
+ fun dataSource(): DataSource {
+ return DriverManagerDataSource(url, username, password)
+ }
+}
+```
+
+```
+properties-config.xml
+
+
+
+```
+
+```
+jdbc.properties
+jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
+jdbc.username=sa
+jdbc.password=
+```
+
+Java
+
+```
+public static void main(String[] args) {
+ ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+ TransferService transferService = ctx.getBean(TransferService.class);
+ // ...
+}
+```
+
+Kotlin
+
+```
+import org.springframework.beans.factory.getBean
+
+fun main() {
+ val ctx = AnnotationConfigApplicationContext(AppConfig::class.java)
+ val transferService = ctx.getBean()
+ // ...
+}
+```
+
+### [](#beans-environment)1.13. Environment Abstraction ###
+
+The [`Environment`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/env/Environment.html) interface
+is an abstraction integrated in the container that models two key
+aspects of the application environment: [profiles](#beans-definition-profiles)and [properties](#beans-property-source-abstraction).
+
+A profile is a named, logical group of bean definitions to be registered with the
+container only if the given profile is active. Beans may be assigned to a profile
+whether defined in XML or with annotations. The role of the `Environment` object with
+relation to profiles is in determining which profiles (if any) are currently active,
+and which profiles (if any) should be active by default.
+
+Properties play an important role in almost all applications and may originate from
+a variety of sources: properties files, JVM system properties, system environment
+variables, JNDI, servlet context parameters, ad-hoc `Properties` objects, `Map` objects, and so
+on. The role of the `Environment` object with relation to properties is to provide the
+user with a convenient service interface for configuring property sources and resolving
+properties from them.
+
+#### [](#beans-definition-profiles)1.13.1. Bean Definition Profiles ####
+
+Bean definition profiles provide a mechanism in the core container that allows for
+registration of different beans in different environments. The word, “environment,”
+can mean different things to different users, and this feature can help with many
+use cases, including:
+
+* Working against an in-memory datasource in development versus looking up that same
+ datasource from JNDI when in QA or production.
+
+* Registering monitoring infrastructure only when deploying an application into a
+ performance environment.
+
+* Registering customized implementations of beans for customer A versus customer
+ B deployments.
+
+Consider the first use case in a practical application that requires a`DataSource`. In a test environment, the configuration might resemble the following:
+
+Java
+
+```
+@Bean
+public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("my-schema.sql")
+ .addScript("my-test-data.sql")
+ .build();
+}
+```
+
+Kotlin
+
+```
+@Bean
+fun dataSource(): DataSource {
+ return EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("my-schema.sql")
+ .addScript("my-test-data.sql")
+ .build()
+}
+```
+
+Now consider how this application can be deployed into a QA or production
+environment, assuming that the datasource for the application is registered
+with the production application server’s JNDI directory. Our `dataSource` bean
+now looks like the following listing:
+
+Java
+
+```
+@Bean(destroyMethod="")
+public DataSource dataSource() throws Exception {
+ Context ctx = new InitialContext();
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
+}
+```
+
+Kotlin
+
+```
+@Bean(destroyMethod = "")
+fun dataSource(): DataSource {
+ val ctx = InitialContext()
+ return ctx.lookup("java:comp/env/jdbc/datasource") as DataSource
+}
+```
+
+The problem is how to switch between using these two variations based on the
+current environment. Over time, Spring users have devised a number of ways to
+get this done, usually relying on a combination of system environment variables
+and XML `` statements containing `${placeholder}` tokens that resolve
+to the correct configuration file path depending on the value of an environment
+variable. Bean definition profiles is a core container feature that provides a
+solution to this problem.
+
+If we generalize the use case shown in the preceding example of environment-specific bean
+definitions, we end up with the need to register certain bean definitions in
+certain contexts but not in others. You could say that you want to register a
+certain profile of bean definitions in situation A and a different profile in
+situation B. We start by updating our configuration to reflect this need.
+
+##### [](#beans-definition-profiles-java)Using `@Profile` #####
+
+The [`@Profile`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Profile.html)annotation lets you indicate that a component is eligible for registration
+when one or more specified profiles are active. Using our preceding example, we
+can rewrite the `dataSource` configuration as follows:
+
+Java
+
+```
+@Configuration
+@Profile("development")
+public class StandaloneDataConfig {
+
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
+ .build();
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@Profile("development")
+class StandaloneDataConfig {
+
+ @Bean
+ fun dataSource(): DataSource {
+ return EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .addScript("classpath:com/bank/config/sql/schema.sql")
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
+ .build()
+ }
+}
+```
+
+Java
+
+```
+@Configuration
+@Profile("production")
+public class JndiDataConfig {
+
+ @Bean(destroyMethod="")
+ public DataSource dataSource() throws Exception {
+ Context ctx = new InitialContext();
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
+ }
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@Profile("production")
+class JndiDataConfig {
+
+ @Bean(destroyMethod = "")
+ fun dataSource(): DataSource {
+ val ctx = InitialContext()
+ return ctx.lookup("java:comp/env/jdbc/datasource") as DataSource
+ }
+}
+```
+
+| |As mentioned earlier, with `@Bean` methods, you typically choose to use programmatic
JNDI lookups, by using either Spring’s `JndiTemplate`/`JndiLocatorDelegate` helpers or the
straight JNDI `InitialContext` usage shown earlier but not the `JndiObjectFactoryBean`variant, which would force you to declare the return type as the `FactoryBean` type.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+The profile string may contain a simple profile name (for example, `production`) or a
+profile expression. A profile expression allows for more complicated profile logic to be
+expressed (for example, `production & us-east`). The following operators are supported in
+profile expressions:
+
+* `!`: A logical “not” of the profile
+
+* `&`: A logical “and” of the profiles
+
+* `|`: A logical “or” of the profiles
+
+| |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 `` element. Our preceding sample
+configuration can be rewritten in two XML files, as follows:
+
+```
+
+
+
+
+
+
+
+```
+
+```
+
+
+
+
+```
+
+It is also possible to avoid that split and nest `` elements within the same file,
+as the following example shows:
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+The `spring-bean.xsd` has been constrained to allow such elements only as the
+last ones in the file. This should help provide flexibility without incurring
+clutter in the XML files.
+
+| |The XML counterpart does not support the profile expressions described earlier. It is possible,
however, to negate a profile by using the `!` operator. It is also possible to apply a logical
“and” by nesting the profiles, as the following example shows:
```
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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`:
+
+```
+
+
+
+```
+
+### [](#context-load-time-weaver)1.14. Registering a `LoadTimeWeaver` ###
+
+The `LoadTimeWeaver` is used by Spring to dynamically transform classes as they are
+loaded into the Java virtual machine (JVM).
+
+To enable load-time weaving, you can add the `@EnableLoadTimeWeaving` to one of your`@Configuration` classes, as the following example shows:
+
+Java
+
+```
+@Configuration
+@EnableLoadTimeWeaving
+public class AppConfig {
+}
+```
+
+Kotlin
+
+```
+@Configuration
+@EnableLoadTimeWeaving
+class AppConfig
+```
+
+Alternatively, for XML configuration, you can use the `context:load-time-weaver` element:
+
+```
+
+
+
+```
+
+Once configured for the `ApplicationContext`, any bean within that `ApplicationContext`may implement `LoadTimeWeaverAware`, thereby receiving a reference to the load-time
+weaver instance. This is particularly useful in combination with[Spring’s JPA support](data-access.html#orm-jpa) where load-time weaving may be
+necessary for JPA class transformation.
+Consult the[`LocalContainerEntityManagerFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html)javadoc for more detail. For more on AspectJ load-time weaving, see [Load-time Weaving with AspectJ in the Spring Framework](#aop-aj-ltw).
+
+### [](#context-introduction)1.15. Additional Capabilities of the `ApplicationContext` ###
+
+As discussed in the [chapter introduction](#beans), the `org.springframework.beans.factory`package provides basic functionality for managing and manipulating beans, including in a
+programmatic way. The `org.springframework.context` package adds the[`ApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/ApplicationContext.html)interface, which extends the `BeanFactory` interface, in addition to extending other
+interfaces to provide additional functionality in a more application
+framework-oriented style. Many people use the `ApplicationContext` in a completely
+declarative fashion, not even creating it programmatically, but instead relying on
+support classes such as `ContextLoader` to automatically instantiate an`ApplicationContext` as part of the normal startup process of a Java EE web application.
+
+To enhance `BeanFactory` functionality in a more framework-oriented style, the context
+package also provides the following functionality:
+
+* Access to messages in i18n-style, through the `MessageSource` interface.
+
+* Access to resources, such as URLs and files, through the `ResourceLoader` interface.
+
+* Event publication, namely to beans that implement the `ApplicationListener` interface,
+ through the use of the `ApplicationEventPublisher` interface.
+
+* Loading of multiple (hierarchical) contexts, letting each be focused on one
+ particular layer, such as the web layer of an application, through the`HierarchicalBeanFactory` interface.
+
+#### [](#context-functionality-messagesource)1.15.1. Internationalization using `MessageSource` ####
+
+The `ApplicationContext` interface extends an interface called `MessageSource` and,
+therefore, provides internationalization (“i18n”) functionality. Spring also provides the`HierarchicalMessageSource` interface, which can resolve messages hierarchically.
+Together, these interfaces provide the foundation upon which Spring effects message
+resolution. The methods defined on these interfaces include:
+
+* `String getMessage(String code, Object[] args, String default, Locale loc)`: The basic
+ method used to retrieve a message from the `MessageSource`. When no message is found
+ for the specified locale, the default message is used. Any arguments passed in become
+ replacement values, using the `MessageFormat` functionality provided by the standard
+ library.
+
+* `String getMessage(String code, Object[] args, Locale loc)`: Essentially the same as
+ the previous method but with one difference: No default message can be specified. If
+ the message cannot be found, a `NoSuchMessageException` is thrown.
+
+* `String getMessage(MessageSourceResolvable resolvable, Locale locale)`: All properties
+ used in the preceding methods are also wrapped in a class named`MessageSourceResolvable`, which you can use with this method.
+
+When an `ApplicationContext` is loaded, it automatically searches for a `MessageSource`bean defined in the context. The bean must have the name `messageSource`. If such a bean
+is found, all calls to the preceding methods are delegated to the message source. If no
+message source is found, the `ApplicationContext` attempts to find a parent containing a
+bean with the same name. If it does, it uses that bean as the `MessageSource`. If the`ApplicationContext` cannot find any source for messages, an empty`DelegatingMessageSource` is instantiated in order to be able to accept calls to the
+methods defined above.
+
+Spring provides three `MessageSource` implementations, `ResourceBundleMessageSource`, `ReloadableResourceBundleMessageSource`and `StaticMessageSource`. All of them implement `HierarchicalMessageSource` in order to do nested
+messaging. The `StaticMessageSource` is rarely used but provides programmatic ways to
+add messages to the source. The following example shows `ResourceBundleMessageSource`:
+
+```
+
+
+
+
+ format
+ exceptions
+ windows
+
+
+
+
+```
+
+The example assumes that you have three resource bundles called `format`, `exceptions` and `windows`defined in your classpath. Any request to resolve a message is
+handled in the JDK-standard way of resolving messages through `ResourceBundle` objects. For the
+purposes of the example, assume the contents of two of the above resource bundle files
+are as follows:
+
+```
+ # in format.properties
+ message=Alligators rock!
+```
+
+```
+ # in exceptions.properties
+ argument.required=The {0} argument is required.
+```
+
+The next example shows a program to run the `MessageSource` functionality.
+Remember that all `ApplicationContext` implementations are also `MessageSource`implementations and so can be cast to the `MessageSource` interface.
+
+Java
+
+```
+public static void main(String[] args) {
+ MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
+ String message = resources.getMessage("message", null, "Default", Locale.ENGLISH);
+ System.out.println(message);
+}
+```
+
+Kotlin
+
+```
+fun main() {
+ val resources = ClassPathXmlApplicationContext("beans.xml")
+ val message = resources.getMessage("message", null, "Default", Locale.ENGLISH)
+ println(message)
+}
+```
+
+The resulting output from the above program is as follows:
+
+```
+Alligators rock!
+```
+
+To summarize, the `MessageSource` is defined in a file called `beans.xml`, which
+exists at the root of your classpath. The `messageSource` bean definition refers to a
+number of resource bundles through its `basenames` property. The three files that are
+passed in the list to the `basenames` property exist as files at the root of your
+classpath and are called `format.properties`, `exceptions.properties`, and`windows.properties`, respectively.
+
+The next example shows arguments passed to the message lookup. These arguments are
+converted into `String` objects and inserted into placeholders in the lookup message.
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Java
+
+```
+public class Example {
+
+ private MessageSource messages;
+
+ public void setMessages(MessageSource messages) {
+ this.messages = messages;
+ }
+
+ public void execute() {
+ String message = this.messages.getMessage("argument.required",
+ new Object [] {"userDao"}, "Required", Locale.ENGLISH);
+ System.out.println(message);
+ }
+}
+```
+
+Kotlin
+
+```
+ class Example {
+
+ lateinit var messages: MessageSource
+
+ fun execute() {
+ val message = messages.getMessage("argument.required",
+ arrayOf("userDao"), "Required", Locale.ENGLISH)
+ println(message)
+ }
+}
+```
+
+The resulting output from the invocation of the `execute()` method is as follows:
+
+```
+The userDao argument is required.
+```
+
+With regard to internationalization (“i18n”), Spring’s various `MessageSource`implementations follow the same locale resolution and fallback rules as the standard JDK`ResourceBundle`. In short, and continuing with the example `messageSource` defined
+previously, if you want to resolve messages against the British (`en-GB`) locale, you
+would create files called `format_en_GB.properties`, `exceptions_en_GB.properties`, and`windows_en_GB.properties`, respectively.
+
+Typically, locale resolution is managed by the surrounding environment of the
+application. In the following example, the locale against which (British) messages are
+resolved is specified manually:
+
+```
+# in exceptions_en_GB.properties
+argument.required=Ebagum lad, the ''{0}'' argument is required, I say, required.
+```
+
+Java
+
+```
+public static void main(final String[] args) {
+ MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
+ String message = resources.getMessage("argument.required",
+ new Object [] {"userDao"}, "Required", Locale.UK);
+ System.out.println(message);
+}
+```
+
+Kotlin
+
+```
+fun main() {
+ val resources = ClassPathXmlApplicationContext("beans.xml")
+ val message = resources.getMessage("argument.required",
+ arrayOf("userDao"), "Required", Locale.UK)
+ println(message)
+}
+```
+
+The resulting output from the running of the above program is as follows:
+
+```
+Ebagum lad, the 'userDao' argument is required, I say, required.
+```
+
+You can also use the `MessageSourceAware` interface to acquire a reference to any`MessageSource` that has been defined. Any bean that is defined in an`ApplicationContext` that implements the `MessageSourceAware` interface is injected with
+the application context’s `MessageSource` when the bean is created and configured.
+
+| |Because Spring’s `MessageSource` is based on Java’s `ResourceBundle`, it does not merge
bundles with the same base name, but will only use the first bundle found.
Subsequent message bundles with the same base name are ignored.|
+|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+| |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 blockedList;
+ private ApplicationEventPublisher publisher;
+
+ public void setBlockedList(List blockedList) {
+ this.blockedList = blockedList;
+ }
+
+ public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
+ this.publisher = publisher;
+ }
+
+ public void sendEmail(String address, String content) {
+ if (blockedList.contains(address)) {
+ publisher.publishEvent(new BlockedListEvent(this, address, content));
+ return;
+ }
+ // send email...
+ }
+}
+```
+
+Kotlin
+
+```
+class EmailService : ApplicationEventPublisherAware {
+
+ private lateinit var blockedList: List
+ private lateinit var publisher: ApplicationEventPublisher
+
+ fun setBlockedList(blockedList: List) {
+ this.blockedList = blockedList
+ }
+
+ override fun setApplicationEventPublisher(publisher: ApplicationEventPublisher) {
+ this.publisher = publisher
+ }
+
+ fun sendEmail(address: String, content: String) {
+ if (blockedList!!.contains(address)) {
+ publisher!!.publishEvent(BlockedListEvent(this, address, content))
+ return
+ }
+ // send email...
+ }
+}
+```
+
+At configuration time, the Spring container detects that `EmailService` implements`ApplicationEventPublisherAware` and automatically calls`setApplicationEventPublisher()`. In reality, the parameter passed in is the Spring
+container itself. You are interacting with the application context through its`ApplicationEventPublisher` interface.
+
+To receive the custom `ApplicationEvent`, you can create a class that implements`ApplicationListener` and register it as a Spring bean. The following example
+shows such a class:
+
+Java
+
+```
+public class BlockedListNotifier implements ApplicationListener {
+
+ private String notificationAddress;
+
+ public void setNotificationAddress(String notificationAddress) {
+ this.notificationAddress = notificationAddress;
+ }
+
+ public void onApplicationEvent(BlockedListEvent event) {
+ // notify appropriate parties via notificationAddress...
+ }
+}
+```
+
+Kotlin
+
+```
+class BlockedListNotifier : ApplicationListener {
+
+ lateinit var notificationAddres: String
+
+ override fun onApplicationEvent(event: BlockedListEvent) {
+ // notify appropriate parties via notificationAddress...
+ }
+}
+```
+
+Notice that `ApplicationListener` is generically parameterized with the type of your
+custom event (`BlockedListEvent` in the preceding example). This means that the`onApplicationEvent()` method can remain type-safe, avoiding any need for downcasting.
+You can register as many event listeners as you wish, but note that, by default, event
+listeners receive events synchronously. This means that the `publishEvent()` method
+blocks until all listeners have finished processing the event. One advantage of this
+synchronous and single-threaded approach is that, when a listener receives an event, it
+operates inside the transaction context of the publisher if a transaction context is
+available. If another strategy for event publication becomes necessary, see the javadoc
+for Spring’s[`ApplicationEventMulticaster`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/event/ApplicationEventMulticaster.html) interface
+and [`SimpleApplicationEventMulticaster`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/event/SimpleApplicationEventMulticaster.html)implementation for configuration options.
+
+The following example shows the bean definitions used to register and configure each of
+the classes above:
+
+```
+
+
+
+ [email protected]
+ [email protected]
+ [email protected]
+
+
+
+
+
+
+
+```
+
+Putting it all together, when the `sendEmail()` method of the `emailService` bean is
+called, if there are any email messages that should be blocked, a custom event of type`BlockedListEvent` is published. The `blockedListNotifier` bean is registered as an`ApplicationListener` and receives the `BlockedListEvent`, at which point it can
+notify appropriate parties.
+
+| |Spring’s eventing mechanism is designed for simple communication between Spring beans
within the same application context. However, for more sophisticated enterprise
integration needs, the separately maintained[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` where `T` is the type of the actual entity that got created. For example, you
+can create the following listener definition to receive only `EntityCreatedEvent` for a`Person`:
+
+Java
+
+```
+@EventListener
+public void onPersonCreated(EntityCreatedEvent event) {
+ // ...
+}
+```
+
+Kotlin
+
+```
+@EventListener
+fun onPersonCreated(event: EntityCreatedEvent) {
+ // ...
+}
+```
+
+Due to type erasure, this works only if the event that is fired resolves the generic
+parameters on which the event listener filters (that is, something like`class PersonCreatedEvent extends EntityCreatedEvent { … }`).
+
+In certain circumstances, this may become quite tedious if all events follow the same
+structure (as should be the case for the event in the preceding example). In such a case,
+you can implement `ResolvableTypeProvider` to guide the framework beyond what the runtime
+environment provides. The following event shows how to do so:
+
+Java
+
+```
+public class EntityCreatedEvent extends ApplicationEvent implements ResolvableTypeProvider {
+
+ public EntityCreatedEvent(T entity) {
+ super(entity);
+ }
+
+ @Override
+ public ResolvableType getResolvableType() {
+ return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getSource()));
+ }
+}
+```
+
+Kotlin
+
+```
+class EntityCreatedEvent(entity: T) : ApplicationEvent(entity), ResolvableTypeProvider {
+
+ override fun getResolvableType(): ResolvableType? {
+ return ResolvableType.forClassWithGenerics(javaClass, ResolvableType.forInstance(getSource()))
+ }
+}
+```
+
+| |This works not only for `ApplicationEvent` but any arbitrary object that you send as
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:
+
+```
+
+ contextConfigLocation
+ /WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+```
+
+The listener inspects the `contextConfigLocation` parameter. If the parameter does not
+exist, the listener uses `/WEB-INF/applicationContext.xml` as a default. When the
+parameter does exist, the listener separates the `String` by using predefined
+delimiters (comma, semicolon, and whitespace) and uses the values as locations where
+application contexts are searched. Ant-style path patterns are supported as well.
+Examples are `/WEB-INF/*Context.xml` (for all files with names that end with`Context.xml` and that reside in the `WEB-INF` directory) and `/WEB-INF/**/*Context.xml`(for all such files in any subdirectory of `WEB-INF`).
+
+#### [](#context-deploy-rar)1.15.6. Deploying a Spring `ApplicationContext` as a Java EE RAR File ####
+
+It is possible to deploy a Spring `ApplicationContext` as a RAR file, encapsulating the
+context and all of its required bean classes and library JARs in a Java EE RAR deployment
+unit. This is the equivalent of bootstrapping a stand-alone `ApplicationContext` (only hosted
+in Java EE environment) being able to access the Java EE servers facilities. RAR deployment
+is a more natural alternative to a scenario of deploying a headless WAR file — in effect,
+a WAR file without any HTTP entry points that is used only for bootstrapping a Spring`ApplicationContext` in a Java EE environment.
+
+RAR deployment is ideal for application contexts that do not need HTTP entry points but
+rather consist only of message endpoints and scheduled jobs. Beans in such a context can
+use application server resources such as the JTA transaction manager and JNDI-bound JDBC`DataSource` instances and JMS `ConnectionFactory` instances and can also register with
+the platform’s JMX server — all through Spring’s standard transaction management and JNDI
+and JMX support facilities. Application components can also interact with the application
+server’s JCA `WorkManager` through Spring’s `TaskExecutor` abstraction.
+
+See the javadoc of the[`SpringContextResourceAdapter`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jca/context/SpringContextResourceAdapter.html)class for the configuration details involved in RAR deployment.
+
+For a simple deployment of a Spring ApplicationContext as a Java EE RAR file:
+
+1. Package
+ all application classes into a RAR file (which is a standard JAR file with a different
+ file extension).
+
+2. Add all required library JARs into the root of the RAR archive.
+
+3. Add a`META-INF/ra.xml` deployment descriptor (as shown in the [javadoc for `SpringContextResourceAdapter`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jca/context/SpringContextResourceAdapter.html))
+ and the corresponding Spring XML bean definition file(s) (typically`META-INF/applicationContext.xml`).
+
+4. Drop the resulting RAR file into your
+ application server’s deployment directory.
+
+| |Such RAR deployment units are usually self-contained. They do not expose components
to the outside world, not even to other modules of the same application. Interaction with a
RAR-based `ApplicationContext` usually occurs through JMS destinations that it shares with
other modules. A RAR-based `ApplicationContext` may also, for example, schedule some jobs
or react to new files in the file system (or the like). If it needs to allow synchronous
access from the outside, it could (for example) export RMI endpoints, which may be used
by other application modules on the same machine.|
+|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+### [](#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:
+
+```
+
+
+
+```
+
+Note that the resource path has no prefix. Consequently, because the application context
+itself is going to be used as the `ResourceLoader`, the resource is loaded through a`ClassPathResource`, a `FileSystemResource`, or a `ServletContextResource`, depending on
+the exact type of the application context.
+
+If you need to force a specific `Resource` type to be used, you can use a prefix. The
+following two examples show how to force a `ClassPathResource` and a `UrlResource` (the
+latter being used to access a file in the filesystem):
+
+```
+
+```
+
+```
+
+```
+
+If the `MyBean` class is refactored for use with annotation-driven configuration, the
+path to `myTemplate.txt` can be stored under a key named `template.path` — for example,
+in a properties file made available to the Spring `Environment` (see[Environment Abstraction](#beans-environment)). The template path can then be referenced via the `@Value`annotation using a property placeholder (see [Using `@Value`](#beans-value-annotations)). Spring will
+retrieve the value of the template path as a string, and a special `PropertyEditor` will
+convert the string to a `Resource` object to be injected into the `MyBean` constructor.
+The following example demonstrates how to achieve this.
+
+Java
+
+```
+@Component
+public class MyBean {
+
+ private final Resource template;
+
+ public MyBean(@Value("${template.path}") Resource template) {
+ this.template = template;
+ }
+
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Component
+class MyBean(@Value("\${template.path}") private val template: Resource)
+```
+
+If we want to support multiple templates discovered under the same path in multiple
+locations in the classpath — for example, in multiple jars in the classpath — we can
+use the special `classpath*:` prefix and wildcarding to define a `templates.path` key as`classpath*:/config/templates/*.txt`. If we redefine the `MyBean` class as follows,
+Spring will convert the template path pattern into an array of `Resource` objects that
+can be injected into the `MyBean` constructor.
+
+Java
+
+```
+@Component
+public class MyBean {
+
+ private final Resource[] templates;
+
+ public MyBean(@Value("${templates.path}") Resource[] templates) {
+ this.templates = templates;
+ }
+
+ // ...
+}
+```
+
+Kotlin
+
+```
+@Component
+class MyBean(@Value("\${templates.path}") private val templates: Resource[])
+```
+
+### [](#resources-app-ctx)2.8. Application Contexts and Resource Paths ###
+
+This section covers how to create application contexts with resources, including shortcuts
+that work with XML, how to use wildcards, and other details.
+
+#### [](#resources-app-ctx-construction)2.8.1. Constructing Application Contexts ####
+
+An application context constructor (for a specific application context type) generally
+takes a string or array of strings as the location paths of the resources, such as
+XML files that make up the definition of the context.
+
+When such a location path does not have a prefix, the specific `Resource` type built from
+that path and used to load the bean definitions depends on and is appropriate to the
+specific application context. For example, consider the following example, which creates a`ClassPathXmlApplicationContext`:
+
+Java
+
+```
+ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
+```
+
+Kotlin
+
+```
+val ctx = ClassPathXmlApplicationContext("conf/appContext.xml")
+```
+
+The bean definitions are loaded from the classpath, because a `ClassPathResource` is
+used. However, consider the following example, which creates a `FileSystemXmlApplicationContext`:
+
+Java
+
+```
+ApplicationContext ctx =
+ new FileSystemXmlApplicationContext("conf/appContext.xml");
+```
+
+Kotlin
+
+```
+val ctx = FileSystemXmlApplicationContext("conf/appContext.xml")
+```
+
+Now the bean definitions are loaded from a filesystem location (in this case, relative to
+the current working directory).
+
+Note that the use of the special `classpath` prefix or a standard URL prefix on the
+location path overrides the default type of `Resource` created to load the bean
+definitions. Consider the following example:
+
+Java
+
+```
+ApplicationContext ctx =
+ new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
+```
+
+Kotlin
+
+```
+val ctx = FileSystemXmlApplicationContext("classpath:conf/appContext.xml")
+```
+
+Using `FileSystemXmlApplicationContext` loads the bean definitions from the classpath.
+However, it is still a `FileSystemXmlApplicationContext`. If it is subsequently used as a`ResourceLoader`, any unprefixed paths are still treated as filesystem paths.
+
+##### [](#resources-app-ctx-classpathxml)Constructing `ClassPathXmlApplicationContext` Instances — Shortcuts #####
+
+The `ClassPathXmlApplicationContext` exposes a number of constructors to enable
+convenient instantiation. The basic idea is that you can supply merely a string array
+that contains only the filenames of the XML files themselves (without the leading path
+information) and also supply a `Class`. The `ClassPathXmlApplicationContext` then derives
+the path information from the supplied class.
+
+Consider the following directory layout:
+
+```
+com/
+ example/
+ services.xml
+ repositories.xml
+ MessengerService.class
+```
+
+The following example shows how a `ClassPathXmlApplicationContext` instance composed of
+the beans defined in files named `services.xml` and `repositories.xml` (which are on the
+classpath) can be instantiated:
+
+Java
+
+```
+ApplicationContext ctx = new ClassPathXmlApplicationContext(
+ new String[] {"services.xml", "repositories.xml"}, MessengerService.class);
+```
+
+Kotlin
+
+```
+val ctx = ClassPathXmlApplicationContext(arrayOf("services.xml", "repositories.xml"), MessengerService::class.java)
+```
+
+See the [`ClassPathXmlApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/support/ClassPathXmlApplicationContext.html)javadoc for details on the various constructors.
+
+#### [](#resources-app-ctx-wildcards-in-resource-paths)2.8.2. Wildcards in Application Context Constructor Resource Paths ####
+
+The resource paths in application context constructor values may be simple paths (as
+shown earlier), each of which has a one-to-one mapping to a target `Resource` or,
+alternately, may contain the special `classpath*:` prefix or internal Ant-style patterns
+(matched by using Spring’s `PathMatcher` utility). Both of the latter are effectively
+wildcards.
+
+One use for this mechanism is when you need to do component-style application assembly. All
+components can *publish* context definition fragments to a well-known location path, and,
+when the final application context is created using the same path prefixed with`classpath*:`, all component fragments are automatically picked up.
+
+Note that this wildcarding is specific to the use of resource paths in application context
+constructors (or when you use the `PathMatcher` utility class hierarchy directly) and is
+resolved at construction time. It has nothing to do with the `Resource` type itself.
+You cannot use the `classpath*:` prefix to construct an actual `Resource`, as
+a resource points to just one resource at a time.
+
+##### [](#resources-app-ctx-ant-patterns-in-paths)Ant-style Patterns #####
+
+Path locations can contain Ant-style patterns, as the following example shows:
+
+```
+/WEB-INF/*-context.xml
+com/mycompany/**/applicationContext.xml
+file:C:/some/path/*-context.xml
+classpath:com/mycompany/**/applicationContext.xml
+```
+
+When the path location contains an Ant-style pattern, the resolver follows a more complex
+procedure to try to resolve the wildcard. It produces a `Resource` for the path up to the
+last non-wildcard segment and obtains a URL from it. If this URL is not a `jar:` URL or
+container-specific variant (such as `zip:` in WebLogic, `wsjar` in WebSphere, and so on),
+a `java.io.File` is obtained from it and used to resolve the wildcard by traversing the
+filesystem. In the case of a jar URL, the resolver either gets a`java.net.JarURLConnection` from it or manually parses the jar URL and then traverses the
+contents of the jar file to resolve the wildcards.
+
+###### [](#resources-app-ctx-portability)Implications on Portability ######
+
+If the specified path is already a `file` URL (either implicitly because the base`ResourceLoader` is a filesystem one or explicitly), wildcarding is guaranteed to
+work in a completely portable fashion.
+
+If the specified path is a `classpath` location, the resolver must obtain the last
+non-wildcard path segment URL by making a `Classloader.getResource()` call. Since this
+is just a node of the path (not the file at the end), it is actually undefined (in the`ClassLoader` javadoc) exactly what sort of a URL is returned in this case. In practice,
+it is always a `java.io.File` representing the directory (where the classpath resource
+resolves to a filesystem location) or a jar URL of some sort (where the classpath resource
+resolves to a jar location). Still, there is a portability concern on this operation.
+
+If a jar URL is obtained for the last non-wildcard segment, the resolver must be able to
+get a `java.net.JarURLConnection` from it or manually parse the jar URL, to be able to
+walk the contents of the jar and resolve the wildcard. This does work in most environments
+but fails in others, and we strongly recommend that the wildcard resolution of resources
+coming from jars be thoroughly tested in your specific environment before you rely on it.
+
+##### [](#resources-classpath-wildcards)The `classpath*:` Prefix #####
+
+When constructing an XML-based application context, a location string may use the
+special `classpath*:` prefix, as the following example shows:
+
+Java
+
+```
+ApplicationContext ctx =
+ new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
+```
+
+Kotlin
+
+```
+val ctx = ClassPathXmlApplicationContext("classpath*:conf/appContext.xml")
+```
+
+This special prefix specifies that all classpath resources that match the given name
+must be obtained (internally, this essentially happens through a call to`ClassLoader.getResources(…)`) and then merged to form the final application
+context definition.
+
+| |The wildcard classpath relies on the `getResources()` method of the underlying`ClassLoader`. As most application servers nowadays supply their own `ClassLoader`implementation, the behavior might differ, especially when dealing with jar files. A
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("")`. Try this test with
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 `` tag to inspect the error messages, but
+you can also inspect the `Errors` object yourself. More information about the
+methods it offers can be found in the [javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/Errors.html).
+
+### [](#validation-conversion)3.2. Resolving Codes to Error Messages ###
+
+We covered databinding and validation. This section covers outputting messages that correspond
+to validation errors. In the example shown in the [preceding section](#validator),
+we rejected the `name` and `age` fields. If we want to output the error messages by using a`MessageSource`, we can do so using the error code we provide when rejecting the field
+('name' and 'age' in this case). When you call (either directly, or indirectly, by using,
+for example, the `ValidationUtils` class) `rejectValue` or one of the other `reject` methods
+from the `Errors` interface, the underlying implementation not only registers the code you
+passed in but also registers a number of additional error codes. The `MessageCodesResolver`determines which error codes the `Errors` interface registers. By default, the`DefaultMessageCodesResolver` is used, which (for example) not only registers a message
+with the code you gave but also registers messages that include the field name you passed
+to the reject method. So, if you reject a field by using `rejectValue("age", "too.darn.old")`,
+apart from the `too.darn.old` code, Spring also registers `too.darn.old.age` and`too.darn.old.age.int` (the first includes the field name and the second includes the type
+of the field). This is done as a convenience to aid developers when targeting error messages.
+
+More information on the `MessageCodesResolver` and the default strategy can be found
+in the javadoc of[`MessageCodesResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/MessageCodesResolver.html) and[`DefaultMessageCodesResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/DefaultMessageCodesResolver.html),
+respectively.
+
+### [](#beans-beans)3.3. Bean Manipulation and the `BeanWrapper` ###
+
+The `org.springframework.beans` package adheres to the JavaBeans standard.
+A JavaBean is a class with a default no-argument constructor and that follows
+a naming convention where (for example) a property named `bingoMadness` would
+have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For
+more information about JavaBeans and the specification, see[javabeans](https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html).
+
+One quite important class in the beans package is the `BeanWrapper` interface and its
+corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the`BeanWrapper` offers functionality to set and get property values (individually or in
+bulk), get property descriptors, and query properties to determine if they are
+readable or writable. Also, the `BeanWrapper` offers support for nested properties,
+enabling the setting of properties on sub-properties to an unlimited depth. The`BeanWrapper` also supports the ability to add standard JavaBeans `PropertyChangeListeners`and `VetoableChangeListeners`, without the need for supporting code in the target class.
+Last but not least, the `BeanWrapper` provides support for setting indexed properties.
+The `BeanWrapper` usually is not used by application code directly but is used by the`DataBinder` and the `BeanFactory`.
+
+The way the `BeanWrapper` works is partly indicated by its name: it wraps a bean to
+perform actions on that bean, such as setting and retrieving properties.
+
+#### [](#beans-beans-conventions)3.3.1. Setting and Getting Basic and Nested Properties ####
+
+Setting and getting properties is done through the `setPropertyValue` and`getPropertyValue` overloaded method variants of `BeanWrapper`. See their Javadoc for
+details. The below table shows some examples of these conventions:
+
+| Expression | Explanation |
+|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `name` | Indicates the property `name` that corresponds to the `getName()` or `isName()`and `setName(..)` methods. |
+| `account.name` |Indicates the nested property `name` of the property `account` that corresponds to
(for example) the `getAccount().setName()` or `getAccount().getName()` methods.|
+| `account[2]` | Indicates the *third* element of the indexed property `account`. Indexed properties
can be of type `array`, `list`, or other naturally ordered collection. |
+|`account[COMPANYNAME]`| Indicates the value of the map entry indexed by the `COMPANYNAME` key of the `account` `Map`property. |
+
+(This next section is not vitally important to you if you do not plan to work with
+the `BeanWrapper` directly. If you use only the `DataBinder` and the `BeanFactory`and their default implementations, you should skip ahead to the[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 {
+ try {
+ val numberPE = CustomNumberEditor(Int::class.java, true)
+ val ageDescriptor = object : PropertyDescriptor("age", Something::class.java) {
+ override fun createPropertyEditor(bean: Any): PropertyEditor {
+ return numberPE
+ }
+ }
+ return arrayOf(ageDescriptor)
+ } catch (ex: IntrospectionException) {
+ throw Error(ex.toString())
+ }
+
+ }
+}
+```
+
+##### [](#beans-beans-conversion-customeditor-registration)Registering Additional Custom `PropertyEditor` Implementations #####
+
+When setting bean properties as string values, a Spring IoC container ultimately uses
+standard JavaBeans `PropertyEditor` implementations to convert these strings to the complex type of the
+property. Spring pre-registers a number of custom `PropertyEditor` implementations (for example, to
+convert a class name expressed as a string into a `Class` object). Additionally,
+Java’s standard JavaBeans `PropertyEditor` lookup mechanism lets a `PropertyEditor`for a class be named appropriately and placed in the same package as the class
+for which it provides support, so that it can be found automatically.
+
+If there is a need to register other custom `PropertyEditors`, several mechanisms are
+available. The most manual approach, which is not normally convenient or
+recommended, is to use the `registerCustomEditor()` method of the`ConfigurableBeanFactory` interface, assuming you have a `BeanFactory` reference.
+Another (slightly more convenient) mechanism is to use a special bean factory
+post-processor called `CustomEditorConfigurer`. Although you can use bean factory post-processors
+with `BeanFactory` implementations, the `CustomEditorConfigurer` has a
+nested property setup, so we strongly recommend that you use it with the`ApplicationContext`, where you can deploy it in similar fashion to any other bean and
+where it can be automatically detected and applied.
+
+Note that all bean factories and application contexts automatically use a number of
+built-in property editors, through their use of a `BeanWrapper` to
+handle property conversions. The standard property editors that the `BeanWrapper`registers are listed in the [previous section](#beans-beans-conversion).
+Additionally, `ApplicationContext`s also override or add additional editors to handle
+resource lookups in a manner appropriate to the specific application context type.
+
+Standard JavaBeans `PropertyEditor` instances are used to convert property values
+expressed as strings to the actual complex type of the property. You can use`CustomEditorConfigurer`, a bean factory post-processor, to conveniently add
+support for additional `PropertyEditor` instances to an `ApplicationContext`.
+
+Consider the following example, which defines a user class called `ExoticType` and
+another class called `DependsOnExoticType`, which needs `ExoticType` set as a property:
+
+Java
+
+```
+package example;
+
+public class ExoticType {
+
+ private String name;
+
+ public ExoticType(String name) {
+ this.name = name;
+ }
+}
+
+public class DependsOnExoticType {
+
+ private ExoticType type;
+
+ public void setType(ExoticType type) {
+ this.type = type;
+ }
+}
+```
+
+Kotlin
+
+```
+package example
+
+class ExoticType(val name: String)
+
+class DependsOnExoticType {
+
+ var type: ExoticType? = null
+}
+```
+
+When things are properly set up, we want to be able to assign the type property as a
+string, which a `PropertyEditor` converts into an actual`ExoticType` instance. The following bean definition shows how to set up this relationship:
+
+```
+
+
+
+```
+
+The `PropertyEditor` implementation could look similar to the following:
+
+Java
+
+```
+// converts string representation to ExoticType object
+package example;
+
+public class ExoticTypeEditor extends PropertyEditorSupport {
+
+ public void setAsText(String text) {
+ setValue(new ExoticType(text.toUpperCase()));
+ }
+}
+```
+
+Kotlin
+
+```
+// converts string representation to ExoticType object
+package example
+
+import java.beans.PropertyEditorSupport
+
+class ExoticTypeEditor : PropertyEditorSupport() {
+
+ override fun setAsText(text: String) {
+ value = ExoticType(text.toUpperCase())
+ }
+}
+```
+
+Finally, the following example shows how to use `CustomEditorConfigurer` to register the new `PropertyEditor` with the`ApplicationContext`, which will then be able to use it as needed:
+
+```
+
+
+
+
+
+```
+
+###### [](#beans-beans-conversion-customeditor-registration-per)Using `PropertyEditorRegistrar` ######
+
+Another mechanism for registering property editors with the Spring container is to
+create and use a `PropertyEditorRegistrar`. This interface is particularly useful when
+you need to use the same set of property editors in several different situations.
+You can write a corresponding registrar and reuse it in each case.`PropertyEditorRegistrar` instances work in conjunction with an interface called`PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper`(and `DataBinder`). `PropertyEditorRegistrar` instances are particularly convenient
+when used in conjunction with `CustomEditorConfigurer` (described[here](#beans-beans-conversion-customeditor-registration)), which exposes a property
+called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added
+to a `CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and
+Spring MVC controllers. Furthermore, it avoids the need for synchronization on custom
+editors: A `PropertyEditorRegistrar` is expected to create fresh `PropertyEditor`instances for each bean creation attempt.
+
+The following example shows how to create your own `PropertyEditorRegistrar` implementation:
+
+Java
+
+```
+package com.foo.editors.spring;
+
+public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
+
+ public void registerCustomEditors(PropertyEditorRegistry registry) {
+
+ // it is expected that new PropertyEditor instances are created
+ registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
+
+ // you could register as many custom property editors as are required here...
+ }
+}
+```
+
+Kotlin
+
+```
+package com.foo.editors.spring
+
+import org.springframework.beans.PropertyEditorRegistrar
+import org.springframework.beans.PropertyEditorRegistry
+
+class CustomPropertyEditorRegistrar : PropertyEditorRegistrar {
+
+ override fun registerCustomEditors(registry: PropertyEditorRegistry) {
+
+ // it is expected that new PropertyEditor instances are created
+ registry.registerCustomEditor(ExoticType::class.java, ExoticTypeEditor())
+
+ // you could register as many custom property editors as are required here...
+ }
+}
+```
+
+See also the `org.springframework.beans.support.ResourceEditorRegistrar` for an example`PropertyEditorRegistrar` implementation. Notice how in its implementation of the`registerCustomEditors(..)` method, it creates new instances of each property editor.
+
+The next example shows how to configure a `CustomEditorConfigurer` and inject an instance of our`CustomPropertyEditorRegistrar` into it:
+
+```
+
+
+
+
+
+
+
+
+
+```
+
+Finally (and in a bit of a departure from the focus of this chapter for those of you
+using [Spring’s MVC web framework](web.html#mvc)), using `PropertyEditorRegistrars` in
+conjunction with data-binding `Controllers` (such as `SimpleFormController`) can be very
+convenient. The following example uses a `PropertyEditorRegistrar` in the
+implementation of an `initBinder(..)` method:
+
+Java
+
+```
+public final class RegisterUserController extends SimpleFormController {
+
+ private final PropertyEditorRegistrar customPropertyEditorRegistrar;
+
+ public RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
+ this.customPropertyEditorRegistrar = propertyEditorRegistrar;
+ }
+
+ protected void initBinder(HttpServletRequest request,
+ ServletRequestDataBinder binder) throws Exception {
+ this.customPropertyEditorRegistrar.registerCustomEditors(binder);
+ }
+
+ // other methods to do with registering a User
+}
+```
+
+Kotlin
+
+```
+class RegisterUserController(
+ private val customPropertyEditorRegistrar: PropertyEditorRegistrar) : SimpleFormController() {
+
+ protected fun initBinder(request: HttpServletRequest,
+ binder: ServletRequestDataBinder) {
+ this.customPropertyEditorRegistrar.registerCustomEditors(binder)
+ }
+
+ // other methods to do with registering a User
+}
+```
+
+This style of `PropertyEditor` registration can lead to concise code (the implementation
+of `initBinder(..)` is only one line long) and lets common `PropertyEditor`registration code be encapsulated in a class and then shared amongst as many`Controllers` as needed.
+
+### [](#core-convert)3.4. Spring Type Conversion ###
+
+Spring 3 introduced a `core.convert` package that provides a general type conversion
+system. The system defines an SPI to implement type conversion logic and an API
+to perform type conversions at runtime. Within a Spring container, you can use this system
+as an alternative to `PropertyEditor` implementations to convert externalized bean property value
+strings to the required property types. You can also use the public API anywhere in your
+application where type conversion is needed.
+
+#### [](#core-convert-Converter-API)3.4.1. Converter SPI ####
+
+The SPI to implement type conversion logic is simple and strongly typed, as the following
+interface definition shows:
+
+```
+package org.springframework.core.convert.converter;
+
+public interface Converter {
+
+ T convert(S source);
+}
+```
+
+To create your own converter, implement the `Converter` interface and parameterize `S`as the type you are converting from and `T` as the type you are converting to. You can also transparently apply such a
+converter if a collection or array of `S` needs to be
+converted to an array or collection of `T`, provided that a delegating array or collection
+converter has been registered as well (which `DefaultConversionService` does by default).
+
+For each call to `convert(S)`, the source argument is guaranteed to not be null. Your`Converter` may throw any unchecked exception if conversion fails. Specifically, it should throw an`IllegalArgumentException` to report an invalid source value.
+Take care to ensure that your `Converter` implementation is thread-safe.
+
+Several converter implementations are provided in the `core.convert.support` package as
+a convenience. These include converters from strings to numbers and other common types.
+The following listing shows the `StringToInteger` class, which is a typical `Converter` implementation:
+
+```
+package org.springframework.core.convert.support;
+
+final class StringToInteger implements Converter {
+
+ public Integer convert(String source) {
+ return Integer.valueOf(source);
+ }
+}
+```
+
+#### [](#core-convert-ConverterFactory-SPI)3.4.2. Using `ConverterFactory` ####
+
+When you need to centralize the conversion logic for an entire class hierarchy
+(for example, when converting from `String` to `Enum` objects), you can implement`ConverterFactory`, as the following example shows:
+
+```
+package org.springframework.core.convert.converter;
+
+public interface ConverterFactory {
+
+ Converter getConverter(Class targetType);
+}
+```
+
+Parameterize S to be the type you are converting from and R to be the base type defining
+the *range* of classes you can convert to. Then implement `getConverter(Class)`,
+where T is a subclass of R.
+
+Consider the `StringToEnumConverterFactory` as an example:
+
+```
+package org.springframework.core.convert.support;
+
+final class StringToEnumConverterFactory implements ConverterFactory {
+
+ public Converter getConverter(Class targetType) {
+ return new StringToEnumConverter(targetType);
+ }
+
+ private final class StringToEnumConverter implements Converter