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.
#### 1.10.3. Automatically Detecting Classes and Registering Bean Definitions
Spring can automatically detect stereotyped classes and register corresponding`BeanDefinition` instances with the `ApplicationContext`. For example, the following two classes
are eligible for such autodetection:
Java
```
@Service
public class SimpleMovieLister {
private MovieFinder movieFinder;
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
```
Kotlin
```
@Service
class SimpleMovieLister(private val movieFinder: MovieFinder)
```
Java
```
@Repository
public class JpaMovieFinder implements MovieFinder {
// implementation elided for clarity
}
```
Kotlin
```
@Repository
class JpaMovieFinder : MovieFinder {
// implementation elided for clarity
}
```
To autodetect these classes and register the corresponding beans, you need to add`@ComponentScan` to your `@Configuration` class, where the `basePackages` attribute
is a common parent package for the two classes. (Alternatively, you can specify a
comma- or semicolon- or space-separated list that includes the parent package of each class.)
Java
```
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
// ...
}
```
Kotlin
```
@Configuration
@ComponentScan(basePackages = ["org.example"])
class AppConfig {
// ...
}
```
| |For brevity, the preceding example could have used the `value` attribute of the
annotation (that is, `@ComponentScan("org.example")`).|
|---|------------------------------------------------------------------------------------------------------------------------------------------|
The following alternative uses XML:
```
entries in the classpath. When you build JARs with Ant, make sure that you do not
activate the files-only switch of the JAR task. Also, classpath directories may not be
exposed based on security policies in some environments — for example, standalone apps on
JDK 1.7.0\_45 and higher (which requires 'Trusted-Library' setup in your manifests — see[https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources](https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources)).
On JDK 9’s module path (Jigsaw), Spring’s classpath scanning generally works as expected.
However, make sure that your component classes are exported in your `module-info`descriptors. If you expect Spring to invoke non-public members of your classes, make
sure that they are 'opened' (that is, that they use an `opens` declaration instead of an`exports` declaration in your `module-info` descriptor).|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Furthermore, the `AutowiredAnnotationBeanPostProcessor` and`CommonAnnotationBeanPostProcessor` are both implicitly included when you use the
component-scan element. That means that the two components are autodetected and
wired together — all without any bean configuration metadata provided in XML.
| |You can disable the registration of `AutowiredAnnotationBeanPostProcessor` and`CommonAnnotationBeanPostProcessor` by including the `annotation-config` attribute
with a value of `false`.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.10.4. Using Filters to Customize Scanning
By default, classes annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,`@Configuration`, or a custom annotation that itself is annotated with `@Component` are
the only detected candidate components. However, you can modify and extend this behavior
by applying custom filters. Add them as `includeFilters` or `excludeFilters` attributes of
the `@ComponentScan` annotation (or as `
annotation or by providing `use-default-filters="false"` as an attribute of the`
annotated or meta-annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,`@RestController`, or `@Configuration`.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.10.5. Defining Bean Metadata within Components
Spring components can also contribute bean definition metadata to the container. You can do
this with the same `@Bean` annotation used to define bean metadata within `@Configuration`annotated classes. The following example shows how to do so:
Java
```
@Component
public class FactoryMethodComponent {
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void doWork() {
// Component method implementation omitted
}
}
```
Kotlin
```
@Component
class FactoryMethodComponent {
@Bean
@Qualifier("public")
fun publicInstance() = TestBean("publicInstance")
fun doWork() {
// Component method implementation omitted
}
}
```
The preceding class is a Spring component that has application-specific code in its`doWork()` method. However, it also contributes a bean definition that has a factory
method referring to the method `publicInstance()`. The `@Bean` annotation identifies the
factory method and other bean definition properties, such as a qualifier value through
the `@Qualifier` annotation. Other method-level annotations that can be specified are`@Scope`, `@Lazy`, and custom qualifier annotations.
| |In addition to its role for component initialization, you can also place the `@Lazy`annotation on injection points marked with `@Autowired` or `@Inject`. In this context,
it leads to the injection of a lazy-resolution proxy. However, such a proxy approach
is rather limited. For sophisticated lazy interactions, in particular in combination
with optional dependencies, we recommend `ObjectProvider
creating their containing configuration class as an instance. This makes particular
sense when defining post-processor beans (for example, of type `BeanFactoryPostProcessor`or `BeanPostProcessor`), since such beans get initialized early in the container
lifecycle and should avoid triggering other parts of the configuration at that point.
Calls to static `@Bean` methods never get intercepted by the container, not even within`@Configuration` classes (as described earlier in this section), due to technical
limitations: CGLIB subclassing can override only non-static methods. As a consequence,
a direct call to another `@Bean` method has standard Java semantics, resulting
in an independent instance being returned straight from the factory method itself.
The Java language visibility of `@Bean` methods does not have an immediate impact on
the resulting bean definition in Spring’s container. You can freely declare your
factory methods as you see fit in non-`@Configuration` classes and also for static
methods anywhere. However, regular `@Bean` methods in `@Configuration` classes need
to be overridable — that is, they must not be declared as `private` or `final`.
`@Bean` methods are also discovered on base classes of a given component or
configuration class, as well as on Java 8 default methods declared in interfaces
implemented by the component or configuration class. This allows for a lot of
flexibility in composing complex configuration arrangements, with even multiple
inheritance being possible through Java 8 default methods as of Spring 4.2.
Finally, a single class may hold multiple `@Bean` methods for the same
bean, as an arrangement of multiple factory methods to use depending on available
dependencies at runtime. This is the same algorithm as for choosing the “greediest”
constructor or factory method in other configuration scenarios: The variant with
the largest number of satisfiable dependencies is picked at construction time,
analogous to how the container selects between multiple `@Autowired` constructors.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.10.6. Naming Autodetected Components
When a component is autodetected as part of the scanning process, its bean name is
generated by the `BeanNameGenerator` strategy known to that scanner. By default, any
Spring stereotype annotation (`@Component`, `@Repository`, `@Service`, and`@Controller`) that contains a name `value` thereby provides that name to the
corresponding bean definition.
If such an annotation contains no name `value` or for any other detected component
(such as those discovered by custom filters), the default bean name generator returns
the uncapitalized non-qualified class name. For example, if the following component
classes were detected, the names would be `myMovieLister` and `movieFinderImpl`:
Java
```
@Service("myMovieLister")
public class SimpleMovieLister {
// ...
}
```
Kotlin
```
@Service("myMovieLister")
class SimpleMovieLister {
// ...
}
```
Java
```
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
```
Kotlin
```
@Repository
class MovieFinderImpl : MovieFinder {
// ...
}
```
If you do not want to rely on the default bean-naming strategy, you can provide a custom
bean-naming strategy. First, implement the[`BeanNameGenerator`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/support/BeanNameGenerator.html)interface, and be sure to include a default no-arg constructor. Then, provide the fully
qualified class name when configuring the scanner, as the following example annotation
and bean definition show.
| |If you run into naming conflicts due to multiple autodetected components having the
same non-qualified class name (i.e., classes with identical names but residing in
different packages), you may need to configure a `BeanNameGenerator` that defaults to the
fully qualified class name for the generated bean name. As of Spring Framework 5.2.3, the`FullyQualifiedAnnotationBeanNameGenerator` located in package`org.springframework.context.annotation` can be used for such purposes.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Java
```
@Configuration
@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
public class AppConfig {
// ...
}
```
Kotlin
```
@Configuration
@ComponentScan(basePackages = ["org.example"], nameGenerator = MyNameGenerator::class)
class AppConfig {
// ...
}
```
```
components) or the factory method (for `@Bean` methods). In contrast to XML bean
definitions, there is no notion of bean definition inheritance, and inheritance
hierarchies at the class level are irrelevant for metadata purposes.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
For details on web-specific scopes such as “request” or “session” in a Spring context,
see [Request, Session, Application, and WebSocket Scopes](#beans-factory-scopes-other). As with the pre-built annotations for those scopes,
you may also compose your own scoping annotations by using Spring’s meta-annotation
approach: for example, a custom annotation meta-annotated with `@Scope("prototype")`,
possibly also declaring a custom scoped-proxy mode.
| |To provide a custom strategy for scope resolution rather than relying on the
annotation-based approach, you can implement the[`ScopeMetadataResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/ScopeMetadataResolver.html)interface. Be sure to include a default no-arg constructor. Then you can provide the
fully qualified class name when configuring the scanner, as the following example of both
an annotation and a bean definition shows:|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Java
```
@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
// ...
}
```
Kotlin
```
@Configuration
@ComponentScan(basePackages = ["org.example"], scopeResolver = MyScopeResolver::class)
class AppConfig {
// ...
}
```
```
bound to the class definition itself, while the use of XML allows for multiple beans
of the same type to provide variations in their qualifier metadata, because that
metadata is provided per-instance rather than per-class.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.10.9. Generating an Index of Candidate Components
While classpath scanning is very fast, it is possible to improve the startup performance
of large applications by creating a static list of candidates at compilation time. In this
mode, all modules that are targets of component scanning must use this mechanism.
| |Your existing `@ComponentScan` or `
unchanged to request the context to scan candidates in certain packages. When the`ApplicationContext` detects such an index, it automatically uses it rather than scanning
the classpath.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
To generate the index, add an additional dependency to each module that contains
components that are targets for component scan directives. The following example shows
how to do so with Maven:
```
registered as an annotation processor to make sure the index is up-to-date when
candidate components are updated.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |The index is enabled automatically when a `META-INF/spring.components` file is found
on the classpath. If an index is partially available for some libraries (or use cases)
but could not be built for the whole application, you can fall back to a regular classpath
arrangement (as though no index were present at all) by setting `spring.index.ignore` to`true`, either as a JVM system property or via the[`SpringProperties`](appendix.html#appendix-spring-properties) mechanism.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 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:
```
```|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.11.1. Dependency Injection with `@Inject` and `@Named`
Instead of `@Autowired`, you can use `@javax.inject.Inject` as follows:
Java
```
import javax.inject.Inject;
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
public void listMovies() {
this.movieFinder.findMovies(...);
// ...
}
}
```
Kotlin
```
import javax.inject.Inject
class SimpleMovieLister {
@Inject
lateinit var movieFinder: MovieFinder
fun listMovies() {
movieFinder.findMovies(...)
// ...
}
}
```
As with `@Autowired`, you can use `@Inject` at the field level, method level
and constructor-argument level. Furthermore, you may declare your injection point as a`Provider`, allowing for on-demand access to beans of shorter scopes or lazy access to
other beans through a `Provider.get()` call. The following example offers a variant of the
preceding example:
Java
```
import javax.inject.Inject;
import javax.inject.Provider;
public class SimpleMovieLister {
private Provider
custom component annotations.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 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. |
### 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)
#### 1.12.1. Basic Concepts: `@Bean` and `@Configuration`
The central artifacts in Spring’s new Java-configuration support are`@Configuration`-annotated classes and `@Bean`-annotated methods.
The `@Bean` annotation is used to indicate that a method instantiates, configures, and
initializes a new object to be managed by the Spring IoC container. For those familiar
with Spring’s `
Spring’s `context:` namespace, shown in the following example:
```
```|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
In the preceding example, the `com.acme` package is scanned to look for any`@Component`-annotated classes, and those classes are registered as Spring bean
definitions within the container. `AnnotationConfigApplicationContext` exposes the`scan(String…)` method to allow for the same component-scanning functionality, as the
following example shows:
Java
```
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
```
Kotlin
```
fun main() {
val ctx = AnnotationConfigApplicationContext()
ctx.scan("com.acme")
ctx.refresh()
val myService = ctx.getBean
assuming that `AppConfig` is declared within the `com.acme` package (or any package
underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean`methods are processed and registered as bean definitions within the container.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### Support for Web Applications with `AnnotationConfigWebApplicationContext` #####
A `WebApplicationContext` variant of `AnnotationConfigApplicationContext` is available
with `AnnotationConfigWebApplicationContext`. You can use this implementation when
configuring the Spring `ContextLoaderListener` servlet listener, Spring MVC`DispatcherServlet`, and so forth. The following `web.xml` snippet configures a typical
Spring MVC web application (note the use of the `contextClass` context-param and
init-param):
```
alternative to `AnnotationConfigWebApplicationContext`. See the[`GenericWebApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/context/support/GenericWebApplicationContext.html)javadoc for details.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.12.3. Using the `@Bean` Annotation
`@Bean` is a method-level annotation and a direct analog of the XML `
that implement several interfaces or for components potentially referred to by their
implementation type, it is safer to declare the most specific return type possible
(at least as specific as required by the injection points that refer to your bean).|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### 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.
##### 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.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------|
##### Specifying Bean Scope
Spring includes the `@Scope` annotation so that you can specify the scope of a bean.
###### 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 {
// ...
}
}
```
###### `@Scope` and `scoped-proxy`
Spring offers a convenient way of working with scoped dependencies through[scoped proxies](#beans-factory-scopes-other-injection). The easiest way to create
such a proxy when using the XML configuration is the `
is declared within a `@Configuration` class. You cannot declare inter-bean dependencies
by using plain `@Component` classes.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### 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()
}
}
}
```
##### 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.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 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.
##### Using the `@Import` Annotation
Much as the `
classes, analogous to the `AnnotationConfigApplicationContext.register` method.
This is particularly useful if you want to avoid component scanning, by using a few
configuration classes as entry points to explicitly define all your components.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
###### Injecting Dependencies on Imported `@Bean` Definitions
The preceding example works but is simplistic. In most practical scenarios, beans have
dependencies on one another across configuration classes. When using XML, this is not an
issue, because no compiler is involved, and you can declare`ref="someBean"` and trust Spring to work it out during container initialization.
When using `@Configuration` classes, the Java compiler places constraints on
the configuration model, in that references to other beans must be valid Java syntax.
Fortunately, solving this problem is simple. As [we already discussed](#beans-java-dependencies),
a `@Bean` method can have an arbitrary number of parameters that describe the bean
dependencies. Consider the following more real-world scenario with several `@Configuration`classes, each depending on beans declared in the others:
Java
```
@Configuration
public class ServiceConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
@Configuration
public class RepositoryConfig {
@Bean
public AccountRepository accountRepository(DataSource dataSource) {
return new JdbcAccountRepository(dataSource);
}
}
@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return new DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
// everything wires up across configuration classes...
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
```
Kotlin
```
import org.springframework.beans.factory.getBean
@Configuration
class ServiceConfig {
@Bean
fun transferService(accountRepository: AccountRepository): TransferService {
return TransferServiceImpl(accountRepository)
}
}
@Configuration
class RepositoryConfig {
@Bean
fun accountRepository(dataSource: DataSource): AccountRepository {
return JdbcAccountRepository(dataSource)
}
}
@Configuration
@Import(ServiceConfig::class, RepositoryConfig::class)
class SystemTestConfig {
@Bean
fun dataSource(): DataSource {
// return new DataSource
}
}
fun main() {
val ctx = AnnotationConfigApplicationContext(SystemTestConfig::class.java)
// everything wires up across configuration classes...
val transferService = ctx.getBean
to be injected this way may lead to unexpected early initialization. Whenever possible, resort to
parameter-based injection, as in the preceding example.
Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProcessor` definitions
through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the
instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not
work on the configuration class itself, since it is possible to create it as a bean instance earlier than[`AutowiredAnnotationBeanPostProcessor`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html).|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
The following example shows how one bean can be autowired to another bean:
Java
```
@Configuration
public class ServiceConfig {
@Autowired
private AccountRepository accountRepository;
@Bean
public TransferService transferService() {
return new TransferServiceImpl(accountRepository);
}
}
@Configuration
public class RepositoryConfig {
private final DataSource dataSource;
public RepositoryConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public AccountRepository accountRepository() {
return new JdbcAccountRepository(dataSource);
}
}
@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return new DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
// everything wires up across configuration classes...
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
```
Kotlin
```
import org.springframework.beans.factory.getBean
@Configuration
class ServiceConfig {
@Autowired
lateinit var accountRepository: AccountRepository
@Bean
fun transferService(): TransferService {
return TransferServiceImpl(accountRepository)
}
}
@Configuration
class RepositoryConfig(private val dataSource: DataSource) {
@Bean
fun accountRepository(): AccountRepository {
return JdbcAccountRepository(dataSource)
}
}
@Configuration
@Import(ServiceConfig::class, RepositoryConfig::class)
class SystemTestConfig {
@Bean
fun dataSource(): DataSource {
// return new DataSource
}
}
fun main() {
val ctx = AnnotationConfigApplicationContext(SystemTestConfig::class.java)
// everything wires up across configuration classes...
val transferService = ctx.getBean
Framework 4.3. Note also that there is no need to specify `@Autowired` if the target
bean defines only one constructor.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[]()Fully-qualifying imported beans for ease of navigation
In the preceding scenario, using `@Autowired` works well and provides the desired
modularity, but determining exactly where the autowired bean definitions are declared is
still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do
you know exactly where the `@Autowired AccountRepository` bean is declared? It is not
explicit in the code, and this may be just fine. Remember that the[Spring Tools for Eclipse](https://spring.io/tools) provides tooling that
can render graphs showing how everything is wired, which may be all you need. Also,
your Java IDE can easily find all declarations and uses of the `AccountRepository` type
and quickly show you the location of `@Bean` methods that return that type.
In cases where this ambiguity is not acceptable and you wish to have direct navigation
from within your IDE from one `@Configuration` class to another, consider autowiring the
configuration classes themselves. The following example shows how to do so:
Java
```
@Configuration
public class ServiceConfig {
@Autowired
private RepositoryConfig repositoryConfig;
@Bean
public TransferService transferService() {
// navigate 'through' the config class to the @Bean method!
return new TransferServiceImpl(repositoryConfig.accountRepository());
}
}
```
Kotlin
```
@Configuration
class ServiceConfig {
@Autowired
private lateinit var repositoryConfig: RepositoryConfig
@Bean
fun transferService(): TransferService {
// navigate 'through' the config class to the @Bean method!
return TransferServiceImpl(repositoryConfig.accountRepository())
}
}
```
In the preceding situation, where `AccountRepository` is defined is completely explicit.
However, `ServiceConfig` is now tightly coupled to `RepositoryConfig`. That is the
tradeoff. This tight coupling can be somewhat mitigated by using interface-based or
abstract class-based `@Configuration` classes. Consider the following example:
Java
```
@Configuration
public class ServiceConfig {
@Autowired
private RepositoryConfig repositoryConfig;
@Bean
public TransferService transferService() {
return new TransferServiceImpl(repositoryConfig.accountRepository());
}
}
@Configuration
public interface RepositoryConfig {
@Bean
AccountRepository accountRepository();
}
@Configuration
public class DefaultRepositoryConfig implements RepositoryConfig {
@Bean
public AccountRepository accountRepository() {
return new JdbcAccountRepository(...);
}
}
@Configuration
@Import({ServiceConfig.class, DefaultRepositoryConfig.class}) // import the concrete config!
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
```
Kotlin
```
import org.springframework.beans.factory.getBean
@Configuration
class ServiceConfig {
@Autowired
private lateinit var repositoryConfig: RepositoryConfig
@Bean
fun transferService(): TransferService {
return TransferServiceImpl(repositoryConfig.accountRepository())
}
}
@Configuration
interface RepositoryConfig {
@Bean
fun accountRepository(): AccountRepository
}
@Configuration
class DefaultRepositoryConfig : RepositoryConfig {
@Bean
fun accountRepository(): AccountRepository {
return JdbcAccountRepository(...)
}
}
@Configuration
@Import(ServiceConfig::class, DefaultRepositoryConfig::class) // import the concrete config!
class SystemTestConfig {
@Bean
fun dataSource(): DataSource {
// return DataSource
}
}
fun main() {
val ctx = AnnotationConfigApplicationContext(SystemTestConfig::class.java)
val transferService = ctx.getBean
declaring some of them as `@Lazy` (for creation on first access instead of on startup)
or as `@DependsOn` certain other beans (making sure that specific other beans are
created before the current bean, beyond what the latter’s direct dependencies imply).|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### Conditionally Include `@Configuration` Classes or `@Bean` Methods
It is often useful to conditionally enable or disable a complete `@Configuration` class
or even individual `@Bean` methods, based on some arbitrary system state. One common
example of this is to use the `@Profile` annotation to activate beans only when a specific
profile has been enabled in the Spring `Environment` (see [Bean Definition Profiles](#beans-definition-profiles)for details).
The `@Profile` annotation is actually implemented by using a much more flexible annotation
called [`@Conditional`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Conditional.html).
The `@Conditional` annotation indicates specific`org.springframework.context.annotation.Condition` implementations that should be
consulted before a `@Bean` is registered.
Implementations of the `Condition` interface provide a `matches(…)`method that returns `true` or `false`. For example, the following listing shows the actual`Condition` implementation used for `@Profile`:
Java
```
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// Read the @Profile annotation attributes
MultiValueMap
ever refers to it, and it is unlikely to be explicitly fetched from the container by name.
Similarly, the `DataSource` bean is only ever autowired by type, so an explicit bean `id`is not strictly required.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[]() Using \
JNDI lookups, by using either Spring’s `JndiTemplate`/`JndiLocatorDelegate` helpers or the
straight JNDI `InitialContext` usage shown earlier but not the `JndiObjectFactoryBean`variant, which would force you to declare the return type as the `FactoryBean` type.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
The profile string may contain a simple profile name (for example, `production`) or a
profile expression. A profile expression allows for more complicated profile logic to be
expressed (for example, `production & us-east`). The following operators are supported in
profile expressions:
* `!`: A logical “not” of the profile
* `&`: A logical “and” of the profiles
* `|`: A logical “or” of the profiles
| |You cannot mix the `&` and `|` operators without using parentheses. For example,`production & us-east | eu-central` is not a valid expression. It must be expressed as`production & (us-east | eu-central)`.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
You can use `@Profile` as a [meta-annotation](#beans-meta-annotations) for the purpose
of creating a custom composed annotation. The following example defines a custom`@Production` annotation that you can use as a drop-in replacement for`@Profile("production")`:
Java
```
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("production")
public @interface Production {
}
```
Kotlin
```
@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@Profile("production")
annotation class Production
```
| |If a `@Configuration` class is marked with `@Profile`, all of the `@Bean` methods and`@Import` annotations associated with that class are bypassed unless one or more of
the specified profiles are active. If a `@Component` or `@Configuration` class is marked
with `@Profile({"p1", "p2"})`, that class is not registered or processed unless
profiles 'p1' or 'p2' have been activated. If a given profile is prefixed with the
NOT operator (`!`), the annotated element is registered only if the profile is not
active. For example, given `@Profile({"p1", "!p2"})`, registration will occur if profile
'p1' is active or if profile 'p2' is not active.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
`@Profile` can also be declared at the method level to include only one particular bean
of a configuration class (for example, for alternative variants of a particular bean), as
the following example shows:
Java
```
@Configuration
public class AppConfig {
@Bean("dataSource")
@Profile("development") (1)
public DataSource standaloneDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
@Bean("dataSource")
@Profile("production") (2)
public DataSource jndiDataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
```
|**1**|The `standaloneDataSource` method is available only in the `development` profile.|
|-----|---------------------------------------------------------------------------------|
|**2**| The `jndiDataSource` method is available only in the `production` profile. |
Kotlin
```
@Configuration
class AppConfig {
@Bean("dataSource")
@Profile("development") (1)
fun standaloneDataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build()
}
@Bean("dataSource")
@Profile("production") (2)
fun jndiDataSource() =
InitialContext().lookup("java:comp/env/jdbc/datasource") as DataSource
}
```
|**1**|The `standaloneDataSource` method is available only in the `development` profile.|
|-----|---------------------------------------------------------------------------------|
|**2**| The `jndiDataSource` method is available only in the `production` profile. |
| |With `@Profile` on `@Bean` methods, a special scenario may apply: In the case of
overloaded `@Bean` methods of the same Java method name (analogous to constructor
overloading), a `@Profile` condition needs to be consistently declared on all
overloaded methods. If the conditions are inconsistent, only the condition on the
first declaration among the overloaded methods matters. Therefore, `@Profile` can
not be used to select an overloaded method with a particular argument signature over
another. Resolution between all factory methods for the same bean follows Spring’s
constructor resolution algorithm at creation time.
If you want to define alternative beans with different profile conditions,
use distinct Java method names that point to the same bean name by using the `@Bean` name
attribute, as shown in the preceding example. If the argument signatures are all
the same (for example, all of the variants have no-arg factory methods), this is the only
way to represent such an arrangement in a valid Java class in the first place
(since there can only be one method of a particular name and argument signature).|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### XML Bean Definition Profiles
The XML counterpart is the `profile` attribute of the `
however, to negate a profile by using the `!` operator. It is also possible to apply a logical
“and” by nesting the profiles, as the following example shows:
```
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">
```
In the preceding example, the `dataSource` bean is exposed if both the `production` and`us-east` profiles are active.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### 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"
```
##### 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.
#### 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.
#### 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.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.13.4. Placeholder Resolution in Statements
Historically, the value of placeholders in elements could be resolved only against
JVM system properties or environment variables. This is no longer the case. Because
the `Environment` abstraction is integrated throughout the container, it is easy to
route resolution of placeholders through it. This means that you may configure the
resolution process in any way you like. You can change the precedence of searching through
system properties and environment variables or remove them entirely. You can also add your
own property sources to the mix, as appropriate.
Concretely, the following statement works regardless of where the `customer`property is defined, as long as it is available in the `Environment`:
```
bundles with the same base name, but will only use the first bundle found.
Subsequent message bundles with the same base name are ignored.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |As an alternative to `ResourceBundleMessageSource`, Spring provides a`ReloadableResourceBundleMessageSource` class. This variant supports the same bundle
file format but is more flexible than the standard JDK based`ResourceBundleMessageSource` implementation. In particular, it allows for reading
files from any Spring resource location (not only from the classpath) and supports hot
reloading of bundle property files (while efficiently caching them in between).
See the [`ReloadableResourceBundleMessageSource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html)javadoc for details.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.15.2. Standard and Custom Events
Event handling in the `ApplicationContext` is provided through the `ApplicationEvent`class and the `ApplicationListener` interface. If a bean that implements the`ApplicationListener` interface is deployed into the context, every time an`ApplicationEvent` gets published to the `ApplicationContext`, that bean is notified.
Essentially, this is the standard Observer design pattern.
| |As of Spring 4.2, the event infrastructure has been significantly improved and offers
an [annotation-based model](#context-functionality-events-annotation) as well as the
ability to publish any arbitrary event (that is, an object that does not necessarily
extend from `ApplicationEvent`). When such an object is published, we wrap it in an
event for you.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
The following table describes the standard events that Spring provides:
| Event | Explanation |
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ContextRefreshedEvent` |Published when the `ApplicationContext` is initialized or refreshed (for example, by
using the `refresh()` method on the `ConfigurableApplicationContext` interface).
Here, “initialized” means that all beans are loaded, post-processor beans are detected
and activated, singletons are pre-instantiated, and the `ApplicationContext` object is
ready for use. As long as the context has not been closed, a refresh can be triggered
multiple times, provided that the chosen `ApplicationContext` actually supports such
“hot” refreshes. For example, `XmlWebApplicationContext` supports hot refreshes, but`GenericApplicationContext` does not.|
| `ContextStartedEvent` | Published when the `ApplicationContext` is started by using the `start()` method on the`ConfigurableApplicationContext` interface. Here, “started” means that all `Lifecycle`beans receive an explicit start signal. Typically, this signal is used to restart beans
after an explicit stop, but it may also be used to start components that have not been
configured for autostart (for example, components that have not already started on
initialization). |
| `ContextStoppedEvent` | Published when the `ApplicationContext` is stopped by using the `stop()` method on the`ConfigurableApplicationContext` interface. Here, “stopped” means that all `Lifecycle`beans receive an explicit stop signal. A stopped context may be restarted through a`start()` call. |
| `ContextClosedEvent` | Published when the `ApplicationContext` is being closed by using the `close()` method
on the `ConfigurableApplicationContext` interface or via a JVM shutdown hook. Here,
"closed" means that all singleton beans will be destroyed. Once the context is closed,
it reaches its end of life and cannot be refreshed or restarted. |
| `RequestHandledEvent` | A web-specific event telling all beans that an HTTP request has been serviced. This
event is published after the request is complete. This event is only applicable to
web applications that use Spring’s `DispatcherServlet`. |
|`ServletRequestHandledEvent`| A subclass of `RequestHandledEvent` that adds Servlet-specific context information. |
You can also create and publish your own custom events. The following example shows a
simple class that extends Spring’s `ApplicationEvent` base class:
Java
```
public class BlockedListEvent extends ApplicationEvent {
private final String address;
private final String content;
public BlockedListEvent(Object source, String address, String content) {
super(source);
this.address = address;
this.content = content;
}
// accessor and other methods...
}
```
Kotlin
```
class BlockedListEvent(source: Any,
val address: String,
val content: String) : ApplicationEvent(source)
```
To publish a custom `ApplicationEvent`, call the `publishEvent()` method on an`ApplicationEventPublisher`. Typically, this is done by creating a class that implements`ApplicationEventPublisherAware` and registering it as a Spring bean. The following
example shows such a class:
Java
```
public class EmailService implements ApplicationEventPublisherAware {
private List
within the same application context. However, for more sophisticated enterprise
integration needs, the separately maintained[Spring Integration](https://projects.spring.io/spring-integration/) project provides
complete support for building lightweight,[pattern-oriented](https://www.enterpriseintegrationpatterns.com), event-driven
architectures that build upon the well-known Spring programming model.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### 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.
##### 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.
##### 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...
}
```
##### Generic Events
You can also use generics to further define the structure of your event. Consider using an`EntityCreatedEvent
an event.|
|---|--------------------------------------------------------------------------------------------------|
#### 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.
#### 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.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.15.5. Convenient ApplicationContext Instantiation for Web Applications
You can create `ApplicationContext` instances declaratively by using, for example, a`ContextLoader`. Of course, you can also create `ApplicationContext` instances
programmatically by using one of the `ApplicationContext` implementations.
You can register an `ApplicationContext` by using the `ContextLoaderListener`, as the
following example shows:
```
to the outside world, not even to other modules of the same application. Interaction with a
RAR-based `ApplicationContext` usually occurs through JMS destinations that it shares with
other modules. A RAR-based `ApplicationContext` may also, for example, schedule some jobs
or react to new files in the file system (or the like). If it needs to allow synchronous
access from the outside, it could (for example) export RMI endpoints, which may be used
by other application modules on the same machine.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 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.
#### 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.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## 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)
### 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.
### 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.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 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.
#### 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`.
#### 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.
#### 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`.
#### 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.
#### 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.
#### 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.
#### 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`.
### 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`. |
### 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`.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 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`.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 2.7. Resources as Dependencies
If the bean itself is going to determine and supply the resource path through some sort
of dynamic process, it probably makes sense for the bean to use the `ResourceLoader` or`ResourcePatternResolver` interface to load resources. For example, consider the loading
of a template of some sort, where the specific resource that is needed depends on the
role of the user. If the resources are static, it makes sense to eliminate the use of the`ResourceLoader` interface (or `ResourcePatternResolver` interface) completely, have the
bean expose the `Resource` properties it needs, and expect them to be injected into it.
What makes it trivial to then inject these properties is that all application contexts
register and use a special JavaBeans `PropertyEditor`, which can convert `String` paths
to `Resource` objects. For example, the following `MyBean` class has a `template`property of type `Resource`.
Java
```
package example;
public class MyBean {
private Resource template;
public setTemplate(Resource template) {
this.template = template;
}
// ...
}
```
Kotlin
```
class MyBean(var template: Resource)
```
In an XML configuration file, the `template` property can be configured with a simple
string for that resource, as the following example shows:
```
simple test to check if `classpath*` works is to use the `ClassLoader` to load a file from
within a jar on the classpath:`getClass().getClassLoader().getResources("
files that have the same name but reside in two different locations — for example, files
with the same name and same path but in different jars on the classpath. In case an
inappropriate result is returned, check the application server documentation for settings
that might affect the `ClassLoader` behavior.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
You can also combine the `classpath*:` prefix with a `PathMatcher` pattern in the
rest of the location path (for example, `classpath*:META-INF/*-beans.xml`). In this
case, the resolution strategy is fairly simple: A `ClassLoader.getResources()` call is
used on the last non-wildcard path segment to get all the matching resources in the
class loader hierarchy and then, off each resource, the same `PathMatcher` resolution
strategy described earlier is used for the wildcard subpath.
##### 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`.
#### 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")
```
## 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.
### 3.1. Validation by Using Spring’s Validator Interface
Spring features a `Validator` interface that you can use to validate objects. The`Validator` interface works by using an `Errors` object so that, while validating,
validators can report validation failures to the `Errors` object.
Consider the following example of a small data object:
Java
```
public class Person {
private String name;
private int age;
// the usual getters and setters...
}
```
Kotlin
```
class Person(val name: String, val age: Int)
```
The next example provides validation behavior for the `Person` class by implementing the
following two methods of the `org.springframework.validation.Validator` interface:
* `supports(Class)`: Can this `Validator` validate instances of the supplied `Class`?
* `validate(Object, org.springframework.validation.Errors)`: Validates the given object
and, in case of validation errors, registers those with the given `Errors` object.
Implementing a `Validator` is fairly straightforward, especially when you know of the`ValidationUtils` helper class that the Spring Framework also provides. The following
example implements `Validator` for `Person` instances:
Java
```
public class PersonValidator implements Validator {
/**
* This Validator validates only Person instances
*/
public boolean supports(Class clazz) {
return Person.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
Person p = (Person) obj;
if (p.getAge() < 0) {
e.rejectValue("age", "negativevalue");
} else if (p.getAge() > 110) {
e.rejectValue("age", "too.darn.old");
}
}
}
```
Kotlin
```
class PersonValidator : Validator {
/**
* This Validator validates only Person instances
*/
override fun supports(clazz: Class<*>): Boolean {
return Person::class.java == clazz
}
override fun validate(obj: Any, e: Errors) {
ValidationUtils.rejectIfEmpty(e, "name", "name.empty")
val p = obj as Person
if (p.age < 0) {
e.rejectValue("age", "negativevalue")
} else if (p.age > 110) {
e.rejectValue("age", "too.darn.old")
}
}
}
```
The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to
reject the `name` property if it is `null` or the empty string. Have a look at the[`ValidationUtils`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/ValidationUtils.html) javadoc
to see what functionality it provides besides the example shown previously.
While it is certainly possible to implement a single `Validator` class to validate each
of the nested objects in a rich object, it may be better to encapsulate the validation
logic for each nested class of object in its own `Validator` implementation. A simple
example of a “rich” object would be a `Customer` that is composed of two `String`properties (a first and a second name) and a complex `Address` object. `Address` objects
may be used independently of `Customer` objects, so a distinct `AddressValidator`has been implemented. If you want your `CustomerValidator` to reuse the logic contained
within the `AddressValidator` class without resorting to copy-and-paste, you can
dependency-inject or instantiate an `AddressValidator` within your `CustomerValidator`,
as the following example shows:
Java
```
public class CustomerValidator implements Validator {
private final Validator addressValidator;
public CustomerValidator(Validator addressValidator) {
if (addressValidator == null) {
throw new IllegalArgumentException("The supplied [Validator] is " +
"required and must not be null.");
}
if (!addressValidator.supports(Address.class)) {
throw new IllegalArgumentException("The supplied [Validator] must " +
"support the validation of [Address] instances.");
}
this.addressValidator = addressValidator;
}
/**
* This Validator validates Customer instances, and any subclasses of Customer too
*/
public boolean supports(Class clazz) {
return Customer.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
Customer customer = (Customer) target;
try {
errors.pushNestedPath("address");
ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
} finally {
errors.popNestedPath();
}
}
}
```
Kotlin
```
class CustomerValidator(private val addressValidator: Validator) : Validator {
init {
if (addressValidator == null) {
throw IllegalArgumentException("The supplied [Validator] is required and must not be null.")
}
if (!addressValidator.supports(Address::class.java)) {
throw IllegalArgumentException("The supplied [Validator] must support the validation of [Address] instances.")
}
}
/*
* This Validator validates Customer instances, and any subclasses of Customer too
*/
override fun supports(clazz: Class<>): Boolean {
return Customer::class.java.isAssignableFrom(clazz)
}
override fun validate(target: Any, errors: Errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required")
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required")
val customer = target as Customer
try {
errors.pushNestedPath("address")
ValidationUtils.invokeValidator(this.addressValidator, customer.address, errors)
} finally {
errors.popNestedPath()
}
}
}
```
Validation errors are reported to the `Errors` object passed to the validator. In the case
of Spring Web MVC, you can use the `
(for example) the `getAccount().setName()` or `getAccount().getName()` methods.|
| `account[2]` | Indicates the *third* element of the indexed property `account`. Indexed properties
can be of type `array`, `list`, or other naturally ordered collection. |
|`account[COMPANYNAME]`| Indicates the value of the map entry indexed by the `COMPANYNAME` key of the `account` `Map`property. |
(This next section is not vitally important to you if you do not plan to work with
the `BeanWrapper` directly. If you use only the `DataBinder` and the `BeanFactory`and their default implementations, you should skip ahead to the[section on `PropertyEditors`](#beans-beans-conversion).)
The following two example classes use the `BeanWrapper` to get and set
properties:
Java
```
public class Company {
private String name;
private Employee managingDirector;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Employee getManagingDirector() {
return this.managingDirector;
}
public void setManagingDirector(Employee managingDirector) {
this.managingDirector = managingDirector;
}
}
```
Kotlin
```
class Company {
var name: String? = null
var managingDirector: Employee? = null
}
```
Java
```
public class Employee {
private String name;
private float salary;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
}
```
Kotlin
```
class Employee {
var name: String? = null
var salary: Float? = null
}
```
The following code snippets show some examples of how to retrieve and manipulate some of
the properties of instantiated `Company`s and `Employee`s:
Java
```
BeanWrapper company = new BeanWrapperImpl(new Company());
// setting the company name..
company.setPropertyValue("name", "Some Company Inc.");
// ... can also be done like this:
PropertyValue value = new PropertyValue("name", "Some Company Inc.");
company.setPropertyValue(value);
// ok, let's create the director and tie it to the company:
BeanWrapper jim = new BeanWrapperImpl(new Employee());
jim.setPropertyValue("name", "Jim Stravinsky");
company.setPropertyValue("managingDirector", jim.getWrappedInstance());
// retrieving the salary of the managingDirector through the company
Float salary = (Float) company.getPropertyValue("managingDirector.salary");
```
Kotlin
```
val company = BeanWrapperImpl(Company())
// setting the company name..
company.setPropertyValue("name", "Some Company Inc.")
// ... can also be done like this:
val value = PropertyValue("name", "Some Company Inc.")
company.setPropertyValue(value)
// ok, let's create the director and tie it to the company:
val jim = BeanWrapperImpl(Employee())
jim.setPropertyValue("name", "Jim Stravinsky")
company.setPropertyValue("managingDirector", jim.wrappedInstance)
// retrieving the salary of the managingDirector through the company
val salary = company.getPropertyValue("managingDirector.salary") as Float?
```
#### 3.3.2. Built-in `PropertyEditor` Implementations
Spring uses the concept of a `PropertyEditor` to effect the conversion between an`Object` and a `String`. It can be handy
to represent properties in a different way than the object itself. For example, a `Date`can be represented in a human readable way (as the `String`: `'2007-14-09'`), while
we can still convert the human readable form back to the original date (or, even
better, convert any date entered in a human readable form back to `Date` objects). This
behavior can be achieved by registering custom editors of type`java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,
alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it
the knowledge of how to convert properties to the desired type. For more about`PropertyEditor`, see [the javadoc of the `java.beans` package from Oracle](https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html).
A couple of examples where property editing is used in Spring:
* Setting properties on beans is done by using `PropertyEditor` implementations.
When you use `String` as the value of a property of some bean that you declare
in an XML file, Spring (if the setter of the corresponding property has a `Class`parameter) uses `ClassEditor` to try to resolve the parameter to a `Class` object.
* Parsing HTTP request parameters in Spring’s MVC framework is done by using all kinds
of `PropertyEditor` implementations that you can manually bind in all subclasses of the`CommandController`.
Spring has a number of built-in `PropertyEditor` implementations to make life easy.
They are all located in the `org.springframework.beans.propertyeditors`package. Most, (but not all, as indicated in the following table) are, by default, registered by`BeanWrapperImpl`. Where the property editor is configurable in some fashion, you can
still register your own variant to override the default one. The following table describes
the various `PropertyEditor` implementations that Spring provides:
| Class | Explanation |
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`ByteArrayPropertyEditor`| Editor for byte arrays. Converts strings to their corresponding byte
representations. Registered by default by `BeanWrapperImpl`. |
| `ClassEditor` | Parses Strings that represent classes to actual classes and vice-versa. When a
class is not found, an `IllegalArgumentException` is thrown. By default, registered by`BeanWrapperImpl`. |
| `CustomBooleanEditor` | Customizable property editor for `Boolean` properties. By default, registered by`BeanWrapperImpl` but can be overridden by registering a custom instance of it as a
custom editor. |
|`CustomCollectionEditor` | Property editor for collections, converting any source `Collection` to a given target`Collection` type. |
| `CustomDateEditor` | Customizable property editor for `java.util.Date`, supporting a custom `DateFormat`. NOT
registered by default. Must be user-registered with the appropriate format as needed. |
| `CustomNumberEditor` | Customizable property editor for any `Number` subclass, such as `Integer`, `Long`, `Float`, or`Double`. By default, registered by `BeanWrapperImpl` but can be overridden by
registering a custom instance of it as a custom editor. |
| `FileEditor` | Resolves strings to `java.io.File` objects. By default, registered by`BeanWrapperImpl`. |
| `InputStreamEditor` |One-way property editor that can take a string and produce (through an
intermediate `ResourceEditor` and `Resource`) an `InputStream` so that `InputStream`properties may be directly set as strings. Note that the default usage does not close
the `InputStream` for you. By default, registered by `BeanWrapperImpl`.|
| `LocaleEditor` | Can resolve strings to `Locale` objects and vice-versa (the string format is`[language]_[country]_[variant]`, same as the `toString()` method of`Locale`). Also accepts spaces as separators, as an alternative to underscores.
By default, registered by `BeanWrapperImpl`. |
| `PatternEditor` | Can resolve strings to `java.util.regex.Pattern` objects and vice-versa. |
| `PropertiesEditor` | Can convert strings (formatted with the format defined in the javadoc of the`java.util.Properties` class) to `Properties` objects. By default, registered
by `BeanWrapperImpl`. |
| `StringTrimmerEditor` | Property editor that trims strings. Optionally allows transforming an empty string
into a `null` value. NOT registered by default — must be user-registered. |
| `URLEditor` | Can resolve a string representation of a URL to an actual `URL` object.
By default, registered by `BeanWrapperImpl`. |
Spring uses the `java.beans.PropertyEditorManager` to set the search path for property
editors that might be needed. The search path also includes `sun.bean.editors`, which
includes `PropertyEditor` implementations for types such as `Font`, `Color`, and most of
the primitive types. Note also that the standard JavaBeans infrastructure
automatically discovers `PropertyEditor` classes (without you having to register them
explicitly) if they are in the same package as the class they handle and have the same
name as that class, with `Editor` appended. For example, one could have the following
class and package structure, which would be sufficient for the `SomethingEditor` class to be
recognized and used as the `PropertyEditor` for `Something`-typed properties.
```
com
chank
pop
Something
SomethingEditor // the PropertyEditor for the Something class
```
Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well
(described to some extent[here](https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html)). The
following example uses the `BeanInfo` mechanism to explicitly register one or more`PropertyEditor` instances with the properties of an associated class:
```
com
chank
pop
Something
SomethingBeanInfo // the BeanInfo for the Something class
```
The following Java source code for the referenced `SomethingBeanInfo` class
associates a `CustomNumberEditor` with the `age` property of the `Something` class:
Java
```
public class SomethingBeanInfo extends SimpleBeanInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
final PropertyEditor numberPE = new CustomNumberEditor(Integer.class, true);
PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", Something.class) {
@Override
public PropertyEditor createPropertyEditor(Object bean) {
return numberPE;
}
};
return new PropertyDescriptor[] { ageDescriptor };
}
catch (IntrospectionException ex) {
throw new Error(ex.toString());
}
}
}
```
Kotlin
```
class SomethingBeanInfo : SimpleBeanInfo() {
override fun getPropertyDescriptors(): Array {
T convert(S source);
}
```
To create your own converter, implement the `Converter` interface and parameterize `S`as the type you are converting from and `T` as the type you are converting to. You can also transparently apply such a
converter if a collection or array of `S` needs to be
converted to an array or collection of `T`, provided that a delegating array or collection
converter has been registered as well (which `DefaultConversionService` does by default).
For each call to `convert(S)`, the source argument is guaranteed to not be null. Your`Converter` may throw any unchecked exception if conversion fails. Specifically, it should throw an`IllegalArgumentException` to report an invalid source value.
Take care to ensure that your `Converter` implementation is thread-safe.
Several converter implementations are provided in the `core.convert.support` package as
a convenience. These include converters from strings to numbers and other common types.
The following listing shows the `StringToInteger` class, which is a typical `Converter` implementation:
```
package org.springframework.core.convert.support;
final class StringToInteger implements Converter {
getConverter(Class
it only when you need it. Favor `Converter` or `ConverterFactory` for basic type
conversion needs.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
##### Using `ConditionalGenericConverter`
Sometimes, you want a `Converter` to run only if a specific condition holds true. For
example, you might want to run a `Converter` only if a specific annotation is present
on the target field, or you might want to run a `Converter` only if a specific method
(such as a `static valueOf` method) is defined on the target class.`ConditionalGenericConverter` is the union of the `GenericConverter` and`ConditionalConverter` interfaces that lets you define such custom matching criteria:
```
public interface ConditionalConverter {
boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}
public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
}
```
A good example of a `ConditionalGenericConverter` is an `IdToEntityConverter` that converts
between a persistent entity identifier and an entity reference. Such an `IdToEntityConverter`might match only if the target entity type declares a static finder method (for example,`findAccount(Long)`). You might perform such a finder method check in the implementation of`matches(TypeDescriptor, TypeDescriptor)`.
#### 3.4.4. The `ConversionService` API
`ConversionService` defines a unified API for executing type conversion logic at
runtime. Converters are often run behind the following facade interface:
```
package org.springframework.core.convert;
public interface ConversionService {
boolean canConvert(Class> sourceType, Class> targetType);
system is used.|
|---|------------------------------------------------------------------------------------------------------------|
To register a default `ConversionService` with Spring, add the following bean definition
with an `id` of `conversionService`:
```