2017-10-17 15:44:13 +02:00

6932 lines
253 KiB
Plaintext

[[boot-features]]
= Spring Boot features
[partintro]
--
This section dives into the details of Spring Boot. Here you can learn about the key
features that you will want to use and customize. If you haven't already, you might want
to read the _<<getting-started.adoc#getting-started>>_ and
_<<using-spring-boot.adoc#using-boot>>_ sections so that you have a good grounding
of the basics.
--
[[boot-features-spring-application]]
== SpringApplication
The `SpringApplication` class provides a convenient way to bootstrap a Spring application
that will be started from a `main()` method. In many situations you can just delegate to
the static `SpringApplication.run` method:
[source,java,indent=0]
----
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
----
When your application starts you should see something similar to the following:
[indent=0,subs="attributes"]
----
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v{spring-boot-version}
2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912 INFO 41370 --- [ main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501 INFO 41370 --- [ main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658)
----
By default `INFO` logging messages will be shown, including some relevant startup details
such as the user that launched the application.
[boot-features-startup-failure]
=== Startup failure
If your application fails to start, registered `FailureAnalyzers` get a chance to provide
a dedicated error message and a concrete action to fix the problem. For instance if you
start a web application on port `8080` and that port is already in use, you should see
something similar to the following:
[indent=0]
----
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
----
NOTE: Spring Boot provides numerous `FailureAnalyzer` implementations and you can
<<howto.adoc#howto-failure-analyzer,add your own>> very easily.
If no failure analyzers are able to handle the exception, you can still display the full
auto-configuration report to better understand what went wrong. To do so you need to
<<boot-features-external-config,enable the `debug` property>> or
<<boot-features-custom-log-levels,enable `DEBUG` logging>> for
`org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer`.
For instance, if you are running your application using `java -jar` you can enable the
`debug` property as follows:
[indent=0,subs="attributes"]
----
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
----
[[boot-features-banner]]
=== Customizing the Banner
The banner that is printed on start up can be changed by adding a `banner.txt` file
to your classpath, or by setting `banner.location` to the location of such a file.
If the file has an unusual encoding you can set `banner.charset` (default is `UTF-8`).
In addition to a text file, you can also add a `banner.gif`, `banner.jpg` or `banner.png`
image file to your classpath, or set a `banner.image.location` property. Images will be
converted into an ASCII art representation and printed above any text banner.
Inside your `banner.txt` file you can use any of the following placeholders:
.Banner variables
|===
| Variable | Description
|`${application.version}`
|The version number of your application as declared in `MANIFEST.MF`. For example
`Implementation-Version: 1.0` is printed as `1.0`.
|`${application.formatted-version}`
|The version number of your application as declared in `MANIFEST.MF` formatted for
display (surrounded with brackets and prefixed with `v`). For example `(v1.0)`.
|`${spring-boot.version}`
|The Spring Boot version that you are using. For example `{spring-boot-version}`.
|`${spring-boot.formatted-version}`
|The Spring Boot version that you are using formatted for display (surrounded with
brackets and prefixed with `v`). For example `(v{spring-boot-version})`.
|`${Ansi.NAME}` (or `${AnsiColor.NAME}`, `${AnsiBackground.NAME}`, `${AnsiStyle.NAME}`)
|Where `NAME` is the name of an ANSI escape code. See
{sc-spring-boot}/ansi/AnsiPropertySource.{sc-ext}[`AnsiPropertySource`] for details.
|`${application.title}`
|The title of your application as declared in `MANIFEST.MF`. For example
`Implementation-Title: MyApp` is printed as `MyApp`.
|===
TIP: The `SpringApplication.setBanner(...)` method can be used if you want to generate
a banner programmatically. Use the `org.springframework.boot.Banner` interface and
implement your own `printBanner()` method.
You can also use the `spring.main.banner-mode` property to determine if the banner has
to be printed on `System.out` (`console`), using the configured logger (`log`) or not
at all (`off`).
The printed banner will be registered as a singleton bean under the name
`springBootBanner`.
[NOTE]
====
YAML maps `off` to `false` so make sure to add quotes if you want to disable the
banner in your application.
[source,yaml,indent=0]
----
spring:
main:
banner-mode: "off"
----
====
[[boot-features-customizing-spring-application]]
=== Customizing SpringApplication
If the `SpringApplication` defaults aren't to your taste you can instead create a local
instance and customize it. For example, to turn off the banner you would write:
[source,java,indent=0]
----
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
----
NOTE: The constructor arguments passed to `SpringApplication` are configuration sources
for spring beans. In most cases these will be references to `@Configuration` classes, but
they could also be references to XML configuration or to packages that should be scanned.
It is also possible to configure the `SpringApplication` using an `application.properties`
file. See _<<boot-features-external-config>>_ for details.
For a complete list of the configuration options, see the
{dc-spring-boot}/SpringApplication.{dc-ext}[`SpringApplication` Javadoc].
[[boot-features-fluent-builder-api]]
=== Fluent builder API
If you need to build an `ApplicationContext` hierarchy (multiple contexts with a
parent/child relationship), or if you just prefer using a '`fluent`' builder API, you
can use the `SpringApplicationBuilder`.
The `SpringApplicationBuilder` allows you to chain together multiple method calls, and
includes `parent` and `child` methods that allow you to create a hierarchy.
For example:
[source,java,indent=0]
----
include::{code-examples}/builder/SpringApplicationBuilderExample.java[tag=hierarchy]
----
NOTE: There are some restrictions when creating an `ApplicationContext` hierarchy, e.g.
Web components *must* be contained within the child context, and the same `Environment`
will be used for both parent and child contexts. See the
{dc-spring-boot}/builder/SpringApplicationBuilder.{dc-ext}[`SpringApplicationBuilder`
Javadoc] for full details.
[[boot-features-application-events-and-listeners]]
=== Application events and listeners
In addition to the usual Spring Framework events, such as
{spring-javadoc}/context/event/ContextRefreshedEvent.{dc-ext}[`ContextRefreshedEvent`],
a `SpringApplication` sends some additional application events.
[NOTE]
====
Some events are actually triggered before the `ApplicationContext` is created so you
cannot register a listener on those as a `@Bean`. You can register them via the
`SpringApplication.addListeners(...)` or `SpringApplicationBuilder.listeners(...)`
methods.
If you want those listeners to be registered automatically regardless of the way the
application is created you can add a `META-INF/spring.factories` file to your project
and reference your listener(s) using the `org.springframework.context.ApplicationListener`
key.
[indent=0]
----
org.springframework.context.ApplicationListener=com.example.project.MyListener
----
====
Application events are sent in the following order, as your application runs:
. An `ApplicationStartingEvent` is sent at the start of a run, but before any
processing except the registration of listeners and initializers.
. An `ApplicationEnvironmentPreparedEvent` is sent when the `Environment` to be used in
the context is known, but before the context is created.
. An `ApplicationPreparedEvent` is sent just before the refresh is started, but after bean
definitions have been loaded.
. An `ApplicationReadyEvent` is sent after the refresh and any related callbacks have
been processed to indicate the application is ready to service requests.
. An `ApplicationFailedEvent` is sent if there is an exception on startup.
TIP: You often won't need to use application events, but it can be handy to know that they
exist. Internally, Spring Boot uses events to handle a variety of tasks.
[[boot-features-web-environment]]
=== Web environment
A `SpringApplication` will attempt to create the right type of `ApplicationContext` on
your behalf. By default, an `AnnotationConfigApplicationContext` or
`AnnotationConfigServletWebServerApplicationContext` will be used, depending on whether you
are developing a web application or not.
The algorithm used to determine a '`web environment`' is fairly simplistic (based on the
presence of a few classes). You can use `setWebEnvironment(boolean webEnvironment)` if
you need to override the default.
It is also possible to take complete control of the `ApplicationContext` type that will
be used by calling `setApplicationContextClass(...)`.
TIP: It is often desirable to call `setWebEnvironment(false)` when using
`SpringApplication` within a JUnit test.
[[boot-features-application-arguments]]
=== Accessing application arguments
If you need to access the application arguments that were passed to
`SpringApplication.run(...)` you can inject a
`org.springframework.boot.ApplicationArguments` bean. The `ApplicationArguments` interface
provides access to both the raw `String[]` arguments as well as parsed `option` and
`non-option` arguments:
[source,java,indent=0]
----
import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
}
}
----
TIP: Spring Boot will also register a `CommandLinePropertySource` with the Spring
`Environment`. This allows you to also inject single application arguments using the
`@Value` annotation.
[[boot-features-command-line-runner]]
=== Using the ApplicationRunner or CommandLineRunner
If you need to run some specific code once the `SpringApplication` has started, you can
implement the `ApplicationRunner` or `CommandLineRunner` interfaces. Both interfaces work
in the same way and offer a single `run` method which will be called just before
`SpringApplication.run(...)` completes.
The `CommandLineRunner` interfaces provides access to application arguments as a simple
string array, whereas the `ApplicationRunner` uses the `ApplicationArguments` interface
discussed above.
[source,java,indent=0]
----
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
----
You can additionally implement the `org.springframework.core.Ordered` interface or use the
`org.springframework.core.annotation.Order` annotation if several `CommandLineRunner` or
`ApplicationRunner` beans are defined that must be called in a specific order.
[[boot-features-application-exit]]
=== Application exit
Each `SpringApplication` will register a shutdown hook with the JVM to ensure that the
`ApplicationContext` is closed gracefully on exit. All the standard Spring lifecycle
callbacks (such as the `DisposableBean` interface, or the `@PreDestroy` annotation) can
be used.
In addition, beans may implement the `org.springframework.boot.ExitCodeGenerator`
interface if they wish to return a specific exit code when `SpringApplication.exit()`
is called. This exit code can then be passed to `System.exit()` to return it as a status
code.
[source,java,indent=0]
----
include::{code-examples}/ExitCodeApplication.java[tag=example]
----
Also, the `ExitCodeGenerator` interface may be implemented by exceptions. When such an
exception is encountered, Spring Boot will return the exit code provided by the
implemented `getExitCode()` method.
[[boot-features-application-admin]]
=== Admin features
It is possible to enable admin-related features for the application by specifying the
`spring.application.admin.enabled` property. This exposes the
{sc-spring-boot}/admin/SpringApplicationAdminMXBean.{sc-ext}[`SpringApplicationAdminMXBean`]
on the platform `MBeanServer`. You could use this feature to administer your Spring Boot
application remotely. This could also be useful for any service wrapper implementation.
TIP: If you want to know on which HTTP port the application is running, get the property
with key `local.server.port`.
NOTE: Take care when enabling this feature as the MBean exposes a method to shutdown the
application.
[[boot-features-external-config]]
== Externalized Configuration
Spring Boot allows you to externalize your configuration so you can work with the same
application code in different environments. You can use properties files, YAML files,
environment variables and command-line arguments to externalize configuration. Property
values can be injected directly into your beans using the `@Value` annotation, accessed
via Spring's `Environment` abstraction or
<<boot-features-external-config-typesafe-configuration-properties,bound to structured objects>>
via `@ConfigurationProperties`.
Spring Boot uses a very particular `PropertySource` order that is designed to allow
sensible overriding of values. Properties are considered in the following order:
. <<using-boot-devtools-globalsettings,Devtools global settings properties>>
on your home directory (`~/.spring-boot-devtools.properties` when devtools is active).
. {spring-javadoc}/test/context/TestPropertySource.{dc-ext}[`@TestPropertySource`]
annotations on your tests.
. {dc-spring-boot-test}/context/SpringBootTest.{dc-ext}[`@SpringBootTest#properties`]
annotation attribute on your tests.
. Command line arguments.
. Properties from `SPRING_APPLICATION_JSON` (inline JSON embedded in an environment
variable or system property)
. `ServletConfig` init parameters.
. `ServletContext` init parameters.
. JNDI attributes from `java:comp/env`.
. Java System properties (`System.getProperties()`).
. OS environment variables.
. A `RandomValuePropertySource` that only has properties in `+random.*+`.
. <<boot-features-external-config-profile-specific-properties,Profile-specific
application properties>> outside of your packaged jar
(`application-{profile}.properties` and YAML variants)
. <<boot-features-external-config-profile-specific-properties,Profile-specific
application properties>> packaged inside your jar (`application-{profile}.properties`
and YAML variants)
. Application properties outside of your packaged jar (`application.properties` and YAML
variants).
. Application properties packaged inside your jar (`application.properties` and YAML
variants).
. {spring-javadoc}/context/annotation/PropertySource.{dc-ext}[`@PropertySource`]
annotations on your `@Configuration` classes.
. Default properties (specified using `SpringApplication.setDefaultProperties`).
To provide a concrete example, suppose you develop a `@Component` that uses a
`name` property:
[source,java,indent=0]
----
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
----
On your application classpath (e.g. inside your jar) you can have an
`application.properties` that provides a sensible default property value for `name`. When
running in a new environment, an `application.properties` can be provided outside of your
jar that overrides the `name`; and for one-off testing, you can launch with a specific
command line switch (e.g. `java -jar app.jar --name="Spring"`).
[TIP]
====
The `SPRING_APPLICATION_JSON` properties can be supplied on the
command line with an environment variable. For example in a
UN{asterisk}X shell:
----
$ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar
----
In this example you will end up with `foo.bar=spam` in the Spring
`Environment`. You can also supply the JSON as
`spring.application.json` in a System variable:
----
$ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar
----
or command line argument:
----
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'
----
or as a JNDI variable `java:comp/env/spring.application.json`.
====
[[boot-features-external-config-random-values]]
=== Configuring random values
The `RandomValuePropertySource` is useful for injecting random values (e.g. into secrets
or test cases). It can produce integers, longs, uuids or strings, e.g.
[source,properties,indent=0]
----
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
----
The `+random.int*+` syntax is `OPEN value (,max) CLOSE` where the `OPEN,CLOSE` are any
character and `value,max` are integers. If `max` is provided then `value` is the minimum
value and `max` is the maximum (exclusive).
[[boot-features-external-config-command-line-args]]
=== Accessing command line properties
By default `SpringApplication` will convert any command line option arguments (starting
with '`--`', e.g. `--server.port=9000`) to a `property` and add it to the Spring
`Environment`. As mentioned above, command line properties always take precedence over
other property sources.
If you don't want command line properties to be added to the `Environment` you can disable
them using `SpringApplication.setAddCommandLineProperties(false)`.
[[boot-features-external-config-application-property-files]]
=== Application property files
`SpringApplication` will load properties from `application.properties` files in the
following locations and add them to the Spring `Environment`:
. A `/config` subdirectory of the current directory.
. The current directory
. A classpath `/config` package
. The classpath root
The list is ordered by precedence (properties defined in locations higher in the list
override those defined in lower locations).
NOTE: You can also <<boot-features-external-config-yaml, use YAML ('.yml') files>> as
an alternative to '.properties'.
If you don't like `application.properties` as the configuration file name you can switch
to another by specifying a `spring.config.name` environment property. You can also refer
to an explicit location using the `spring.config.location` environment property
(comma-separated list of directory locations, or file paths).
[indent=0]
----
$ java -jar myproject.jar --spring.config.name=myproject
----
or
[indent=0]
----
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
----
WARNING: `spring.config.name` and `spring.config.location` are used very early to
determine which files have to be loaded so they have to be defined as an environment
property (typically OS env, system property or command line argument).
If `spring.config.location` contains directories (as opposed to files) they should end
in `/` (and will be appended with the names generated from `spring.config.name` before
being loaded, including profile-specific file names). Files specified in
`spring.config.location` are used as-is, with no support for profile-specific variants,
and will be overridden by any profile-specific properties.
Config locations are searched in reverse order. By default, the configured locations are
`classpath:/,classpath:/config/,file:./,file:./config/`. The resulting search order is:
1. `file:./config/`
2. `file:./`
3. `classpath:/config/`
4. `classpath:/`
When custom config locations are configured, they are used in addition to the default
locations. Custom locations are searched before the default locations. For example,
if custom locations `classpath:/custom-config/,file:./custom-config/` are configured,
the search order becomes:
1. `file:./custom-config/`
2. `classpath:custom-config/`
3. `file:./config/`
4. `file:./`
5. `classpath:/config/`
6. `classpath:/`
This search ordering allows you to specify default values in one configuration file
and then selectively override those values in another. You can provide default values
for your application in `application.properties` (or whatever other basename you choose
with `spring.config.name`) in one of the default locations. These default values can
then be overriden at runtime with a different file located in one of the custom
locations.
NOTE: If you use environment variables rather than system properties, most operating
systems disallow period-separated key names, but you can use underscores instead (e.g.
`SPRING_CONFIG_NAME` instead of `spring.config.name`).
NOTE: If you are running in a container then JNDI properties (in `java:comp/env`) or
servlet context initialization parameters can be used instead of, or as well as,
environment variables or system properties.
[[boot-features-external-config-profile-specific-properties]]
=== Profile-specific properties
In addition to `application.properties` files, profile-specific properties can also be
defined using the naming convention `application-{profile}.properties`. The
`Environment` has a set of default profiles (by default `[default]`) which are
used if no active profiles are set (i.e. if no profiles are explicitly activated
then properties from `application-default.properties` are loaded).
Profile-specific properties are loaded from the same locations as standard
`application.properties`, with profile-specific files always overriding the non-specific
ones irrespective of whether the profile-specific files are inside or outside your
packaged jar.
If several profiles are specified, a last wins strategy applies. For example, profiles
specified by the `spring.profiles.active` property are added after those configured via
the `SpringApplication` API and therefore take precedence.
NOTE: If you have specified any files in `spring.config.location`, profile-specific
variants of those files will not be considered. Use directories in
`spring.config.location` if you also want to also use profile-specific properties.
[[boot-features-external-config-placeholders-in-properties]]
=== Placeholders in properties
The values in `application.properties` are filtered through the existing `Environment`
when they are used so you can refer back to previously defined values (e.g. from System
properties).
[source,properties,indent=0]
----
app.name=MyApp
app.description=${app.name} is a Spring Boot application
----
TIP: You can also use this technique to create '`short`' variants of existing Spring Boot
properties. See the _<<howto.adoc#howto-use-short-command-line-arguments>>_ how-to
for details.
[[boot-features-external-config-yaml]]
=== Using YAML instead of Properties
http://yaml.org[YAML] is a superset of JSON, and as such is a very convenient format
for specifying hierarchical configuration data. The `SpringApplication` class will
automatically support YAML as an alternative to properties whenever you have the
http://www.snakeyaml.org/[SnakeYAML] library on your classpath.
NOTE: If you use '`Starters`' SnakeYAML will be automatically provided via
`spring-boot-starter`.
[[boot-features-external-config-loading-yaml]]
==== Loading YAML
Spring Framework provides two convenient classes that can be used to load YAML documents.
The `YamlPropertiesFactoryBean` will load YAML as `Properties` and the
`YamlMapFactoryBean` will load YAML as a `Map`.
For example, the following YAML document:
[source,yaml,indent=0]
----
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
----
Would be transformed into these properties:
[source,properties,indent=0]
----
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
----
YAML lists are represented as property keys with `[index]` dereferencers,
for example this YAML:
[source,yaml,indent=0]
----
my:
servers:
- dev.bar.com
- foo.bar.com
----
Would be transformed into these properties:
[source,properties,indent=0]
----
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
----
To bind to properties like that using the Spring `DataBinder` utilities (which is what
`@ConfigurationProperties` does) you need to have a property in the target bean of type
`java.util.List` (or `Set`) and you either need to provide a setter, or initialize it
with a mutable value, e.g. this will bind to the properties above
[source,java,indent=0]
----
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
----
[NOTE]
====
Extra care is required when configuring lists that way as overriding will not work as you
would expect. In the example above, when `my.servers` is redefined in several places, the
individual elements are targeted for override, not the list. To make sure that a
`PropertySource` with higher precedence can override the list, you need to define it as
a single property:
[source,yaml,indent=0]
----
my:
servers: dev.bar.com,foo.bar.com
----
====
[[boot-features-external-config-exposing-yaml-to-spring]]
==== Exposing YAML as properties in the Spring Environment
The `YamlPropertySourceLoader` class can be used to expose YAML as a `PropertySource`
in the Spring `Environment`. This allows you to use the familiar `@Value` annotation with
placeholders syntax to access YAML properties.
[[boot-features-external-config-multi-profile-yaml]]
==== Multi-profile YAML documents
You can specify multiple profile-specific YAML documents in a single file by
using a `spring.profiles` key to indicate when the document applies. For example:
[source,yaml,indent=0]
----
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
----
In the example above, the `server.address` property will be `127.0.0.1` if the
`development` profile is active. If the `development` and `production` profiles are *not*
enabled, then the value for the property will be `192.168.1.100`.
The default profiles are activated if none are explicitly active when the application
context starts. So in this YAML we set a value for `security.user.password` that is
*only* available in the "default" profile:
[source,yaml,indent=0]
----
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak
----
whereas in this example, the password is always set because it isn't attached to any
profile, and it would have to be explicitly reset in all other profiles as necessary:
[source,yaml,indent=0]
----
server:
port: 8000
security:
user:
password: weak
----
Spring profiles designated using the "spring.profiles" element may optionally be negated
using the `!` character. If both negated and non-negated profiles are specified for
a single document, at least one non-negated profile must match and no negated profiles
may match.
[[boot-features-external-config-yaml-shortcomings]]
==== YAML shortcomings
YAML files can't be loaded via the `@PropertySource` annotation. So in the
case that you need to load values that way, you need to use a properties file.
[[boot-features-external-config-complex-type-merge]]
==== Merging YAML lists
As <<boot-features-external-config-loading-yaml,we have seen above>>, any YAML content is
ultimately transformed to properties. That process may be counter intuitive when
overriding "`list`" properties via a profile.
For example, assume a `MyPojo` object with `name` and `description` attributes
that are `null` by default. Let's expose a list of `MyPojo` from `FooProperties`:
[source,java,indent=0]
----
@ConfigurationProperties("foo")
public class FooProperties {
private final List<MyPojo> list = new ArrayList<>();
public List<MyPojo> getList() {
return this.list;
}
}
----
Consider the following configuration:
[source,yaml,indent=0]
----
foo:
list:
- name: my name
description: my description
---
spring:
profiles: dev
foo:
list:
- name: my another name
----
If the `dev` profile isn't active, `FooProperties.list` will contain one `MyPojo` entry
as defined above. If the `dev` profile is enabled however, the `list` will _still_
only contain one entry (with name "`my another name`" and description `null`). This
configuration _will not_ add a second `MyPojo` instance to the list, and it won't merge
the items.
When a collection is specified in multiple profiles, the one with highest priority is
used (and only that one):
[source,yaml,indent=0]
----
foo:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
foo:
list:
- name: my another name
----
In the example above, considering that the `dev` profile is active, `FooProperties.list`
will contain _one_ `MyPojo` entry (with name "`my another name`" and description `null`).
[[boot-features-external-config-typesafe-configuration-properties]]
=== Type-safe Configuration Properties
Using the `@Value("${property}")` annotation to inject configuration properties can
sometimes be cumbersome, especially if you are working with multiple properties or your
data is hierarchical in nature. Spring Boot provides an alternative method of working with
properties that allows strongly typed beans to govern and validate the configuration of
your application.
[source,java,indent=0]
----
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("foo")
public class FooProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
----
The POJO above defines the following properties:
* `foo.enabled`, `false` by default
* `foo.remote-address`, with a type that can be coerced from `String`
* `foo.security.username`, with a nested "security" whose name is determined by the name
of the property. In particular the return type is not used at all there and could have
been `SecurityProperties`
* `foo.security.password`
* `foo.security.roles`, with a collection of `String`
[NOTE]
====
Getters and setters are usually mandatory, since binding is via standard Java Beans
property descriptors, just like in Spring MVC. There are cases where a setter may be
omitted:
* Maps, as long as they are initialized, need a getter but not necessarily a setter since
they can be mutated by the binder.
* Collections and arrays can be either accessed via an index (typically with YAML) or
using a single comma-separated value (properties). In the latter case, a setter is
mandatory. We recommend to always add a setter for such types. If you initialize a
collection, make sure it is not immutable (as in the example above)
* If nested POJO properties are initialized (like the `Security` field in the example
above), a setter is not required. If you want the binder to create the instance on-the-fly
using its default constructor, you will need a setter.
Some people use Project Lombok to add getters and setters automatically. Make sure that
Lombok doesn't generate any particular constructor for such type as it will be used
automatically by the container to instantiate the object.
====
TIP: See also the <<boot-features-external-config-vs-value,differences between `@Value`
and `@ConfigurationProperties`>>.
You also need to list the properties classes to register in the
`@EnableConfigurationProperties` annotation:
[source,java,indent=0]
----
@Configuration
@EnableConfigurationProperties(FooProperties.class)
public class MyConfiguration {
}
----
[NOTE]
====
When `@ConfigurationProperties` bean is registered that way, the bean will have a
conventional name: `<prefix>-<fqn>`, where `<prefix>` is the environment key prefix
specified in the `@ConfigurationProperties` annotation and `<fqn>` the fully qualified
name of the bean. If the annotation does not provide any prefix, only the fully qualified
name of the bean is used.
The bean name in the example above will be `foo-com.example.FooProperties`.
====
Even if the configuration above will create a regular bean for `FooProperties`, we
recommend that `@ConfigurationProperties` only deal with the environment and in particular
does not inject other beans from the context. Having said that, The
`@EnableConfigurationProperties` annotation is _also_ automatically applied to your project
so that any _existing_ bean annotated with `@ConfigurationProperties` will be configured
from the `Environment`. You could shortcut `MyConfiguration` above by making sure
`FooProperties` is already a bean:
[source,java,indent=0]
----
@Component
@ConfigurationProperties(prefix="foo")
public class FooProperties {
// ... see above
}
----
This style of configuration works particularly well with the
`SpringApplication` external YAML configuration:
[source,yaml,indent=0]
----
# application.yml
foo:
remote-address: 192.168.1.1
security:
username: foo
roles:
- USER
- ADMIN
# additional configuration as required
----
To work with `@ConfigurationProperties` beans you can just inject them in the same way
as any other bean.
[source,java,indent=0]
----
@Service
public class MyService {
private final FooProperties properties;
@Autowired
public MyService(FooProperties properties) {
this.properties = properties;
}
//...
@PostConstruct
public void openConnection() {
Server server = new Server(this.properties.getRemoteAddress());
// ...
}
}
----
TIP: Using `@ConfigurationProperties` also allows you to generate meta-data files that can
be used by IDEs to offer auto-completion for your own keys, see the
<<configuration-metadata>> appendix for details.
[[boot-features-external-config-3rd-party-configuration]]
==== Third-party configuration
As well as using `@ConfigurationProperties` to annotate a class, you can also use it
on public `@Bean` methods. This can be particularly useful when you want to bind
properties to third-party components that are outside of your control.
To configure a bean from the `Environment` properties, add `@ConfigurationProperties` to
its bean registration:
[source,java,indent=0]
----
@ConfigurationProperties(prefix = "bar")
@Bean
public BarComponent barComponent() {
...
}
----
Any property defined with the `bar` prefix will be mapped onto that `BarComponent` bean
in a similar manner as the `FooProperties` example above.
[[boot-features-external-config-relaxed-binding]]
==== Relaxed binding
Spring Boot uses some relaxed rules for binding `Environment` properties to
`@ConfigurationProperties` beans, so there doesn't need to be an exact match between
the `Environment` property name and the bean property name. Common examples where this
is useful include dashed separated (e.g. `context-path` binds to `contextPath`), and
capitalized (e.g. `PORT` binds to `port`) environment properties.
For example, given the following `@ConfigurationProperties` class:
[source,java,indent=0]
----
@ConfigurationProperties(prefix="person")
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
----
The following properties names can all be used:
.relaxed binding
[cols="1,4"]
|===
| Property | Note
|`person.firstName`
|Standard camel case syntax.
|`person.first-name`
|Kebab-case, recommended for use in `.properties` and `.yml` files.
|`person.first_name`
|Underscore notation, alternative format for use in `.properties` and `.yml` files.
|`PERSON_FIRSTNAME`
|Upper case format. Recommended when using a system environment variables.
|===
NOTE: The `prefix` value for the annotation must be in kebab-case, ie, lowercase and separated by `-`.
.relaxed binding rules per property source
[cols="2,4,4"]
|===
| Property Source | Simple | List
|Properties Files
|Camel-case, kebab-case or underscore notation
|Standard list syntax using `[ ]` or comma-separated values
|YAML Files
|Camel-case, kebab-case or underscore notation
|Standard YAML list syntax or comma-separated values
|Environment Variables
|Upper case format with underscore as the delimiter. `_` should not be used within a property name
|Numeric values surrounded by underscores. eg: `MY_FOO_1_BAR = my.foo[1].bar`
|System properties
|Camel-case, kebab-case or underscore notation
|Standard list syntax using `[ ]` or comma-separated values
|===
TIP: We recommend that, when possible, properties are stored in lowercase kebab format. i.e. `my.property-name=foo`
[[boot-features-external-config-conversion]]
==== Properties conversion
Spring will attempt to coerce the external application properties to the right type when
it binds to the `@ConfigurationProperties` beans. If you need custom type conversion you
can provide a `ConversionService` bean (with bean id `conversionService`) or custom
property editors (via a `CustomEditorConfigurer` bean) or custom `Converters` (with
bean definitions annotated as `@ConfigurationPropertiesBinding`).
NOTE: As this bean is requested very early during the application lifecycle, make sure to
limit the dependencies that your `ConversionService` is using. Typically, any dependency
that you require may not be fully initialized at creation time. You may want to rename
your custom `ConversionService` if it's not required for configuration keys coercion and
only rely on custom converters qualified with `@ConfigurationPropertiesBinding`.
[[boot-features-external-config-validation]]
==== @ConfigurationProperties Validation
Spring Boot will attempt to validate `@ConfigurationProperties` classes whenever they
are annotated with Spring's `@Validated` annotation. You can use JSR-303 `javax.validation`
constraint annotations directly on your configuration class. Simply ensure that a
compliant JSR-303 implementation is on your classpath, then add constraint annotations to
your fields:
[source,java,indent=0]
----
@ConfigurationProperties(prefix="foo")
@Validated
public class FooProperties {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
----
In order to validate values of nested properties, you must annotate the associated field
as `@Valid` to trigger its validation. For example, building upon the above
`FooProperties` example:
[source,java,indent=0]
----
@ConfigurationProperties(prefix="connection")
@Validated
public class FooProperties {
@NotNull
private InetAddress remoteAddress;
@Valid
private final Security security = new Security();
// ... getters and setters
public static class Security {
@NotEmpty
public String username;
// ... getters and setters
}
}
----
You can also add a custom Spring `Validator` by creating a bean definition called
`configurationPropertiesValidator`. The `@Bean` method should be declared `static`. The
configuration properties validator is created very early in the application's lifecycle
and declaring the `@Bean` method as static allows the bean to be created without having to
instantiate the `@Configuration` class. This avoids any problems that may be caused by
early instantiation. There is a
{github-code}/spring-boot-samples/spring-boot-sample-property-validation[property
validation sample] so you can see how to set things up.
TIP: The `spring-boot-actuator` module includes an endpoint that exposes all
`@ConfigurationProperties` beans. Simply point your web browser to
`/application/configprops` or use the equivalent JMX endpoint. See the
_<<production-ready-features.adoc#production-ready-endpoints, Production ready features>>_.
section for details.
[[boot-features-external-config-vs-value]]
==== @ConfigurationProperties vs. @Value
`@Value` is a core container feature and it does not provide the same features as
type-safe Configuration Properties. The table below summarizes the features that are
supported by `@ConfigurationProperties` and `@Value`:
[cols="4,2,2"]
|===
|Feature |`@ConfigurationProperties` |`@Value`
| <<boot-features-external-config-relaxed-binding,Relaxed binding>>
| Yes
| No
| <<appendix-configuration-metadata.adoc#configuration-metadata,Meta-data support>>
| Yes
| No
| `SpEL` evaluation
| No
| Yes
|===
If you define a set of configuration keys for your own components, we recommend you to
group them in a POJO annotated with `@ConfigurationProperties`. Please also be aware
that since `@Value` does not support relaxed binding, it isn't a great candidate if you
need to provide the value using environment variables.
Finally, while you can write a `SpEL` expression in `@Value`, such expressions are not
processed from <<boot-features-external-config-application-property-files,Application
property files>>.
[[boot-features-profiles]]
== Profiles
Spring Profiles provide a way to segregate parts of your application configuration and
make it only available in certain environments. Any `@Component` or `@Configuration` can
be marked with `@Profile` to limit when it is loaded:
[source,java,indent=0]
----
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
----
In the normal Spring way, you can use a `spring.profiles.active`
`Environment` property to specify which profiles are active. You can
specify the property in any of the usual ways, for example you could
include it in your `application.properties`:
[source,properties,indent=0]
----
spring.profiles.active=dev,hsqldb
----
or specify on the command line using the switch `--spring.profiles.active=dev,hsqldb`.
[[boot-features-adding-active-profiles]]
=== Adding active profiles
The `spring.profiles.active` property follows the same ordering rules as other
properties, the highest `PropertySource` will win. This means that you can specify
active profiles in `application.properties` then *replace* them using the command line
switch.
Sometimes it is useful to have profile-specific properties that *add* to the active
profiles rather than replace them. The `spring.profiles.include` property can be used
to unconditionally add active profiles. The `SpringApplication` entry point also has
a Java API for setting additional profiles (i.e. on top of those activated by the
`spring.profiles.active` property): see the `setAdditionalProfiles()` method.
For example, when an application with following properties is run using the switch
`--spring.profiles.active=prod` the `proddb` and `prodmq` profiles will also be activated:
[source,yaml,indent=0]
----
---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
- proddb
- prodmq
----
NOTE: Remember that the `spring.profiles` property can be defined in a YAML document
to determine when this particular document is included in the configuration. See
<<howto-change-configuration-depending-on-the-environment>> for more details.
[[boot-features-programmatically-setting-profiles]]
=== Programmatically setting profiles
You can programmatically set active profiles by calling
`SpringApplication.setAdditionalProfiles(...)` before your application runs. It is also
possible to activate profiles using Spring's `ConfigurableEnvironment` interface.
[[boot-features-profile-specific-configuration]]
=== Profile-specific configuration files
Profile-specific variants of both `application.properties` (or `application.yml`) and
files referenced via `@ConfigurationProperties` are considered as files are loaded.
See _<<boot-features-external-config-profile-specific-properties>>_ for details.
[[boot-features-logging]]
== Logging
Spring Boot uses http://commons.apache.org/logging[Commons Logging] for all internal
logging, but leaves the underlying log implementation open. Default configurations are
provided for
http://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html[Java Util Logging],
http://logging.apache.org/log4j/2.x/[Log4J2] and http://logback.qos.ch/[Logback]. In each
case loggers are pre-configured to use console output with optional file output also
available.
By default, if you use the '`Starters`', Logback will be used for logging. Appropriate
Logback routing is also included to ensure that dependent libraries that use
Java Util Logging, Commons Logging, Log4J or SLF4J will all work correctly.
TIP: There are a lot of logging frameworks available for Java. Don't worry if the above
list seems confusing. Generally you won't need to change your logging dependencies and
the Spring Boot defaults will work just fine.
[[boot-features-logging-format]]
=== Log format
The default log output from Spring Boot looks like this:
[indent=0]
----
2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
----
The following items are output:
* Date and Time -- Millisecond precision and easily sortable.
* Log Level -- `ERROR`, `WARN`, `INFO`, `DEBUG` or `TRACE`.
* Process ID.
* A `---` separator to distinguish the start of actual log messages.
* Thread name -- Enclosed in square brackets (may be truncated for console output).
* Logger name -- This is usually the source class name (often abbreviated).
* The log message.
NOTE: Logback does not have a `FATAL` level (it is mapped to `ERROR`)
[[boot-features-logging-console-output]]
=== Console output
The default log configuration will echo messages to the console as they are written. By
default `ERROR`, `WARN` and `INFO` level messages are logged. You can also enable a
"`debug`" mode by starting your application with a `--debug` flag.
[indent=0]
----
$ java -jar myapp.jar --debug
----
NOTE: you can also specify `debug=true` in your `application.properties`.
When the debug mode is enabled, a selection of core loggers (embedded container, Hibernate
and Spring Boot) are configured to output more information. Enabling the debug mode does
_not_ configure your application to log all messages with `DEBUG` level.
Alternatively, you can enable a "`trace`" mode by starting your application with a
`--trace` flag (or `trace=true` in your `application.properties`). This will enable trace
logging for a selection of core loggers (embedded container, Hibernate schema generation
and the whole Spring portfolio).
[[boot-features-logging-color-coded-output]]
==== Color-coded output
If your terminal supports ANSI, color output will be used to aid readability. You can set
`spring.output.ansi.enabled` to a
{dc-spring-boot}/ansi/AnsiOutput.Enabled.{dc-ext}[supported value] to override the auto
detection.
Color coding is configured using the `%clr` conversion word. In its simplest form the
converter will color the output according to the log level, for example:
[source,indent=0]
----
%clr(%5p)
----
The mapping of log level to a color is as follows:
|===
|Level | Color
|`FATAL`
| Red
|`ERROR`
| Red
|`WARN`
| Yellow
|`INFO`
| Green
|`DEBUG`
| Green
|`TRACE`
| Green
|===
Alternatively, you can specify the color or style that should be used by providing it
as an option to the conversion. For example, to make the text yellow:
[source,indent=0]
----
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
----
The following colors and styles are supported:
- `blue`
- `cyan`
- `faint`
- `green`
- `magenta`
- `red`
- `yellow`
[[boot-features-logging-file-output]]
=== File output
By default, Spring Boot will only log to the console and will not write log files. If you
want to write log files in addition to the console output you need to set a
`logging.file` or `logging.path` property (for example in your `application.properties`).
The following table shows how the `logging.*` properties can be used together:
.Logging properties
[cols="1,1,1,4"]
|===
|`logging.file` |`logging.path` |Example |Description
|_(none)_
|_(none)_
|
|Console only logging.
|Specific file
|_(none)_
|`my.log`
|Writes to the specified log file. Names can be an exact location or relative to the
current directory.
|_(none)_
|Specific directory
|`/var/log`
|Writes `spring.log` to the specified directory. Names can be an exact location or
relative to the current directory.
|===
Log files will rotate when they reach 10 MB and as with console output, `ERROR`, `WARN`
and `INFO` level messages are logged by default.
NOTE: The logging system is initialized early in the application lifecycle and as such
logging properties will not be found in property files loaded via `@PropertySource`
annotations.
TIP: Logging properties are independent of the actual logging infrastructure. As a
result, specific configuration keys (such as `logback.configurationFile` for Logback)
are not managed by spring Boot.
[[boot-features-custom-log-levels]]
=== Log Levels
All the supported logging systems can have the logger levels set in the Spring
`Environment` (so for example in `application.properties`) using
'`+logging.level.*=LEVEL+`' where '`LEVEL`' is one of TRACE, DEBUG, INFO, WARN, ERROR,
FATAL, OFF. The `root` logger can be configured using `logging.level.root`.
Example `application.properties`:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
----
NOTE: By default Spring Boot remaps Thymeleaf `INFO` messages so that they are logged at
`DEBUG` level. This helps to reduce noise in the standard log output. See
{sc-spring-boot}/logging/logback/LevelRemappingAppender.{sc-ext}[`LevelRemappingAppender`]
for details of how you can apply remapping in your own configuration.
[[boot-features-custom-log-configuration]]
=== Custom log configuration
The various logging systems can be activated by including the appropriate libraries on
the classpath, and further customized by providing a suitable configuration file in the
root of the classpath, or in a location specified by the Spring `Environment` property
`logging.config`.
You can force Spring Boot to use a particular logging system using the
`org.springframework.boot.logging.LoggingSystem` system property. The value should be
the fully-qualified class name of a `LoggingSystem` implementation. You can also disable
Spring Boot's logging configuration entirely by using a value of `none`.
NOTE: Since logging is initialized *before* the `ApplicationContext` is created, it isn't
possible to control logging from `@PropertySources` in Spring `@Configuration` files.
System properties and the conventional Spring Boot external configuration files work just
fine.)
Depending on your logging system, the following files will be loaded:
|===
|Logging System |Customization
|Logback
|`logback-spring.xml`, `logback-spring.groovy`, `logback.xml` or `logback.groovy`
|Log4j2
|`log4j2-spring.xml` or `log4j2.xml`
|JDK (Java Util Logging)
|`logging.properties`
|===
NOTE: When possible we recommend that you use the `-spring` variants for your logging
configuration (for example `logback-spring.xml` rather than `logback.xml`). If you use
standard configuration locations, Spring cannot completely control log initialization.
WARNING: There are known classloading issues with Java Util Logging that cause problems
when running from an '`executable jar`'. We recommend that you avoid it if at all
possible.
To help with the customization some other properties are transferred from the Spring
`Environment` to System properties:
|===
|Spring Environment |System Property |Comments
|`logging.exception-conversion-word`
|`LOG_EXCEPTION_CONVERSION_WORD`
|The conversion word that's used when logging exceptions.
|`logging.file`
|`LOG_FILE`
|Used in default log configuration if defined.
|`logging.path`
|`LOG_PATH`
|Used in default log configuration if defined.
|`logging.pattern.console`
|`CONSOLE_LOG_PATTERN`
|The log pattern to use on the console (stdout). (Only supported with the default logback setup.)
|`logging.pattern.file`
|`FILE_LOG_PATTERN`
|The log pattern to use in a file (if LOG_FILE enabled). (Only supported with the default logback setup.)
|`logging.pattern.level`
|`LOG_LEVEL_PATTERN`
|The format to use to render the log level (default `%5p`). (Only supported with the default logback setup.)
|`PID`
|`PID`
|The current process ID (discovered if possible and when not already defined as an OS
environment variable).
|===
All the logging systems supported can consult System properties when parsing their
configuration files. See the default configurations in `spring-boot.jar` for examples.
[TIP]
====
If you want to use a placeholder in a logging property, you should use
<<boot-features-external-config-placeholders-in-properties,Spring Boot's syntax>> and not
the syntax of the underlying framework. Notably, if you're using Logback, you should use
`:` as the delimiter between a property name and its default value and not `:-`.
====
[TIP]
====
You can add MDC and other ad-hoc content to log lines by overriding
only the `LOG_LEVEL_PATTERN` (or `logging.pattern.level` with
Logback). For example, if you use `logging.pattern.level=user:%X{user}
%5p` then the default log format will contain an MDC entry for "user"
if it exists, e.g.
----
2015-09-30 12:30:04.031 user:juergen INFO 22174 --- [ nio-8080-exec-0] demo.Controller
Handling authenticated request
----
====
[[boot-features-logback-extensions]]
=== Logback extensions
Spring Boot includes a number of extensions to Logback which can help with advanced
configuration. You can use these extensions in your `logback-spring.xml` configuration
file.
NOTE: You cannot use extensions in the standard `logback.xml` configuration file since
it's loaded too early. You need to either use `logback-spring.xml` or define a
`logging.config` property.
WARNING: The extensions cannot be used with Logback's
http://logback.qos.ch/manual/configuration.html#autoScan[configuration scanning]. If you
attempt to do so, making changes to the configuration file will result in an error similar
to one of the following being logged:
----
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
----
==== Profile-specific configuration
The `<springProfile>` tag allows you to optionally include or exclude sections of
configuration based on the active Spring profiles. Profile sections are supported anywhere
within the `<configuration>` element. Use the `name` attribute to specify which profile
accepts the configuration. Multiple profiles can be specified using a comma-separated
list.
[source,xml,indent=0]
----
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev, staging">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!production">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
----
==== Environment properties
The `<springProperty>` tag allows you to surface properties from the Spring `Environment`
for use within Logback. This can be useful if you want to access values from your
`application.properties` file in your logback configuration. The tag works in a similar
way to Logback's standard `<property>` tag, but rather than specifying a direct `value`
you specify the `source` of the property (from the `Environment`). You can use the `scope`
attribute if you need to store the property somewhere other than in `local` scope. If
you need a fallback value in case the property is not set in the `Environment`, you can
use the `defaultValue` attribute.
[source,xml,indent=0]
----
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
...
</appender>
----
NOTE: The `source` must be specified using kebab-case (`my.property-name`). However, properties can be added to the
`Environment` using the relaxed rules.
[[boot-features-developing-web-applications]]
== Developing web applications
Spring Boot is well suited for web application development. You can easily create a
self-contained HTTP server using embedded Tomcat, Jetty, Undertow, or Netty.
Most web applications will use the `spring-boot-starter-web` module to get up
and running quickly. You can also choose to use to build reactive web applications
by using the `spring-boot-starter-webflux` module.
If you haven't yet developed a Spring Boot web application you can follow the
"Hello World!" example in the
_<<getting-started.adoc#getting-started-first-application, Getting started>>_ section.
[[boot-features-spring-mvc]]
=== The '`Spring Web MVC framework`'
The Spring Web MVC framework (often referred to as simply '`Spring MVC`') is a rich
'`model view controller`' web framework. Spring MVC lets you create special `@Controller`
or `@RestController` beans to handle incoming HTTP requests. Methods in your controller
are mapped to HTTP using `@RequestMapping` annotations.
Here is a typical example `@RestController` to serve JSON data:
[source,java,indent=0]
----
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}
----
Spring MVC is part of the core Spring Framework and detailed information is available in
the {spring-reference}web.html#mvc[reference documentation]. There are also several guides
available at http://spring.io/guides that cover Spring MVC.
[[boot-features-spring-mvc-auto-configuration]]
==== Spring MVC auto-configuration
Spring Boot provides auto-configuration for Spring MVC that works well with most
applications.
The auto-configuration adds the following features on top of Spring's defaults:
* Inclusion of `ContentNegotiatingViewResolver` and `BeanNameViewResolver` beans.
* Support for serving static resources, including support for WebJars (see below).
* Automatic registration of `Converter`, `GenericConverter`, `Formatter` beans.
* Support for `HttpMessageConverters` (see below).
* Automatic registration of `MessageCodesResolver` (see below).
* Static `index.html` support.
* Custom `Favicon` support (see below).
* Automatic use of a `ConfigurableWebBindingInitializer` bean (see below).
If you want to keep Spring Boot MVC features, and
you just want to add additional {spring-reference}web.html#mvc[MVC configuration] (interceptors,
formatters, view controllers etc.) you can add your own `@Configuration` class of type
`WebMvcConfigurer`, but *without* `@EnableWebMvc`. If you wish to provide custom
instances of `RequestMappingHandlerMapping`, `RequestMappingHandlerAdapter` or
`ExceptionHandlerExceptionResolver` you can declare a `WebMvcRegistrationsAdapter`
instance providing such components.
If you want to take complete control of Spring MVC, you can add your own `@Configuration`
annotated with `@EnableWebMvc`.
[[boot-features-spring-mvc-message-converters]]
==== HttpMessageConverters
Spring MVC uses the `HttpMessageConverter` interface to convert HTTP requests and
responses. Sensible defaults are included out of the box, for example Objects can be
automatically converted to JSON (using the Jackson library) or XML (using the Jackson
XML extension if available, else using JAXB). Strings are encoded using `UTF-8` by
default.
If you need to add or customize converters you can use Spring Boot's
`HttpMessageConverters` class:
[source,java,indent=0]
----
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;
@Configuration
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
----
Any `HttpMessageConverter` bean that is present in the context will be added to the list
of converters. You can also override default converters that way.
[[boot-features-json-components]]
==== Custom JSON Serializers and Deserializers
If you're using Jackson to serialize and deserialize JSON data, you might want to write
your own `JsonSerializer` and `JsonDeserializer` classes. Custom serializers are usually
http://wiki.fasterxml.com/JacksonHowToCustomDeserializers[registered with Jackson via a Module],
but Spring Boot provides an alternative `@JsonComponent` annotation which makes it easier
to directly register Spring Beans.
You can use `@JsonComponent` directly on `JsonSerializer` or `JsonDeserializer`
implementations. You can also use it on classes that contains serializers/deserializers as
inner-classes. For example:
[source,java,indent=0]
----
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;
@JsonComponent
public class Example {
public static class Serializer extends JsonSerializer<SomeObject> {
// ...
}
public static class Deserializer extends JsonDeserializer<SomeObject> {
// ...
}
}
----
All `@JsonComponent` beans in the `ApplicationContext` will be automatically registered
with Jackson, and since `@JsonComponent` is meta-annotated with `@Component`, the usual
component-scanning rules apply.
Spring Boot also provides
{sc-spring-boot}/jackson/JsonObjectSerializer.{sc-ext}[`JsonObjectSerializer`] and
{sc-spring-boot}/jackson/JsonObjectDeserializer.{sc-ext}[`JsonObjectDeserializer`] base
classes which provide useful alternatives to the standard Jackson versions when
serializing Objects. See the Javadoc for details.
[[boot-features-spring-message-codes]]
==== MessageCodesResolver
Spring MVC has a strategy for generating error codes for rendering error messages
from binding errors: `MessageCodesResolver`. Spring Boot will create one for you if
you set the `spring.mvc.message-codes-resolver.format` property `PREFIX_ERROR_CODE` or
`POSTFIX_ERROR_CODE` (see the enumeration in `DefaultMessageCodesResolver.Format`).
[[boot-features-spring-mvc-static-content]]
==== Static Content
By default Spring Boot will serve static content from a directory called `/static` (or
`/public` or `/resources` or `/META-INF/resources`) in the classpath or from the root
of the `ServletContext`. It uses the `ResourceHttpRequestHandler` from Spring MVC so you
can modify that behavior by adding your own `WebMvcConfigurer` and overriding the
`addResourceHandlers` method.
In a stand-alone web application the default servlet from the container is also
enabled, and acts as a fallback, serving content from the root of the `ServletContext` if
Spring decides not to handle it. Most of the time this will not happen (unless you modify
the default MVC configuration) because Spring will always be able to handle requests
through the `DispatcherServlet`.
By default, resources are mapped on `+/**+` but you can tune that via
`spring.mvc.static-path-pattern`. For instance, relocating all resources to `/resources/**`
can be achieved as follows:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.mvc.static-path-pattern=/resources/**
----
You can also customize the static resource locations using
`spring.resources.static-locations` (replacing the default values with a list
of directory locations). The root Servlet context path `"/"` will be automatically
added as a location as well. If you do this the default welcome page detection will
switch to your custom locations. So if there is an `index.html` in any of your locations
on startup, it will be the home page of the application.
In addition to the '`standard`' static resource locations above, a special case is made
for http://www.webjars.org/[Webjars content]. Any resources with a path in `+/webjars/**+`
will be served from jar files if they are packaged in the Webjars format.
TIP: Do not use the `src/main/webapp` directory if your application will be packaged as a
jar. Although this directory is a common standard, it will *only* work with war packaging
and it will be silently ignored by most build tools if you generate a jar.
Spring Boot also supports advanced resource handling features provided by Spring MVC,
allowing use cases such as cache busting static resources or using version agnostic URLs
for Webjars.
To use version agnostic URLs for Webjars, simply add the `webjars-locator` dependency.
Then declare your Webjar, taking jQuery for example, as `"/webjars/jquery/dist/jquery.min.js"`
which results in `"/webjars/jquery/x.y.z/dist/jquery.min.js"` where `x.y.z` is the Webjar
version.
NOTE: If you are using JBoss, you'll need to declare the `webjars-locator-jboss-vfs`
dependency instead of the `webjars-locator`; otherwise all Webjars resolve as a `404`.
To use cache busting, the following configuration will configure a cache busting
solution for all static resources, effectively adding a content hash in URLs, such as
`<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>`:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
----
NOTE: Links to resources are rewritten at runtime in template, thanks to a
`ResourceUrlEncodingFilter`, auto-configured for Thymeleaf and FreeMarker. You should
manually declare this filter when using JSPs. Other template engines aren't automatically
supported right now, but can be with custom template macros/helpers and the use of the
{spring-javadoc}/web/servlet/resource/ResourceUrlProvider.{dc-ext}[`ResourceUrlProvider`].
When loading resources dynamically with, for example, a JavaScript module loader, renaming
files is not an option. That's why other strategies are also supported and can be combined.
A "fixed" strategy will add a static version string in the URL, without changing the file
name:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12
----
With this configuration, JavaScript modules located under `"/js/lib/"` will use a fixed
versioning strategy `"/v12/js/lib/mymodule.js"` while other resources will still use
the content one `<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>`.
See {sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[`ResourceProperties`]
for more of the supported options.
[TIP]
====
This feature has been thoroughly described in a dedicated
https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources[blog post]
and in Spring Framework's {spring-reference}web.html#mvc-config-static-resources[reference documentation].
====
[[boot-features-spring-mvc-favicon]]
==== Custom Favicon
Spring Boot looks for a `favicon.ico` in the configured static content locations and the
root of the classpath (in that order). If such file is present, it is automatically used
as the favicon of the application.
[[boot-features-spring-mvc-web-binding-initializer]]
==== ConfigurableWebBindingInitializer
Spring MVC uses a `WebBindingInitializer` to initialize a `WebDataBinder` for a particular
request. If you create your own `ConfigurableWebBindingInitializer` `@Bean`, Spring Boot
will automatically configure Spring MVC to use it.
[[boot-features-spring-mvc-template-engines]]
==== Template engines
As well as REST web services, you can also use Spring MVC to serve dynamic HTML content.
Spring MVC supports a variety of templating technologies including Thymeleaf, FreeMarker
and JSPs. Many other templating engines also ship their own Spring MVC integrations.
Spring Boot includes auto-configuration support for the following templating engines:
* http://freemarker.org/docs/[FreeMarker]
* http://docs.groovy-lang.org/docs/next/html/documentation/template-engines.html#_the_markuptemplateengine[Groovy]
* http://www.thymeleaf.org[Thymeleaf]
* http://mustache.github.io/[Mustache]
TIP: JSPs should be avoided if possible, there are several
<<boot-features-jsp-limitations, known limitations>> when using them with embedded
servlet containers.
When you're using one of these templating engines with the default configuration, your
templates will be picked up automatically from `src/main/resources/templates`.
TIP: IntelliJ IDEA orders the classpath differently depending on how you run your
application. Running your application in the IDE via its main method will result in a
different ordering to when you run your application using Maven or Gradle or from its
packaged jar. This can cause Spring Boot to fail to find the templates on the classpath.
If you're affected by this problem you can reorder the classpath in the IDE to place the
module's classes and resources first. Alternatively, you can configure the template prefix
to search every templates directory on the classpath: `classpath*:/templates/`.
[[boot-features-error-handling]]
==== Error Handling
Spring Boot provides an `/error` mapping by default that handles all errors in a sensible
way, and it is registered as a '`global`' error page in the servlet container. For machine
clients it will produce a JSON response with details of the error, the HTTP status and the
exception message. For browser clients there is a '`whitelabel`' error view that renders
the same data in HTML format (to customize it just add a `View` that resolves to
'`error`'). To replace the default behaviour completely you can implement
`ErrorController` and register a bean definition of that type, or simply add a bean of
type `ErrorAttributes` to use the existing mechanism but replace the contents.
TIP: The `BasicErrorController` can be used as a base class for a custom `ErrorController`.
This is particularly useful if you want to add a handler for a new content type (the
default is to handle `text/html` specifically and provide a fallback for everything else).
To do that just extend `BasicErrorController` and add a public method with a
`@RequestMapping` that has a `produces` attribute, and create a bean of your new type.
You can also define a `@ControllerAdvice` to customize the JSON document to return for a
particular controller and/or exception type.
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
@ControllerAdvice(basePackageClasses = FooController.class)
public class FooControllerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(YourException.class)
@ResponseBody
ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
}
----
In the example above, if `YourException` is thrown by a controller defined in the same
package as `FooController`, a json representation of the `CustomErrorType` POJO will be
used instead of the `ErrorAttributes` representation.
[[boot-features-error-handling-custom-error-pages]]
===== Custom error pages
If you want to display a custom HTML error page for a given status code, you add a file to
an `/error` folder. Error pages can either be static HTML (i.e. added under any of the
static resource folders) or built using templates. The name of the file should be the
exact status code or a series mask.
For example, to map `404` to a static HTML file, your folder structure would look like
this:
[source,indent=0,subs="verbatim,quotes,attributes"]
----
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
----
To map all `5xx` errors using a FreeMarker template, you'd have a structure like this:
[source,indent=0,subs="verbatim,quotes,attributes"]
----
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
+- <other templates>
----
For more complex mappings you can also add beans that implement the `ErrorViewResolver`
interface.
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
}
----
You can also use regular Spring MVC features like
{spring-reference}web.html#mvc-exceptionhandlers[`@ExceptionHandler` methods] and
{spring-reference}web.html#mvc-ann-controller-advice[`@ControllerAdvice`]. The `ErrorController`
will then pick up any unhandled exceptions.
[[boot-features-error-handling-mapping-error-pages-without-mvc]]
===== Mapping error pages outside of Spring MVC
For applications that aren't using Spring MVC, you can use the `ErrorPageRegistrar`
interface to directly register `ErrorPages`. This abstraction works directly with the
underlying embedded servlet container and will work even if you don't have a Spring MVC
`DispatcherServlet`.
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
@Bean
public ErrorPageRegistrar errorPageRegistrar(){
return new MyErrorPageRegistrar();
}
// ...
private static class MyErrorPageRegistrar implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
}
}
----
N.B. if you register an `ErrorPage` with a path that will end up being handled by a
`Filter` (e.g. as is common with some non-Spring web frameworks, like Jersey and Wicket),
then the `Filter` has to be explicitly registered as an `ERROR` dispatcher, e.g.
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
----
(the default `FilterRegistrationBean` does not include the `ERROR` dispatcher type).
[[boot-features-error-handling-websphere]]
===== Error Handling on WebSphere Application Server
When deployed to a servlet container, a Spring Boot uses its error page filter to forward
a request with an error status to the appropriate error page. The request can only be
forwarded to the correct error page if the response has not already been committed. By
default, WebSphere Application Server 8.0 and later commits the response upon successful
completion of a servlet's service method. You should disable this behaviour by setting
`com.ibm.ws.webcontainer.invokeFlushAfterService` to `false`
[[boot-features-spring-hateoas]]
==== Spring HATEOAS
If you're developing a RESTful API that makes use of hypermedia, Spring Boot provides
auto-configuration for Spring HATEOAS that works well with most applications. The
auto-configuration replaces the need to use `@EnableHypermediaSupport` and registers a
number of beans to ease building hypermedia-based applications including a
`LinkDiscoverers` (for client side support) and an `ObjectMapper` configured to correctly
marshal responses into the desired representation. The `ObjectMapper` will be customized
based on the `spring.jackson.*` properties or a `Jackson2ObjectMapperBuilder` bean if one
exists.
You can take control of Spring HATEOAS's configuration by using
`@EnableHypermediaSupport`. Note that this will disable the `ObjectMapper` customization
described above.
[[boot-features-cors]]
==== CORS support
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross-origin resource sharing]
(CORS) is a http://www.w3.org/TR/cors/[W3C specification] implemented by
http://caniuse.com/#feat=cors[most browsers] that allows you to specify in a flexible
way what kind of cross domain requests are authorized, instead of using some less secure
and less powerful approaches like IFRAME or JSONP.
As of version 4.2, Spring MVC {spring-reference}web.html#cors[supports CORS] out of the box.
Using {spring-reference}web.html#controller-method-cors-configuration[controller method CORS
configuration] with
{spring-javadoc}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]
annotations in your Spring Boot application does not require any specific configuration.
{spring-reference}web.html#global-cors-configuration[Global CORS configuration] can be defined
by registering a `WebMvcConfigurer` bean with a customized `addCorsMappings(CorsRegistry)`
method:
[source,java,indent=0]
----
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
----
[[boot-features-webflux]]
=== The '`Spring WebFlux framework`'
Spring WebFlux is the new reactive web framework introduced in Spring Framework 5.0.
Unlike Spring MVC, it does not require the Servlet API, is fully asynchronous and
non-blocking, and implements the http://www.reactive-streams.org/[Reactive Streams]
specification through http://projectreactor.io/[the Reactor project].
Spring WebFlux comes in two flavors; the annotation-based one is quite close to the
Spring MVC model we know:
[source,java,indent=0]
----
@RestController
@RequestMapping("/users")
public class MyRestController {
@GetMapping("/{user}")
public Mono<User> getUser(@PathVariable Long user) {
// ...
}
@GetMapping("/{user}/customers")
Flux<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@DeleteMapping("/{user}")
public Mono<User> deleteUser(@PathVariable Long user) {
// ...
}
}
----
'`WebFlux.fn`', the functional variant, separates the routing configuration from the
actual handling of the requests:
[source,java,indent=0]
----
@Configuration
public class RoutingConfiguration {
@Bean
public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
.andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
.andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
}
}
@Component
public class UserHandler {
public Mono<ServerResponse> getUser(ServerRequest request) {
// ...
}
public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
// ...
}
public Mono<ServerResponse> deleteUser(ServerRequest request) {
// ...
}
}
----
WebFlux is part of the Spring Framework and detailed information is available in the
{spring-reference}web.html#web-reactive[reference documentation].
To get started, add the `spring-boot-starter-webflux` module to your application.
NOTE: Adding both `spring-boot-starter-web` and `spring-boot-starter-webflux` modules in
your application will result in Spring Boot auto-configuring Spring MVC, not WebFlux. This
behavior has been chosen because many Spring developers will add
`spring-boot-starter-webflux` to their Spring MVC application to use the reactive
`WebCLient`. You can still enforce your choice by setting the chosen application type like
`SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)`.
[[boot-features-webflux-auto-configuration]]
==== Spring WebFlux auto-configuration
Spring Boot provides auto-configuration for Spring WebFlux that works well with most
applications.
The auto-configuration adds the following features on top of Spring's defaults:
* Configuring codecs for `HttpMessageReader` and `HttpMessageWriter` instances (see
below).
* Support for serving static resources, including support for WebJars (see below).
If you want to keep Spring Boot WebFlux features, and you just want to add additional
{spring-reference}web.html#web-reactive[WebFlux configuration] you can add your own
`@Configuration` class of type `WebFluxConfigurer`, but *without* `@EnableWebFlux`.
If you want to take complete control of Spring WebFlux, you can add your own
`@Configuration` annotated with `@EnableWebFlux`.
[[boot-features-webflux-httpcodecs]]
==== HTTP codecs with HttpMessageReaders and HttpMessageWriters
Spring WebFlux uses the `HttpMessageReader` and `HttpMessageWriter` interface to convert
HTTP requests and responses. They are configured with `CodecConfigurer` with sensible
defaults, by looking at the libraries available in your classpath.
Spring Boot will apply further customization using `CodecCustomizer` instances.
For example, `spring.jackson.*` configuration keys will be applied to the Jackson codec.
If you need to add or customize codecs you can create a custom `CodecCustomizer`
component:
[source,java,indent=0]
----
import org.springframework.boot.web.codec.CodecCustomizer;
@Configuration
public class MyConfiguration {
@Bean
public CodecCustomizer myCodecCustomizer() {
return codecConfigurer -> {
// ...
}
}
}
----
You can also leverage <<boot-features-json-components,Boot's custom JSON serializers and deserializers>>.
[[boot-features-webflux-static-content]]
==== Static Content
By default Spring Boot will serve static content from a directory called `/static` (or
`/public` or `/resources` or `/META-INF/resources`) in the classpath.
It uses the `ResourceWebHandler` from Spring WebFlux so you
can modify that behavior by adding your own `WebFluxConfigurer` and overriding the
`addResourceHandlers` method.
By default, resources are mapped on `+/**+` but you can tune that via
`spring.mvc.static-path-pattern`. For instance, relocating all resources to `/resources/**`
can be achieved as follows:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.mvc.static-path-pattern=/resources/**
----
You can also customize the static resource locations using
`spring.resources.static-locations` (replacing the default values with a list of directory
locations). If you do this the default welcome page detection will switch to your custom
locations, so if there is an `index.html` in any of your locations on startup, it will be
the home page of the application.
In addition to the '`standard`' static resource locations above, a special case is made
for http://www.webjars.org/[Webjars content]. Any resources with a path in `+/webjars/**+`
will be served from jar files if they are packaged in the Webjars format.
TIP: Spring WebFlux applications don't strictly depend on the Servlet API, so they can't
be deployed as war and have no use of the `src/main/webapp` directory.
[[boot-features-webflux-template-engines]]
==== Template engines
As well as REST web services, you can also use Spring WebFlux to serve dynamic HTML
content. Spring WebFlux supports a variety of templating technologies including Thymeleaf,
FreeMarker and Mustache.
Spring Boot includes auto-configuration support for the following templating engines:
* http://freemarker.org/docs/[FreeMarker]
* http://www.thymeleaf.org[Thymeleaf]
* http://mustache.github.io/[Mustache]
When you're using one of these templating engines with the default configuration, your
templates will be picked up automatically from `src/main/resources/templates`.
[[boot-features-webflux-error-handling]]
==== Error Handling
Spring Boot provides a `WebExceptionHandler` that handles all errors in a sensible way;
it is ordered right before the ones provided by WebFlux, which are considered as last
resort. For machine clients it will produce a JSON response with details of the error,
the HTTP status and the exception message. For browser clients there is a '`whitelabel`'
error handler that renders the same data in HTML format. You can also provide your own
HTML templates to display errors
(see <<boot-features-webflux-error-handling-custom-error-pages,next section>>).
The first step to customizing this feature is often about using the existing mechanism
but replacing or augmenting the error contents. For that, you can simply add a bean
of type `ErrorAttributes`.
To change the error handling behavior, you can implement `ErrorWebExceptionHandler` and
register a bean definition of that type; because a `WebExceptionHandler` is quite
low-level, Spring Boot also provides a convenient `AbstractErrorWebExceptionHandler`
to let you handle errors in a WebFlux functional way:
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
// Define constructor here
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions
.route(aPredicate, aHandler)
.andRoute(anotherPredicate, anotherHandler);
}
}
----
For a more complete picture, you can also subclass `DefaultErrorWebExceptionHandler`
directly and override specific methods.
[[boot-features-webflux-error-handling-custom-error-pages]]
===== Custom error pages
If you want to display a custom HTML error page for a given status code, you can add
a file to an `/error` folder. Error pages can either be static HTML (i.e. added under
any of the static resource folders) or built using templates. The name of the file
should be the exact status code or a series mask.
For example, to map `404` to a static HTML file, your folder structure would look like
this:
[source,indent=0,subs="verbatim,quotes,attributes"]
----
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
----
To map all `5xx` errors using a Mustache template, you'd have a structure like this:
[source,indent=0,subs="verbatim,quotes,attributes"]
----
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.mustache
+- <other templates>
----
[[boot-features-jersey]]
=== JAX-RS and Jersey
If you prefer the JAX-RS programming model for REST endpoints you can use one of the
available implementations instead of Spring MVC. Jersey 1.x and Apache CXF work quite
well out of the box if you just register their `Servlet` or `Filter` as a `@Bean` in your
application context. Jersey 2.x has some native Spring support so we also provide
auto-configuration support for it in Spring Boot together with a starter.
To get started with Jersey 2.x just include the `spring-boot-starter-jersey` as a
dependency and then you need one `@Bean` of type `ResourceConfig` in which you register
all the endpoints:
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(Endpoint.class);
}
}
----
WARNING: Jersey's support for scanning executable archives is rather limited. For example,
it cannot scan for endpoints in a package found in `WEB-INF/classes` when running an
executable war file. To avoid this limitation, the `packages` method should not be used
and endpoints should be registered individually using the `register` method as shown
above.
You can also register an arbitrary number of beans implementing `ResourceConfigCustomizer`
for more advanced customizations.
All the registered endpoints should be `@Components` with HTTP resource annotations
(`@GET` etc.), e.g.
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
@Component
@Path("/hello")
public class Endpoint {
@GET
public String message() {
return "Hello";
}
}
----
Since the `Endpoint` is a Spring `@Component` its lifecycle is managed by Spring and you
can `@Autowired` dependencies and inject external configuration with `@Value`. The Jersey
servlet will be registered and mapped to `/*` by default. You can change the mapping
by adding `@ApplicationPath` to your `ResourceConfig`.
By default Jersey will be set up as a Servlet in a `@Bean` of type
`ServletRegistrationBean` named `jerseyServletRegistration`. By default, the servlet will
be initialized lazily but you can customize it with
`spring.jersey.servlet.load-on-startup` .You can disable or override that bean by creating
one of your own with the same name. You can also use a Filter instead of a Servlet by
setting `spring.jersey.type=filter` (in which case the `@Bean` to replace or override is
`jerseyFilterRegistration`). The servlet has an `@Order` which you can set with
`spring.jersey.filter.order`. Both the Servlet and the Filter registrations can be given
init parameters using `spring.jersey.init.*` to specify a map of properties.
There is a {github-code}/spring-boot-samples/spring-boot-sample-jersey[Jersey sample] so
you can see how to set things up. There is also a
{github-code}/spring-boot-samples/spring-boot-sample-jersey1[Jersey 1.x sample]. Note that
in the Jersey 1.x sample that the spring-boot maven plugin has been configured to unpack
some Jersey jars so they can be scanned by the JAX-RS implementation (because the sample
asks for them to be scanned in its `Filter` registration). You may need to do the same if
any of your JAX-RS resources are packaged as nested jars.
[[boot-features-embedded-container]]
=== Embedded servlet container support
Spring Boot includes support for embedded Tomcat, Jetty, and Undertow servers. Most
developers will simply use the appropriate '`Starter`' to obtain a fully configured
instance. By default the embedded server will listen for HTTP requests on port `8080`.
WARNING: If you choose to use Tomcat on CentOS be aware that, by default, a temporary
directory is used to store compiled JSPs, file uploads etc. This directory may be
deleted by `tmpwatch` while your application is running leading to failures. To avoid
this, you may want to customize your `tmpwatch` configuration so that `tomcat.*`
directories are not deleted, or configure `server.tomcat.basedir` so that embedded Tomcat
uses a different location.
[[boot-features-embedded-container-servlets-filters-listeners]]
==== Servlets, Filters, and listeners
When using an embedded servlet container you can register Servlets, Filters and all the
listeners from the Servlet spec (e.g. `HttpSessionListener`) either by using Spring beans
or by scanning for Servlet components.
[[boot-features-embedded-container-servlets-filters-listeners-beans]]
===== Registering Servlets, Filters, and listeners as Spring beans
Any `Servlet`, `Filter` or Servlet `*Listener` instance that is a Spring bean will be
registered with the embedded container. This can be particularly convenient if you want to
refer to a value from your `application.properties` during configuration.
By default, if the context contains only a single Servlet it will be mapped to `/`. In the
case of multiple Servlet beans the bean name will be used as a path prefix. Filters will
map to `+/*+`.
If convention-based mapping is not flexible enough you can use the
`ServletRegistrationBean`, `FilterRegistrationBean` and `ServletListenerRegistrationBean`
classes for complete control.
[[boot-features-embedded-container-context-initializer]]
==== Servlet Context Initialization
Embedded servlet containers will not directly execute the Servlet 3.0+
`javax.servlet.ServletContainerInitializer` interface, or Spring's
`org.springframework.web.WebApplicationInitializer` interface. This is an intentional
design decision intended to reduce the risk that 3rd party libraries designed to run
inside a war will break Spring Boot applications.
If you need to perform servlet context initialization in a Spring Boot application, you
should register a bean that implements the
`org.springframework.boot.web.servlet.ServletContextInitializer` interface. The
single `onStartup` method provides access to the `ServletContext`, and can easily be used
as an adapter to an existing `WebApplicationInitializer` if necessary.
[[boot-features-embedded-container-servlets-filters-listeners-scanning]]
===== Scanning for Servlets, Filters, and listeners
When using an embedded container, automatic registration of `@WebServlet`, `@WebFilter`,
and `@WebListener` annotated classes can be enabled using `@ServletComponentScan`.
TIP: `@ServletComponentScan` will have no effect in a standalone container, where the
container's built-in discovery mechanisms will be used instead.
[[boot-features-embedded-container-application-context]]
==== The ServletWebServerApplicationContext
Under the hood Spring Boot uses a new type of `ApplicationContext` for embedded servlet
container support. The `ServletWebServerApplicationContext` is a special type of
`WebApplicationContext` that bootstraps itself by searching for a single
`ServletWebServerFactory` bean. Usually a `TomcatServletWebServerFactory`,
`JettyServletWebServerFactory`, or `UndertowServletWebServerFactory` will
have been auto-configured.
NOTE: You usually won't need to be aware of these implementation classes. Most
applications will be auto-configured and the appropriate `ApplicationContext` and
`ServletWebServerFactory` will be created on your behalf.
[[boot-features-customizing-embedded-containers]]
==== Customizing embedded servlet containers
Common servlet container settings can be configured using Spring `Environment`
properties. Usually you would define the properties in your `application.properties`
file.
Common server settings include:
* Network settings: listen port for incoming HTTP requests (`server.port`), interface
address to bind to `server.address`, etc.
* Session settings: whether the session is persistent (`server.session.persistence`),
session timeout (`server.session.timeout`), location of session data
(`server.session.store-dir`) and session-cookie configuration (`server.session.cookie.*`).
* Error management: location of the error page (`server.error.path`), etc.
* <<howto.adoc#howto-configure-ssl,SSL>>
* <<howto.adoc#how-to-enable-http-response-compression,HTTP compression>>
Spring Boot tries as much as possible to expose common settings but this is not always
possible. For those cases, dedicated namespaces offer server-specific customizations (see
`server.tomcat` and `server.undertow`). For instance,
<<howto.adoc#howto-configure-accesslogs,access logs>> can be configured with specific
features of the embedded servlet container.
TIP: See the {sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`]
class for a complete list.
[[boot-features-programmatic-embedded-container-customization]]
===== Programmatic customization
If you need to configure your embedded servlet container programmatically you can
register a Spring bean that implements the `WebServerFactoryCustomizer` interface.
`WebServerFactoryCustomizer` provides access to the
`ConfigurableServletWebServerFactory` which includes numerous customization setter
methods. Dedicated variants exists for Tomcat, Jetty and Undertow.
[source,java,indent=0]
----
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
----
[[boot-features-customizing-configurableservletwebserverfactory-directly]]
===== Customizing ConfigurableServletWebServerFactory directly
If the above customization techniques are too limited, you can register the
`TomcatServletWebServerFactory`, `JettyServletWebServerFactory` or
`UndertowServletWebServerFactory` bean yourself.
[source,java,indent=0]
----
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}
----
Setters are provided for many configuration options. Several protected method
'`hooks`' are also provided should you need to do something more exotic. See the
source code documentation for details.
[[boot-features-jsp-limitations]]
==== JSP limitations
When running a Spring Boot application that uses an embedded servlet container (and is
packaged as an executable archive), there are some limitations in the JSP support.
* With Tomcat it should work if you use war packaging, i.e. an executable war will work,
and will also be deployable to a standard container (not limited to, but including
Tomcat). An executable jar will not work because of a hard coded file pattern in Tomcat.
* With Jetty it should work if you use war packaging, i.e. an executable war will work,
and will also be deployable to any standard container.
* Undertow does not support JSPs.
* Creating a custom `error.jsp` page won't override the default view for
<<boot-features-error-handling,error handling>>,
<<boot-features-error-handling-custom-error-pages,custom error pages>> should be used
instead.
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so you
can see how to set things up.
[[boot-features-security]]
== Security
If Spring Security is on the classpath then web applications will be secure by default
with '`basic`' authentication on all HTTP endpoints. To add method-level security to a web
application you can also add `@EnableGlobalMethodSecurity` with your desired settings.
Additional information can be found in the {spring-security-reference}#jc-method[Spring
Security Reference].
The default `AuthenticationManager` has a single user ('`user`' username and random
password, printed at INFO level when the application starts up)
[indent=0]
----
Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
----
NOTE: If you fine-tune your logging configuration, ensure that the
`org.springframework.boot.autoconfigure.security` category is set to log `INFO` messages,
otherwise the default password will not be printed.
You can change the password by providing a `security.user.password`. This and other useful
properties are externalized via
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
(properties prefix "security").
The default security configuration is implemented in `SecurityAutoConfiguration` and in
the classes imported from there (`SpringBootWebSecurityConfiguration` for web security
and `AuthenticationManagerConfiguration` for authentication configuration which is also
relevant in non-web applications). To switch off the default web application security
configuration completely you can add a bean with `@EnableWebSecurity` (this does not
disable the authentication manager configuration or Actuator's security).
To customize it you normally use external properties and beans of type
`WebSecurityConfigurerAdapter` (e.g. to add form-based login).
NOTE: If you add `@EnableWebSecurity` and also disable Actuator security, you will get
the default form-based login for the entire application unless you add a custom
`WebSecurityConfigurerAdapter`.
To also switch off the authentication manager configuration
you can add a bean of type `AuthenticationManager`, or else configure the
global `AuthenticationManager` by autowiring an `AuthenticationManagerBuilder` into
a method in one of your `@Configuration` classes. There are several secure applications in
the {github-code}/spring-boot-samples/[Spring Boot samples] to get you started with common
use cases.
The basic features you get out of the box in a web application are:
* An `AuthenticationManager` bean with in-memory store and a single user (see
`SecurityProperties.User` for the properties of the user).
* Ignored (insecure) paths for common static resource locations (`+/css/**+`, `+/js/**+`,
`+/images/**+`, `+/webjars/**+` and `+**/favicon.ico+`).
* HTTP Basic security for all other endpoints.
* Security events published to Spring's `ApplicationEventPublisher` (successful and
unsuccessful authentication and access denied).
* Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring Security are
on by default.
All of the above can be switched on and off or modified using external properties
(`+security.*+`). To override the access rules without changing any other auto-configured
features add a `@Bean` of type `WebSecurityConfigurerAdapter` with
`@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)` and configure it to meet your needs.
NOTE: By default, a `WebSecurityConfigurerAdapter` will match any path. If you don't want
to completely override Spring Boot's auto-configured access rules, your adapter must
explicitly configure the paths that you do want to override.
[[boot-features-security-oauth2]]
=== OAuth2
==== Client
If you have `spring-security-oauth2-client` on your classpath you can take advantage of
some auto-configuration to make it easy to set up an OAuth2 Client. This configuration
makes use of the properties under `OAuth2ClientProperties`.
You can register multiple OAuth2 clients and providers under the
`spring.security.oauth2.client` prefix. For example:
[source,properties,indent=0]
----
spring.security.oauth2.client.registration.my-client-1.client-id:=abcd
spring.security.oauth2.client.registration.my-client-1.client-secret=password
spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-1.scope=user
spring.security.oauth2.client.registration.my-client-1.redirect-uri=http://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.my-client-2.client-secret=password
spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-2.scope=email
spring.security.oauth2.client.registration.my-client-2.redirect-uri=http://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=http://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=http://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=http://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name
----
NOTE: For common OAuth2 and OpenID providers such as Google, Github, Facebook and Okta,
we provide a set of provider defaults. If you don't need to customize these providers, you
do not need to provide the `provider` configuration. The client registration `provider`
key should reference one these providers.
[[boot-features-security-actuator]]
=== Actuator Security
If the Actuator is also in use, you will find:
* The management endpoints are secure even if the application endpoints are insecure.
* Security events are transformed into `AuditEvent` instances and published to the
`AuditEventRepository`.
* The default user will have the `ACTUATOR` role as well as the `USER` role.
The Actuator security features can be modified using external properties
(`+management.security.*+`). To override the application access rules
add a `@Bean` of type `WebSecurityConfigurerAdapter` and use
`@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)` if you _don't_ want to override
the actuator access rules, or `@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)`
if you _do_ want to override the actuator access rules.
[[boot-features-sql]]
== Working with SQL databases
The Spring Framework provides extensive support for working with SQL databases. From
direct JDBC access using `JdbcTemplate` to complete '`object relational mapping`'
technologies such as Hibernate. Spring Data provides an additional level of functionality,
creating `Repository` implementations directly from interfaces and using conventions to
generate queries from your method names.
[[boot-features-configure-datasource]]
=== Configure a DataSource
Java's `javax.sql.DataSource` interface provides a standard method of working with
database connections. Traditionally a DataSource uses a `URL` along with some
credentials to establish a database connection.
TIP: Check also <<howto.adoc#howto-configure-a-datasource,the '`How-to`' section>> for more
advanced examples, typically to take full control over the configuration of the
DataSource.
[[boot-features-embedded-database-support]]
==== Embedded Database Support
It's often convenient to develop applications using an in-memory embedded database.
Obviously, in-memory databases do not provide persistent storage; you will need to
populate your database when your application starts and be prepared to throw away
data when your application ends.
TIP: The '`How-to`' section includes a _<<howto.adoc#howto-database-initialization,
section on how to initialize a database>>_
Spring Boot can auto-configure embedded http://www.h2database.com[H2],
http://hsqldb.org/[HSQL] and http://db.apache.org/derby/[Derby] databases. You don't need
to provide any connection URLs, simply include a build dependency to the embedded database
that you want to use.
[NOTE]
====
If you are using this feature in your tests, you may notice that the same database is
reused by your whole test suite regardless of the number of application contexts that
you use. If you want to make sure that each context has a separate embedded database,
you should set `spring.datasource.generate-unique-name` to `true`.
====
For example, typical POM dependencies would be:
[source,xml,indent=0]
----
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
----
NOTE: You need a dependency on `spring-jdbc` for an embedded database to be
auto-configured. In this example it's pulled in transitively via
`spring-boot-starter-data-jpa`.
TIP: If, for whatever reason, you do configure the connection URL for an embedded
database, care should be taken to ensure that the database's automatic shutdown is
disabled. If you're using H2 you should use `DB_CLOSE_ON_EXIT=FALSE` to do so. If you're
using HSQLDB, you should ensure that `shutdown=true` is not used. Disabling the database's
automatic shutdown allows Spring Boot to control when the database is closed, thereby
ensuring that it happens once access to the database is no longer needed.
[[boot-features-connect-to-production-database]]
==== Connection to a production database
Production database connections can also be auto-configured using a pooling `DataSource`.
Here's the algorithm for choosing a specific implementation:
* We prefer HikariCP for its performance and concurrency, so if that is available we
always choose it.
* Otherwise, if the Tomcat pooling `DataSource` is available we will use it.
* If neither HikariCP nor the Tomcat pooling datasource are available and if Commons
DBCP2 is available we will use it.
If you use the `spring-boot-starter-jdbc` or `spring-boot-starter-data-jpa`
'`starters`' you will automatically get a dependency to `HikariCP`.
NOTE: You can bypass that algorithm completely and specify the connection pool to use via
the `spring.datasource.type` property. This is especially important if you are running
your application in a Tomcat container as `tomcat-jdbc` is provided by default.
TIP: Additional connection pools can always be configured manually. If you define your
own `DataSource` bean, auto-configuration will not occur.
DataSource configuration is controlled by external configuration properties in
`+spring.datasource.*+`. For example, you might declare the following section in
`application.properties`:
[source,properties,indent=0]
----
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
----
NOTE: You should at least specify the url using the `spring.datasource.url` property or
Spring Boot will attempt to auto-configure an embedded database.
TIP: You often won't need to specify the `driver-class-name` since Spring boot can deduce
it for most databases from the `url`.
NOTE: For a pooling `DataSource` to be created we need to be able to verify that a valid
`Driver` class is available, so we check for that before doing anything. I.e. if you set
`spring.datasource.driver-class-name=com.mysql.jdbc.Driver` then that class has to be
loadable.
See {sc-spring-boot-autoconfigure}/jdbc/DataSourceProperties.{sc-ext}[`DataSourceProperties`]
for more of the supported options. These are the standard options that work regardless of
the actual implementation. It is also possible to fine-tune implementation-specific
settings using their respective prefix (`+spring.datasource.hikari.*+`,
`+spring.datasource.tomcat.*+`, and `+spring.datasource.dbcp2.*+`). Refer to the
documentation of the connection pool implementation you are using for more details.
For instance, if you are using the
http://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html#Common_Attributes[Tomcat connection pool]
you could customize many additional settings:
[source,properties,indent=0]
----
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=10000
# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50
# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true
----
[[boot-features-connecting-to-a-jndi-datasource]]
==== Connection to a JNDI DataSource
If you are deploying your Spring Boot application to an Application Server you might want
to configure and manage your DataSource using your Application Servers built-in features
and access it using JNDI.
The `spring.datasource.jndi-name` property can be used as an alternative to the
`spring.datasource.url`, `spring.datasource.username` and `spring.datasource.password`
properties to access the `DataSource` from a specific JNDI location. For example, the
following section in `application.properties` shows how you can access a JBoss AS defined
`DataSource`:
[source,properties,indent=0]
----
spring.datasource.jndi-name=java:jboss/datasources/customers
----
[[boot-features-using-jdbc-template]]
=== Using JdbcTemplate
Spring's `JdbcTemplate` and `NamedParameterJdbcTemplate` classes are auto-configured and
you can `@Autowire` them directly into your own beans:
[source,java,indent=0]
----
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JdbcTemplate jdbcTemplate;
@Autowired
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// ...
}
----
You can customize some properties of the template using the `spring.jdbc.template.*`
properties:
[source,properties,indent=0]
----
spring.jdbc.template.max-rows=500
----
TIP: The `NamedParameterJdbcTemplate` reuses the same `JdbcTemplate` instance behind the
scene. If more than one `JdbcTemplate` is defined and no primary candidate exists, the
`NamedParameterJdbcTemplate` is not auto-configured.
[[boot-features-jpa-and-spring-data]]
=== JPA and '`Spring Data`'
The Java Persistence API is a standard technology that allows you to '`map`' objects to
relational databases. The `spring-boot-starter-data-jpa` POM provides a quick way to get
started. It provides the following key dependencies:
* Hibernate -- One of the most popular JPA implementations.
* Spring Data JPA -- Makes it easy to implement JPA-based repositories.
* Spring ORMs -- Core ORM support from the Spring Framework.
TIP: We won't go into too many details of JPA or Spring Data here. You can follow the
http://spring.io/guides/gs/accessing-data-jpa/['`Accessing Data with JPA`'] guide from
http://spring.io and read the http://projects.spring.io/spring-data-jpa/[Spring Data JPA]
and http://hibernate.org/orm/documentation/[Hibernate] reference documentation.
[[boot-features-entity-classes]]
==== Entity Classes
Traditionally, JPA '`Entity`' classes are specified in a `persistence.xml` file. With
Spring Boot this file is not necessary and instead '`Entity Scanning`' is used. By default
all packages below your main configuration class (the one annotated with
`@EnableAutoConfiguration` or `@SpringBootApplication`) will be searched.
Any classes annotated with `@Entity`, `@Embeddable` or `@MappedSuperclass` will be
considered. A typical entity class would look something like this:
[source,java,indent=0]
----
package com.example.myapp.domain;
import java.io.Serializable;
import javax.persistence.*;
@Entity
public class City implements Serializable {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
// ... additional members, often include @OneToMany mappings
protected City() {
// no-args constructor required by JPA spec
// this one is protected since it shouldn't be used directly
}
public City(String name, String state) {
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
// ... etc
}
----
TIP: You can customize entity scanning locations using the `@EntityScan` annotation. See
the _<<howto.adoc#howto-separate-entity-definitions-from-spring-configuration>>_ how-to.
[[boot-features-spring-data-jpa-repositories]]
==== Spring Data JPA Repositories
Spring Data JPA repositories are interfaces that you can define to access data. JPA
queries are created automatically from your method names. For example, a `CityRepository`
interface might declare a `findAllByState(String state)` method to find all cities in a
given state.
For more complex queries you can annotate your method using Spring Data's
{spring-data-javadoc}/repository/Query.html[`Query`] annotation.
Spring Data repositories usually extend from the
{spring-data-commons-javadoc}/repository/Repository.html[`Repository`] or
{spring-data-commons-javadoc}/repository/CrudRepository.html[`CrudRepository`] interfaces.
If you are using auto-configuration, repositories will be searched from the package
containing your main configuration class (the one annotated with
`@EnableAutoConfiguration` or `@SpringBootApplication`) down.
Here is a typical Spring Data repository:
[source,java,indent=0]
----
package com.example.myapp.domain;
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
public interface CityRepository extends Repository<City, Long> {
Page<City> findAll(Pageable pageable);
City findByNameAndCountryAllIgnoringCase(String name, String country);
}
----
TIP: We have barely scratched the surface of Spring Data JPA. For complete details check
their http://projects.spring.io/spring-data-jpa/[reference documentation].
[[boot-features-creating-and-dropping-jpa-databases]]
==== Creating and dropping JPA databases
By default, JPA databases will be automatically created *only* if you use an embedded
database (H2, HSQL or Derby). You can explicitly configure JPA settings using
`+spring.jpa.*+` properties. For example, to create and drop tables you can add the
following to your `application.properties`.
[indent=0]
----
spring.jpa.hibernate.ddl-auto=create-drop
----
NOTE: Hibernate's own internal property name for this (if you happen to remember it
better) is `hibernate.hbm2ddl.auto`. You can set it, along with other Hibernate native
properties, using `+spring.jpa.properties.*+` (the prefix is stripped before adding them
to the entity manager). Example:
[indent=0]
----
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
----
passes `hibernate.globally_quoted_identifiers` to the Hibernate entity manager.
By default the DDL execution (or validation) is deferred until the `ApplicationContext`
has started. There is also a `spring.jpa.generate-ddl` flag, but it is not used if
Hibernate autoconfig is active because the `ddl-auto` settings are more fine-grained.
[[boot-features-jpa-in-web-environment]]
==== Open EntityManager in View
If you are running a web application, Spring Boot will by default register
{spring-javadoc}/orm/jpa/support/OpenEntityManagerInViewInterceptor.html[`OpenEntityManagerInViewInterceptor`]
to apply the "Open EntityManager in View" pattern, i.e. to allow for lazy loading in web
views. If you don't want this behavior you should set `spring.jpa.open-in-view` to
`false` in your `application.properties`.
[[boot-features-sql-h2-console]]
=== Using H2's web console
The http://www.h2database.com[H2 database] provides a
http://www.h2database.com/html/quickstart.html#h2_console[browser-based console] that
Spring Boot can auto-configure for you. The console will be auto-configured when the
following conditions are met:
* You are developing a web application
* `com.h2database:h2` is on the classpath
* You are using <<using-spring-boot.adoc#using-boot-devtools,Spring Boot's developer
tools>>
TIP: If you are not using Spring Boot's developer tools, but would still like to make use
of H2's console, then you can do so by configuring the `spring.h2.console.enabled`
property with a value of `true`. The H2 console is only intended for use during
development so care should be taken to ensure that `spring.h2.console.enabled` is not set
to `true` in production.
[[boot-features-sql-h2-console-custom-path]]
==== Changing the H2 console's path
By default the console will be available at `/h2-console`. You can customize the console's
path using the `spring.h2.console.path` property.
[[boot-features-jooq]]
=== Using jOOQ
Java Object Oriented Querying (http://www.jooq.org/[jOOQ]) is a popular product from
http://www.datageekery.com/[Data Geekery] which generates Java code from your
database, and lets you build type safe SQL queries through its fluent API. Both the
commercial and open source editions can be used with Spring Boot.
==== Code Generation
In order to use jOOQ type-safe queries, you need to generate Java classes from your
database schema. You can follow the instructions in the
http://www.jooq.org/doc/3.6/manual-single-page/#jooq-in-7-steps-step3[jOOQ user manual].
If you are using the `jooq-codegen-maven` plugin (and you also use the
`spring-boot-starter-parent` "`parent POM`") you can safely omit the plugin's `<version>`
tag. You can also use Spring Boot defined version variables (e.g. `h2.version`) to
declare the plugin's database dependency. Here's an example:
[source,xml,indent=0]
----
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
...
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
<configuration>
<jdbc>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:~/yourdatabase</url>
</jdbc>
<generator>
...
</generator>
</configuration>
</plugin>
----
==== Using DSLContext
The fluent API offered by jOOQ is initiated via the `org.jooq.DSLContext` interface.
Spring Boot will auto-configure a `DSLContext` as a Spring Bean and connect it to your
application `DataSource`. To use the `DSLContext` you can just `@Autowire` it:
[source,java,indent=0]
----
@Component
public class JooqExample implements CommandLineRunner {
private final DSLContext create;
@Autowired
public JooqExample(DSLContext dslContext) {
this.create = dslContext;
}
}
----
TIP: The jOOQ manual tends to use a variable named `create` to hold the `DSLContext`,
we've done the same for this example.
You can then use the `DSLContext` to construct your queries:
[source,java,indent=0]
----
public List<GregorianCalendar> authorsBornAfter1980() {
return this.create.selectFrom(AUTHOR)
.where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
.fetch(AUTHOR.DATE_OF_BIRTH);
}
----
==== jOOQ SQL dialect
Spring Boot determines the SQL dialect to use for your datasource unless the
`spring.jooq.sql-dialect` property has been configured. If the dialect couldn't be
detected, `DEFAULT` is used.
NOTE: Spring Boot can only auto-configure dialects supported by the open source version of
jOOQ.
==== Customizing jOOQ
More advanced customizations can be achieved by defining your own `@Bean` definitions
which will be used when the jOOQ `Configuration` is created. You can define beans for
the following jOOQ Types:
* `ConnectionProvider`
* `TransactionProvider`
* `RecordMapperProvider`
* `RecordListenerProvider`
* `ExecuteListenerProvider`
* `VisitListenerProvider`
You can also create your own `org.jooq.Configuration` `@Bean` if you want to take
complete control of the jOOQ configuration.
[[boot-features-nosql]]
== Working with NoSQL technologies
Spring Data provides additional projects that help you access a variety of NoSQL
technologies including
http://projects.spring.io/spring-data-mongodb/[MongoDB],
http://projects.spring.io/spring-data-neo4j/[Neo4J],
https://github.com/spring-projects/spring-data-elasticsearch/[Elasticsearch],
http://projects.spring.io/spring-data-solr/[Solr],
http://projects.spring.io/spring-data-redis/[Redis],
http://projects.spring.io/spring-data-gemfire/[Gemfire],
http://projects.spring.io/spring-data-cassandra/[Cassandra],
http://projects.spring.io/spring-data-couchbase/[Couchbase] and
http://projects.spring.io/spring-data-ldap/[LDAP].
Spring Boot provides auto-configuration for Redis, MongoDB, Neo4j, Elasticsearch, Solr
Cassandra, Couchbase and LDAP; you can make use of the other projects, but you will need
to configure them yourself. Refer to the appropriate reference documentation at
http://projects.spring.io/spring-data[projects.spring.io/spring-data].
[[boot-features-redis]]
=== Redis
http://redis.io/[Redis] is a cache, message broker and richly-featured key-value store.
Spring Boot offers basic auto-configuration for the
https://github.com/lettuce-io/lettuce-core/[Lettuce] and
https://github.com/xetorthio/jedis/[Jedis] client library and abstractions on top of it
provided by https://github.com/spring-projects/spring-data-redis[Spring Data Redis].
There is a `spring-boot-starter-data-redis` '`Starter`' for collecting the dependencies in
a convenient way that uses https://github.com/lettuce-io/lettuce-core/[Lettuce] by
default. Both traditional and regular applications are handled by that starter.
[[boot-features-connecting-to-redis]]
==== Connecting to Redis
You can inject an auto-configured `RedisConnectionFactory`, `StringRedisTemplate` or
vanilla `RedisTemplate` instance as you would any other Spring Bean. By default the
instance will attempt to connect to a Redis server using `localhost:6379`:
[source,java,indent=0]
----
@Component
public class MyBean {
private StringRedisTemplate template;
@Autowired
public MyBean(StringRedisTemplate template) {
this.template = template;
}
// ...
}
----
TIP: You can also register an arbitrary number of beans implementing
`LettuceClientConfigurationBuilderCustomizer` for more advanced customizations. If you are
using Jedis, `JedisClientConfigurationBuilderCustomizer` is also available.
If you add a `@Bean` of your own of any of the auto-configured types it will replace the
default (except in the case of `RedisTemplate` the exclusion is based on the bean name
'`redisTemplate`' not its type). If `commons-pool2` is on the classpath you will get a
pooled connection factory by default.
[[boot-features-mongodb]]
=== MongoDB
http://www.mongodb.com/[MongoDB] is an open-source NoSQL document database that uses a
JSON-like schema instead of traditional table-based relational data. Spring Boot offers
several conveniences for working with MongoDB, including the
`spring-boot-starter-data-mongodb` and `spring-boot-starter-data-mongodb-reactive`
'`Starters`'.
[[boot-features-connecting-to-mongodb]]
==== Connecting to a MongoDB database
You can inject an auto-configured `org.springframework.data.mongodb.MongoDbFactory` to
access Mongo databases. By default the instance will attempt to connect to a MongoDB
server using the URL `mongodb://localhost/test`:
[source,java,indent=0]
----
import org.springframework.data.mongodb.MongoDbFactory;
import com.mongodb.DB;
@Component
public class MyBean {
private final MongoDbFactory mongo;
@Autowired
public MyBean(MongoDbFactory mongo) {
this.mongo = mongo;
}
// ...
public void example() {
DB db = mongo.getDb();
// ...
}
}
----
You can set `spring.data.mongodb.uri` property to change the URL and configure
additional settings such as the _replica set_:
[source,properties,indent=0]
----
spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test
----
Alternatively, as long as you're using Mongo 2.x, specify a `host`/`port`. For example,
you might declare the following in your `application.properties`:
[source,properties,indent=0]
----
spring.data.mongodb.host=mongoserver
spring.data.mongodb.port=27017
----
NOTE: `spring.data.mongodb.host` and `spring.data.mongodb.port` are not supported if
you're using the Mongo 3.0 Java driver. In such cases, `spring.data.mongodb.uri` should be
used to provide all of the configuration.
TIP: If `spring.data.mongodb.port` is not specified the default of `27017` is used. You
could simply delete this line from the sample above.
TIP: If you aren't using Spring Data Mongo you can inject `com.mongodb.Mongo` beans
instead of using `MongoDbFactory`.
You can also declare your own `MongoDbFactory` or `Mongo` bean if you want to take
complete control of establishing the MongoDB connection.
[[boot-features-mongo-template]]
==== MongoTemplate
Spring Data Mongo provides a
{spring-data-mongo-javadoc}/core/MongoTemplate.html[`MongoTemplate`] class that is very
similar in its design to Spring's `JdbcTemplate`. As with `JdbcTemplate` Spring Boot
auto-configures a bean for you to simply inject:
[source,java,indent=0]
----
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final MongoTemplate mongoTemplate;
@Autowired
public MyBean(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
// ...
}
----
See the `MongoOperations` Javadoc for complete details.
[[boot-features-spring-data-mongo-repositories]]
==== Spring Data MongoDB repositories
Spring Data includes repository support for MongoDB. As with the JPA repositories
discussed earlier, the basic principle is that queries are constructed for you
automatically based on method names.
In fact, both Spring Data JPA and Spring Data MongoDB share the same common
infrastructure; so you could take the JPA example from earlier and, assuming that `City`
is now a Mongo data class rather than a JPA `@Entity`, it will work in the same way.
[source,java,indent=0]
----
package com.example.myapp.domain;
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
public interface CityRepository extends Repository<City, Long> {
Page<City> findAll(Pageable pageable);
City findByNameAndCountryAllIgnoringCase(String name, String country);
}
----
TIP: For complete details of Spring Data MongoDB, including its rich object mapping
technologies, refer to their http://projects.spring.io/spring-data-mongodb/[reference
documentation].
[[boot-features-mongo-embedded]]
==== Embedded Mongo
Spring Boot offers auto-configuration for
https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo[Embedded Mongo]. To use
it in your Spring Boot application add a dependency on
`de.flapdoodle.embed:de.flapdoodle.embed.mongo`.
The port that Mongo will listen on can be configured using the `spring.data.mongodb.port`
property. To use a randomly allocated free port use a value of zero. The `MongoClient`
created by `MongoAutoConfiguration` will be automatically configured to use the randomly
allocated port.
NOTE: If you do not configure a custom port, the embedded support will use a random port
by default (rather than 27017).
If you have SLF4J on the classpath, output produced by Mongo will be automatically routed
to a logger named `org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo`.
You can declare your own `IMongodConfig` and `IRuntimeConfig` beans to take control of the
Mongo instance's configuration and logging routing.
[[boot-features-neo4j]]
=== Neo4j
http://neo4j.com/[Neo4j] is an open-source NoSQL graph database that uses a rich data
model of nodes related by first class relationships which is better suited for connected
big data than traditional rdbms approaches. Spring Boot offers several conveniences for
working with Neo4j, including the `spring-boot-starter-data-neo4j` '`Starter`'.
[[boot-features-connecting-to-neo4j]]
==== Connecting to a Neo4j database
You can inject an auto-configured `Neo4jSession`, `Session` or `Neo4jOperations` instance
as you would any other Spring Bean. By default the instance will attempt to connect to a
Neo4j server using `localhost:7474`:
[source,java,indent=0]
----
@Component
public class MyBean {
private final Neo4jTemplate neo4jTemplate;
@Autowired
public MyBean(Neo4jTemplate neo4jTemplate) {
this.neo4jTemplate = neo4jTemplate;
}
// ...
}
----
You can take full control of the configuration by adding a
`org.neo4j.ogm.config.Configuration` `@Bean` of your own. Also, adding a `@Bean` of type
`Neo4jOperations` disables the auto-configuration.
You can configure the user and credentials to use via the `spring.data.neo4j.*`
properties:
[source,properties,indent=0]
----
spring.data.neo4j.uri=http://my-server:7474
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret
----
[[boot-features-connecting-to-neo4j-embedded]]
==== Using the embedded mode
If you add `org.neo4j:neo4j-ogm-embedded-driver` to the dependencies of your application,
Spring Boot will automatically configure an in-process embedded instance of Neo4j that
will not persist any data when your application shuts down. You can explicitly disable
that mode using `spring.data.neo4j.embedded.enabled=false`. You can also enable
persistence for the embedded mode:
----
spring.data.neo4j.uri=file://var/tmp/graph.db
----
[NOTE]
====
The Neo4j OGM embedded driver does not provide the Neo4j kernel. Users are expected to
provide this dependency manually, see
http://neo4j.com/docs/ogm-manual/current/reference/#reference:getting-started[the documentation]
for more details.
====
[[boot-features-neo4j-ogm-session]]
==== Neo4jSession
By default, if you are running a web application, the session is bound to the thread for
the entire processing of the request (i.e. the "Open Session in View" pattern). If you
don't want this behavior add the following to your `application.properties`:
----
spring.data.neo4j.open-in-view=false
----
[[boot-features-spring-data-neo4j-repositories]]
==== Spring Data Neo4j repositories
Spring Data includes repository support for Neo4j.
In fact, both Spring Data JPA and Spring Data Neo4j share the same common
infrastructure; so you could take the JPA example from earlier and, assuming that `City`
is now a Neo4j OGM `@NodeEntity` rather than a JPA `@Entity`, it will work in the same
way.
TIP: You can customize entity scanning locations using the `@EntityScan` annotation.
To enable repository support (and optionally support for `@Transactional`), add the
following two annotations to your Spring configuration:
[source,java,indent=0]
----
@EnableNeo4jRepositories(basePackages = "com.example.myapp.repository")
@EnableTransactionManagement
----
==== Repository example
[source,java,indent=0]
----
package com.example.myapp.domain;
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
public interface CityRepository extends GraphRepository<City> {
Page<City> findAll(Pageable pageable);
City findByNameAndCountry(String name, String country);
}
----
TIP: For complete details of Spring Data Neo4j, including its rich object mapping
technologies, refer to their http://projects.spring.io/spring-data-neo4j/[reference
documentation].
[[boot-features-gemfire]]
=== Gemfire
https://github.com/spring-projects/spring-data-gemfire[Spring Data Gemfire] provides
convenient Spring-friendly tools for accessing the
http://pivotal.io/big-data/pivotal-gemfire#details[Pivotal Gemfire] data management
platform. There is a `spring-boot-starter-data-gemfire` '`Starter`' for collecting the
dependencies in a convenient way. There is currently no auto-configuration support for
Gemfire, but you can enable Spring Data Repositories with a
https://github.com/spring-projects/spring-data-gemfire/blob/master/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java[single annotation (`@EnableGemfireRepositories`)].
[[boot-features-solr]]
=== Solr
http://lucene.apache.org/solr/[Apache Solr] is a search engine. Spring Boot offers basic
auto-configuration for the Solr 5 client library and abstractions on top of it provided by
https://github.com/spring-projects/spring-data-solr[Spring Data Solr]. There is
a `spring-boot-starter-data-solr` '`Starter`' for collecting the dependencies in a
convenient way.
[[boot-features-connecting-to-solr]]
==== Connecting to Solr
You can inject an auto-configured `SolrClient` instance as you would any other Spring
bean. By default the instance will attempt to connect to a server using
`http://localhost:8983/solr`:
[source,java,indent=0]
----
@Component
public class MyBean {
private SolrClient solr;
@Autowired
public MyBean(SolrClient solr) {
this.solr = solr;
}
// ...
}
----
If you add a `@Bean` of your own of type `SolrClient` it will replace the default.
[[boot-features-spring-data-solr-repositories]]
==== Spring Data Solr repositories
Spring Data includes repository support for Apache Solr. As with the JPA repositories
discussed earlier, the basic principle is that queries are constructed for you
automatically based on method names.
In fact, both Spring Data JPA and Spring Data Solr share the same common infrastructure;
so you could take the JPA example from earlier and, assuming that `City` is now a
`@SolrDocument` class rather than a JPA `@Entity`, it will work in the same way.
TIP: For complete details of Spring Data Solr, refer to their
http://projects.spring.io/spring-data-solr/[reference documentation].
[[boot-features-elasticsearch]]
=== Elasticsearch
http://www.elasticsearch.org/[Elasticsearch] is an open source, distributed,
real-time search and analytics engine. Spring Boot offers basic auto-configuration for
the Elasticsearch and abstractions on top of it provided by
https://github.com/spring-projects/spring-data-elasticsearch[Spring Data Elasticsearch].
There is a `spring-boot-starter-data-elasticsearch` '`Starter`' for collecting the
dependencies in a convenient way. Spring Boot also supports
https://github.com/searchbox-io/Jest[Jest].
[[boot-features-connecting-to-elasticsearch-jest]]
==== Connecting to Elasticsearch using Jest
If you have `Jest` on the classpath, you can inject an auto-configured `JestClient`
targeting `http://localhost:9200` by default. You can further tune how the client is
configured:
[source,properties,indent=0]
----
spring.elasticsearch.jest.uris=http://search.example.com:9200
spring.elasticsearch.jest.read-timeout=10000
spring.elasticsearch.jest.username=user
spring.elasticsearch.jest.password=secret
----
You can also register an arbitrary number of beans implementing
`HttpClientConfigBuilderCustomizer` for more advanced customizations. The example below
tunes additional HTTP settings:
[source,java,indent=0]
----
include::{code-examples}/elasticsearch/jest/JestClientCustomizationExample.java[tag=customizer]
----
To take full control over the registration, define a `JestClient` bean.
[[boot-features-connecting-to-elasticsearch-spring-data]]
==== Connecting to Elasticsearch using Spring Data
To connect to Elasticsearch you must provide the address of one or more cluster nodes.
The address can be specified by setting the `spring.data.elasticsearch.cluster-nodes`
property to a comma-separated '`host:port`' list. With this configuration in place, an
`ElasticsearchTemplate` or `TransportClient` can be injected like any other Spring bean:
[source,properties,indent=0]
----
spring.data.elasticsearch.cluster-nodes=localhost:9300
----
[source,java,indent=0]
----
@Component
public class MyBean {
private final ElasticsearchTemplate template;
public MyBean(ElasticsearchTemplate template) {
this.template = template;
}
// ...
}
----
If you add your own `ElasticsearchTemplate` or `TransportClient` `@Bean` it will
replace the default.
[[boot-features-spring-data-elasticsearch-repositories]]
==== Spring Data Elasticsearch repositories
Spring Data includes repository support for Elasticsearch. As with the JPA repositories
discussed earlier, the basic principle is that queries are constructed for you
automatically based on method names.
In fact, both Spring Data JPA and Spring Data Elasticsearch share the same common
infrastructure; so you could take the JPA example from earlier and, assuming that
`City` is now an Elasticsearch `@Document` class rather than a JPA `@Entity`, it will
work in the same way.
TIP: For complete details of Spring Data Elasticsearch, refer to their
http://docs.spring.io/spring-data/elasticsearch/docs/[reference documentation].
[[boot-features-cassandra]]
=== Cassandra
http://cassandra.apache.org/[Cassandra] is an open source, distributed database management
system designed to handle large amounts of data across many commodity servers. Spring Boot
offers auto-configuration for Cassandra and abstractions on top of it provided by
https://github.com/spring-projects/spring-data-cassandra[Spring Data Cassandra].
There is a `spring-boot-starter-data-cassandra` '`Starter`' for collecting the
dependencies in a convenient way.
[[boot-features-connecting-to-cassandra]]
==== Connecting to Cassandra
You can inject an auto-configured `CassandraTemplate` or a Cassandra `Session`
instance as you would with any other Spring Bean. The `spring.data.cassandra.*`
properties can be used to customize the connection. Generally you will provide
`keyspace-name` and `contact-points` properties:
[source,properties,indent=0]
----
spring.data.cassandra.keyspace-name=mykeyspace
spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2
----
[source,java,indent=0]
----
@Component
public class MyBean {
private CassandraTemplate template;
@Autowired
public MyBean(CassandraTemplate template) {
this.template = template;
}
// ...
}
----
If you add a `@Bean` of your own of type `CassandraTemplate` it will replace the
default.
[[boot-features-spring-data-cassandra-repositories]]
==== Spring Data Cassandra repositories
Spring Data includes basic repository support for Cassandra. Currently this is more
limited than the JPA repositories discussed earlier, and will need to annotate finder
methods with `@Query`.
TIP: For complete details of Spring Data Cassandra, refer to their
http://docs.spring.io/spring-data/cassandra/docs/[reference documentation].
[[boot-features-couchbase]]
=== Couchbase
http://www.couchbase.com/[Couchbase] is an open-source, distributed multi-model NoSQL
document-oriented database that is optimized for interactive applications. Spring Boot
offers auto-configuration for Couchbase and abstractions on top of it provided by
https://github.com/spring-projects/spring-data-couchbase[Spring Data Couchbase].
There is a `spring-boot-starter-data-couchbase` '`Starter`' for collecting the
dependencies in a convenient way.
[[boot-features-connecting-to-couchbase]]
==== Connecting to Couchbase
You can very easily get a `Bucket` and `Cluster` by adding the Couchbase SDK and some
configuration. The `spring.couchbase.*` properties can be used to customize the
connection. Generally you will provide the bootstrap hosts, bucket name and password:
[source,properties,indent=0]
----
spring.couchbase.bootstrap-hosts=my-host-1,192.168.1.123
spring.couchbase.bucket.name=my-bucket
spring.couchbase.bucket.password=secret
----
[TIP]
====
You need to provide _at least_ the bootstrap host(s), in which case the bucket name
is `default` and the password is the empty String. Alternatively, you can define your
own `org.springframework.data.couchbase.config.CouchbaseConfigurer` `@Bean` to take
control over the whole configuration.
====
It is also possible to customize some of the `CouchbaseEnvironment` settings. For instance
the following configuration changes the timeout to use to open a new `Bucket` and enables
SSL support:
[source,properties,indent=0]
----
spring.couchbase.env.timeouts.connect=3000
spring.couchbase.env.ssl.key-store=/location/of/keystore.jks
spring.couchbase.env.ssl.key-store-password=secret
----
Check the `spring.couchbase.env.*` properties for more details.
[[boot-features-spring-data-couchbase-repositories]]
==== Spring Data Couchbase repositories
Spring Data includes repository support for Couchbase. For complete details of Spring
Data Couchbase, refer to their
http://docs.spring.io/spring-data/couchbase/docs/current/reference/html/[reference documentation].
You can inject an auto-configured `CouchbaseTemplate` instance as you would with any
other Spring Bean as long as a _default_ `CouchbaseConfigurer` is available (that
happens when you enable the couchbase support as explained above).
[source,java,indent=0]
----
@Component
public class MyBean {
private final CouchbaseTemplate template;
@Autowired
public MyBean(CouchbaseTemplate template) {
this.template = template;
}
// ...
}
----
There are a few beans that you can define in your own configuration to override those
provided by the auto-configuration:
* A `CouchbaseTemplate` `@Bean` with name `couchbaseTemplate`
* An `IndexManager` `@Bean` with name `couchbaseIndexManager`
* A `CustomConversions` `@Bean` with name `couchbaseCustomConversions`
To avoid hard-coding those names in your own config, you can reuse `BeanNames` provided
by Spring Data Couchbase. For instance, you can customize the converters to use as
follows:
[source,java,indent=0]
----
@Configuration
public class SomeConfiguration {
@Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
public CustomConversions myCustomConversions() {
return new CustomConversions(...);
}
// ...
}
----
TIP: If you want to fully bypass the auto-configuration for Spring Data Couchbase, provide
your own `org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration`
implementation.
[[boot-features-ldap]]
=== LDAP
https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol[LDAP] (Lightweight
Directory Access Protocol) is an open, vendor-neutral, industry standard application
protocol for accessing and maintaining distributed directory information services over an
IP network. Spring Boot offers auto-configuration for any compliant LDAP server as well
as support for the embedded in-memory LDAP server from
https://www.ldap.com/unboundid-ldap-sdk-for-java[UnboundID].
LDAP abstractions are provided by
https://github.com/spring-projects/spring-data-ldap[Spring Data LDAP].
There is a `spring-boot-starter-data-ldap` '`Starter`' for collecting the dependencies in
a convenient way.
[[boot-features-ldap-connecting]]
==== Connecting to an LDAP server
To connect to an LDAP server make sure you declare a dependency on the
`spring-boot-starter-data-ldap` '`Starter`' or `spring-ldap-core` then declare the
URLs of your server in your application.properties:
[source,properties,indent=0]
----
spring.ldap.urls=ldap://myserver:1235
spring.ldap.username=admin
spring.ldap.password=secret
----
If you need to customize connection settings you can use the `spring.ldap.base` and
`spring.ldap.base-environment` properties.
[[boot-features-ldap-spring-data-repositories]]
==== Spring Data LDAP repositories
Spring Data includes repository support for LDAP. For complete details of Spring
Data LDAP, refer to their
http://docs.spring.io/spring-data/ldap/docs/1.0.x/reference/html/[reference documentation].
You can also inject an auto-configured `LdapTemplate` instance as you would with any
other Spring Bean.
[source,java,indent=0]
----
@Component
public class MyBean {
private final LdapTemplate template;
@Autowired
public MyBean(LdapTemplate template) {
this.template = template;
}
// ...
}
----
[[boot-features-ldap-embedded]]
==== Embedded in-memory LDAP server
For testing purposes Spring Boot supports auto-configuration of an in-memory LDAP server
from https://www.ldap.com/unboundid-ldap-sdk-for-java[UnboundID]. To configure the server
add a dependency to `com.unboundid:unboundid-ldapsdk` and declare a `base-dn` property:
[source,properties,indent=0]
----
spring.ldap.embedded.base-dn=dc=spring,dc=io
----
By default the server will start on a random port and they trigger the regular LDAP support
(there is no need to specify a `spring.ldap.urls` property).
If there is a `schema.ldif` file on your classpath it will be used to initialize the
server. You can also use the `spring.ldap.embedded.ldif` property if you want to load
the initialization script from a different resource.
By default, a standard schema will be used to validate `LDIF` files, you can turn off
validation altogether using the `spring.ldap.embedded.validation.enabled` property. If
you have custom attributes, you can use `spring.ldap.embedded.validation.schema` to define
your custom attribute types or object classes.
[[boot-features-influxdb]]
=== InfluxDB
https://www.influxdata.com/[InfluxDB] is an open-source time series database optimized for
fast, high-availability storage and retrieval of time series data in fields such as
operations monitoring, application metrics, Internet of Things sensor data, and real-time
analytics.
[[boot-features-connecting-to-influxdb]]
==== Connecting to InfluxDB
Spring Boot auto-configures an `InfluxDB` instance as long as the `influxdb-java` client
is on the classpath and the url of the database is set:
[source,properties,indent=0]
----
spring.influx.url=http://172.0.0.1:8086
----
If the connection to InfluxDB requires a user and password, you can set the
`spring.influx.user` and `spring.influx.password` properties accordingly.
InfluxDB relies on OkHttp. If you need to tune the http client `InfluxDB` uses behind the
scenes, you can register an `OkHttpClient.Builder` bean.
[[boot-features-caching]]
== Caching
The Spring Framework provides support for transparently adding caching to an application.
At its core, the abstraction applies caching to methods, reducing thus the number of
executions based on the information available in the cache. The caching logic is applied
transparently, without any interference to the invoker. Spring Boot auto-configures the
cache infrastructure as long as the caching support is enabled via the `@EnableCaching`
annotation.
NOTE: Check the {spring-reference}integration.html#cache[relevant section] of the Spring Framework
reference for more details.
In a nutshell, adding caching to an operation of your service is as easy as adding the
relevant annotation to its method:
[source,java,indent=0]
----
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Component;
@Component
public class MathService {
@Cacheable("piDecimals")
public int computePiDecimal(int i) {
// ...
}
}
----
This example demonstrates the use of caching on a potentially costly operation. Before
invoking `computePiDecimal`, the abstraction will look for an entry in the `piDecimals`
cache matching the `i` argument. If an entry is found, the content in the cache is
immediately returned to the caller and the method is not invoked. Otherwise, the method is
invoked and the cache is updated before returning the value.
NOTE: You can also use the standard JSR-107 (JCache) annotations (e.g. `@CacheResult`)
transparently. We strongly advise you however to not mix and match them.
If you do not add any specific cache library, Spring Boot will auto-configure a
<<boot-features-caching-provider-simple,Simple provider>> that uses concurrent maps in
memory. When a cache is required (i.e. `piDecimals` in the example above), this provider
will create it on-the-fly for you. The simple provider is not really recommended for
production usage, but it's great for getting started and making sure that you understand
the features. When you have made up your mind about the cache provider to use, please make
sure to read its documentation to figure out how to configure the caches that your
application uses. Practically all providers require you to explicitly configure every
cache that you use in the application. Some offer a way to customize the default caches
defined by the `spring.cache.cache-names` property.
TIP: It is also possible to {spring-reference}integration.html#cache-annotations-put[update] or
{spring-reference}integration.html#cache-annotations-evict[evict] data from the cache transparently.
NOTE: If you are using the cache infrastructure with beans that are not interface-based,
make sure to enable the `proxyTargetClass` attribute of `@EnableCaching`.
=== Supported cache providers
The cache abstraction does not provide an actual store and relies on abstraction
materialized by the `org.springframework.cache.Cache` and
`org.springframework.cache.CacheManager` interfaces.
If you haven't defined a bean of type `CacheManager` or a `CacheResolver` named
`cacheResolver` (see `CachingConfigurer`), Spring Boot tries to detect the following
providers (in this order):
* <<boot-features-caching-provider-generic,Generic>>
* <<boot-features-caching-provider-jcache,JCache (JSR-107)>> (EhCache 3, Hazelcast,
Infinispan, etc)
* <<boot-features-caching-provider-ehcache2,EhCache 2.x>>
* <<boot-features-caching-provider-hazelcast,Hazelcast>>
* <<boot-features-caching-provider-infinispan,Infinispan>>
* <<boot-features-caching-provider-couchbase,Couchbase>>
* <<boot-features-caching-provider-redis,Redis>>
* <<boot-features-caching-provider-caffeine,Caffeine>>
* <<boot-features-caching-provider-simple,Simple>>
TIP: It is also possible to _force_ the cache provider to use via the `spring.cache.type`
property. Use this property if you need to <<boot-features-caching-provider-none,disable
caching altogether>> in certain environment (e.g. tests).
TIP: Use the `spring-boot-starter-cache` '`Starter`' to quickly add basic caching
dependencies. The starter brings in `spring-context-support`: if you are adding
dependencies manually, you must include `spring-context-support` in order to use the
JCache, EhCache 2.x or Guava support.
If the `CacheManager` is auto-configured by Spring Boot, you can further tune its
configuration before it is fully initialized by exposing a bean implementing the
`CacheManagerCustomizer` interface. The following sets a flag to say that null
values should be passed down to the underlying map.
[source,java,indent=0]
----
@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setAllowNullValues(false);
}
};
}
----
[NOTE]
====
In the example above, an auto-configured `ConcurrentMapCacheManager` is expected. If that
is not the case (either you provided your own config or a different cache provider was
auto-configured), the customizer won't be invoked at all. You can have as many customizers
as you want and you can also order them as usual using `@Order` or `Ordered`.
====
[[boot-features-caching-provider-generic]]
==== Generic
Generic caching is used if the context defines _at least_ one
`org.springframework.cache.Cache` bean. A `CacheManager` wrapping all beans of that type
is created.
[[boot-features-caching-provider-jcache]]
==== JCache (JSR-107)
JCache is bootstrapped via the presence of a `javax.cache.spi.CachingProvider` on the
classpath (i.e. a JSR-107 compliant caching library) and the `JCacheCacheManager`
provided by the `spring-boot-starter-cache` '`Starter`'. There are various compliant
libraries out there and Spring Boot provides dependency management for Ehcache 3,
Hazelcast and Infinispan. Any other compliant library can be added as well.
It might happen that more than one provider is present, in which case the provider must
be explicitly specified. Even if the JSR-107 standard does not enforce a standardized
way to define the location of the configuration file, Spring Boot does its best to
accommodate with implementation details.
[source,properties,indent=0]
----
# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
----
NOTE: Since a cache library may offer both a native implementation and JSR-107 support
Spring Boot will prefer the JSR-107 support so that the same features are available if
you switch to a different JSR-107 implementation.
TIP: Spring Boot has a <<boot-features-hazelcast,general support for Hazelcast>>. If
a single `HazelcastInstance` is available, it is automatically reused for the
`CacheManager` as well unless the `spring.cache.jcache.config` property is specified.
There are several ways to customize the underlying `javax.cache.cacheManager`:
* Caches can be created on startup via the `spring.cache.cache-names` property. If a
custom `javax.cache.configuration.Configuration` bean is defined, it is used to
customize them.
* `org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer` beans are
invoked with the reference of the `CacheManager` for full customization.
TIP: If a standard `javax.cache.CacheManager` bean is defined, it is wrapped
automatically in an `org.springframework.cache.CacheManager` implementation that the
abstraction expects. No further customization is applied on it.
[[boot-features-caching-provider-ehcache2]]
==== EhCache 2.x
EhCache 2.x is used if a file named `ehcache.xml` can be found at the root of the
classpath. If EhCache 2.x, the `EhCacheCacheManager` provided by the
`spring-boot-starter-cache` '`Starter`' and such file is present it is used to bootstrap
the cache manager. An alternate configuration file can be provided as well using:
[source,properties,indent=0]
----
spring.cache.ehcache.config=classpath:config/another-config.xml
----
[[boot-features-caching-provider-hazelcast]]
==== Hazelcast
Spring Boot has a <<boot-features-hazelcast,general support for Hazelcast>>. If
a `HazelcastInstance` has been auto-configured, it is automatically wrapped in a
`CacheManager`.
[[boot-features-caching-provider-infinispan]]
==== Infinispan
Infinispan has no default configuration file location so it must be specified explicitly
(or the default bootstrap is used).
[source,properties,indent=0]
----
spring.cache.infinispan.config=infinispan.xml
----
Caches can be created on startup via the `spring.cache.cache-names` property. If a custom
`ConfigurationBuilder` bean is defined, it is used to customize them.
[NOTE]
====
The support of Infinispan in Spring Boot is restricted to the embedded mode and is quite
basic. If you want more options you should use the official Infinispan Spring Boot starter
instead, check
https://github.com/infinispan/infinispan-spring-boot[the documentation] for more details.
====
[[boot-features-caching-provider-couchbase]]
==== Couchbase
If the Couchbase java client and the `couchbase-spring-cache` implementation are
available and Couchbase is <<boot-features-couchbase,configured>>, a
`CouchbaseCacheManager` will be auto-configured. It is also possible to create additional
caches on startup using the `spring.cache.cache-names` property. These will operate on
the `Bucket` that was auto-configured. You can _also_ create additional caches on another
`Bucket` using the customizer: assume you need two caches on the "main" `Bucket` (`foo`
and `bar`) and one `biz` cache with a custom time to live of 2sec on the `another`
`Bucket`. First, you can create the two first caches simply via configuration:
[source,properties,indent=0]
----
spring.cache.cache-names=foo,bar
----
Then define this extra `@Configuration` to configure the extra `Bucket` and the `biz`
cache:
[source,java,indent=0]
----
@Configuration
public class CouchbaseCacheConfiguration {
private final Cluster cluster;
public CouchbaseCacheConfiguration(Cluster cluster) {
this.cluster = cluster;
}
@Bean
public Bucket anotherBucket() {
return this.cluster.openBucket("another", "secret");
}
@Bean
public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
return c -> {
c.prepareCache("biz", CacheBuilder.newInstance(anotherBucket())
.withExpiration(2));
};
}
}
----
This sample configuration reuses the `Cluster` that was created via auto-configuration.
[[boot-features-caching-provider-redis]]
==== Redis
If Redis is available and configured, the `RedisCacheManager` is auto-configured. It is
also possible to create additional caches on startup using the `spring.cache.cache-names`
property.
[NOTE]
====
By default, a key prefix is added to prevent that if two separate caches use the same
key, Redis would have overlapping keys and be likely to return invalid values. We strongly
recommend to keep this setting enabled if you create your own `RedisCacheManager`.
====
[[boot-features-caching-provider-caffeine]]
==== Caffeine
Caffeine is a Java 8 rewrite of Guava's cache that supersede the Guava support. If
Caffeine is present, a `CaffeineCacheManager` (provided by the
`spring-boot-starter-cache` '`Starter`') is auto-configured. Caches can be created
on startup using the `spring.cache.cache-names` property and customized by one of the
following (in this order):
1. A cache spec defined by `spring.cache.caffeine.spec`
2. A `com.github.benmanes.caffeine.cache.CaffeineSpec` bean is defined
3. A `com.github.benmanes.caffeine.cache.Caffeine` bean is defined
For instance, the following configuration creates a `foo` and `bar` caches with a maximum
size of 500 and a _time to live_ of 10 minutes
[source,properties,indent=0]
----
spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
----
Besides, if a `com.github.benmanes.caffeine.cache.CacheLoader` bean is defined, it is
automatically associated to the `CaffeineCacheManager`. Since the `CacheLoader` is
going to be associated to _all_ caches managed by the cache manager, it must be defined
as `CacheLoader<Object, Object>`. Any other generic type will be ignored by the
auto-configuration.
[[boot-features-caching-provider-simple]]
==== Simple
If none of the other providers can be found, a simple implementation using a
`ConcurrentHashMap` as cache store is configured. This is the default if no caching
library is present in your application. Caches are created on-the-fly by default but you
can restrict the list of available caches using the `cache-names` property. For instance,
if you want only `foo` and `bar` caches:
[source,properties,indent=0]
----
spring.cache.cache-names=foo,bar
----
If you do this and your application uses a cache not listed then it will fail at runtime
when the cache is needed, but not on startup. This is similar to the way the "real" cache
providers behave if you use an undeclared cache.
[[boot-features-caching-provider-none]]
==== None
When `@EnableCaching` is present in your configuration, a suitable cache configuration
is expected as well. If you need to disable caching altogether in certain environments,
force the cache type to `none` to use a no-op implementation:
[source,properties,indent=0]
----
spring.cache.type=none
----
[[boot-features-messaging]]
== Messaging
The Spring Framework provides extensive support for integrating with messaging systems:
from simplified use of the JMS API using `JmsTemplate` to a complete infrastructure to
receive messages asynchronously. Spring AMQP provides a similar feature set for the
'`Advanced Message Queuing Protocol`' and Spring Boot also provides auto-configuration
options for `RabbitTemplate` and RabbitMQ. There is also support for STOMP messaging
natively in Spring WebSocket and Spring Boot has support for that through starters and a
small amount of auto-configuration. Spring Boot also has support for Apache Kafka.
[[boot-features-jms]]
=== JMS
The `javax.jms.ConnectionFactory` interface provides a standard method of creating a
`javax.jms.Connection` for interacting with a JMS broker. Although Spring needs a
`ConnectionFactory` to work with JMS, you generally won't need to use it directly yourself
and you can instead rely on higher level messaging abstractions (see the
{spring-reference}integration.html#jms[relevant section] of the Spring Framework reference
documentation for details). Spring Boot also auto-configures the necessary infrastructure
to send and receive messages.
[[boot-features-activemq]]
==== ActiveMQ support
Spring Boot can also configure a `ConnectionFactory` when it detects that ActiveMQ is
available on the classpath. If the broker is present, an embedded broker is started and
configured automatically (as long as no broker URL is specified through configuration).
NOTE: If you are using `spring-boot-starter-activemq` the necessary dependencies to
connect or embed an ActiveMQ instance are provided, as well as the Spring infrastructure
to integrate with JMS.
ActiveMQ configuration is controlled by external configuration properties in
`+spring.activemq.*+`. For example, you might declare the following section in
`application.properties`:
[source,properties,indent=0]
----
spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret
----
You can also pool JMS resources by adding a dependency to
`org.apache.activemq:activemq-pool` and configure the `PooledConnectionFactory`
accordingly:
[source,properties,indent=0]
----
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
----
TIP: See
{sc-spring-boot-autoconfigure}/jms/activemq/ActiveMQProperties.{sc-ext}[`ActiveMQProperties`]
for more of the supported options. You can also register an arbitrary number of beans
implementing `ActiveMQConnectionFactoryCustomizer` for more advanced customizations.
By default, ActiveMQ creates a destination if it does not exist yet, so destinations are
resolved against their provided names.
[[boot-features-artemis]]
==== Artemis support
Spring Boot can auto-configure a `ConnectionFactory` when it detects that Artemis is
available on the classpath. If the broker is present, an embedded broker is started and
configured automatically (unless the mode property has been explicitly set). The supported
modes are: `embedded` (to make explicit that an embedded broker is required and should
lead to an error if the broker is not available in the classpath), and `native` to connect
to a broker using the `netty` transport protocol. When the latter is configured, Spring
Boot configures a `ConnectionFactory` connecting to a broker running on the local machine
with the default settings.
NOTE: If you are using `spring-boot-starter-artemis` the necessary dependencies to
connect to an existing Artemis instance are provided, as well as the Spring infrastructure
to integrate with JMS. Adding `org.apache.activemq:artemis-jms-server` to your application
allows you to use the embedded mode.
Artemis configuration is controlled by external configuration properties in
`+spring.artemis.*+`. For example, you might declare the following section in
`application.properties`:
[source,properties,indent=0]
----
spring.artemis.mode=native
spring.artemis.host=192.168.1.210
spring.artemis.port=9876
spring.artemis.user=admin
spring.artemis.password=secret
----
When embedding the broker, you can choose if you want to enable persistence, and the list
of destinations that should be made available. These can be specified as a comma-separated
list to create them with the default options; or you can define bean(s) of type
`org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration` or
`org.apache.activemq.artemis.jms.server.config.TopicConfiguration`, for advanced queue and
topic configurations respectively.
See
{sc-spring-boot-autoconfigure}/jms/artemis/ArtemisProperties.{sc-ext}[`ArtemisProperties`]
for more of the supported options.
No JNDI lookup is involved at all and destinations are resolved against their names,
either using the '`name`' attribute in the Artemis configuration or the names provided
through configuration.
[[boot-features-jms-jndi]]
==== Using a JNDI ConnectionFactory
If you are running your application in an Application Server Spring Boot will attempt to
locate a JMS `ConnectionFactory` using JNDI. By default the locations `java:/JmsXA` and
`java:/XAConnectionFactory` will be checked. You can use the
`spring.jms.jndi-name` property if you need to specify an alternative location:
[source,properties,indent=0]
----
spring.jms.jndi-name=java:/MyConnectionFactory
----
[[boot-features-using-jms-sending]]
==== Sending a message
Spring's `JmsTemplate` is auto-configured and you can autowire it directly into your own
beans:
[source,java,indent=0]
----
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JmsTemplate jmsTemplate;
@Autowired
public MyBean(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
// ...
}
----
NOTE: {spring-javadoc}/jms/core/JmsMessagingTemplate.{dc-ext}[`JmsMessagingTemplate`]
can be injected in a similar manner. If a `DestinationResolver` or `MessageConverter`
beans are defined, they are associated automatically to the auto-configured
`JmsTemplate`.
[[boot-features-using-jms-receiving]]
==== Receiving a message
When the JMS infrastructure is present, any bean can be annotated with `@JmsListener` to
create a listener endpoint. If no `JmsListenerContainerFactory` has been defined, a
default one is configured automatically. If a `DestinationResolver` or `MessageConverter`
beans are defined, they are associated automatically to the default factory.
The default factory is transactional by default. If you are running in an infrastructure
where a `JtaTransactionManager` is present, it will be associated to the listener container
by default. If not, the `sessionTransacted` flag will be enabled. In that latter scenario,
you can associate your local data store transaction to the processing of an incoming
message by adding `@Transactional` on your listener method (or a delegate thereof). This
will make sure that the incoming message is acknowledged once the local transaction has
completed. This also includes sending response messages that have been performed on the
same JMS session.
The following component creates a listener endpoint on the `someQueue` destination:
[source,java,indent=0]
----
@Component
public class MyBean {
@JmsListener(destination = "someQueue")
public void processMessage(String content) {
// ...
}
}
----
TIP: Check {spring-javadoc}/jms/annotation/EnableJms.{dc-ext}[the Javadoc of `@EnableJms`]
for more details.
If you need to create more `JmsListenerContainerFactory` instances or if you want to
override the default, Spring Boot provides a `DefaultJmsListenerContainerFactoryConfigurer`
that you can use to initialize a `DefaultJmsListenerContainerFactory` with the same
settings as the one that is auto-configured.
For instance, the following exposes another factory that uses a specific
`MessageConverter`:
[source,java,indent=0]
----
@Configuration
static class JmsConfiguration {
@Bean
public DefaultJmsListenerContainerFactory myFactory(
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory());
factory.setMessageConverter(myMessageConverter());
return factory;
}
}
----
Then you can use in any `@JmsListener`-annotated method as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Component
public class MyBean {
@JmsListener(destination = "someQueue", **containerFactory="myFactory"**)
public void processMessage(String content) {
// ...
}
}
----
[[boot-features-amqp]]
=== AMQP
The Advanced Message Queuing Protocol (AMQP) is a platform-neutral, wire-level protocol
for message-oriented middleware. The Spring AMQP project applies core Spring concepts to
the development of AMQP-based messaging solutions. Spring Boot offers several
conveniences for working with AMQP via RabbitMQ, including the
`spring-boot-starter-amqp` '`Starter`'.
[[boot-features-rabbitmq]]
==== RabbitMQ support
RabbitMQ is a lightweight, reliable, scalable and portable message broker based on the
AMQP protocol. Spring uses `RabbitMQ` to communicate using the AMQP protocol.
RabbitMQ configuration is controlled by external configuration properties in
`+spring.rabbitmq.*+`. For example, you might declare the following section in
`application.properties`:
[source,properties,indent=0]
----
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret
----
See {sc-spring-boot-autoconfigure}/amqp/RabbitProperties.{sc-ext}[`RabbitProperties`]
for more of the supported options.
TIP: Check http://spring.io/blog/2010/06/14/understanding-amqp-the-protocol-used-by-rabbitmq/[Understanding AMQP, the protocol used by RabbitMQ]
for more details.
[[boot-features-using-amqp-sending]]
==== Sending a message
Spring's `AmqpTemplate` and `AmqpAdmin` are auto-configured and you can autowire them
directly into your own beans:
[source,java,indent=0]
----
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final AmqpAdmin amqpAdmin;
private final AmqpTemplate amqpTemplate;
@Autowired
public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
this.amqpAdmin = amqpAdmin;
this.amqpTemplate = amqpTemplate;
}
// ...
}
----
NOTE: {spring-amqp-javadoc}/rabbit/core/RabbitMessagingTemplate.{dc-ext}[`RabbitMessagingTemplate`]
can be injected in a similar manner. If a `MessageConverter` bean is defined, it is
associated automatically to the auto-configured `AmqpTemplate`.
Any `org.springframework.amqp.core.Queue` that is defined as a bean will be automatically
used to declare a corresponding queue on the RabbitMQ instance if necessary.
You can enable retries on the `AmqpTemplate` to retry operations, for example in the event
the broker connection is lost. Retries are disabled by default.
[[boot-features-using-amqp-receiving]]
==== Receiving a message
When the Rabbit infrastructure is present, any bean can be annotated with
`@RabbitListener` to create a listener endpoint. If no `RabbitListenerContainerFactory`
has been defined, a default `SimpleRabbitListenerContainerFactory` is configured
automatically and you can switch to a direct container using the
`spring.rabbitmq.listener.type` property. If a `MessageConverter` or `MessageRecoverer`
beans are defined, they are associated automatically to the default factory.
The following component creates a listener endpoint on the `someQueue` queue:
[source,java,indent=0]
----
@Component
public class MyBean {
@RabbitListener(queues = "someQueue")
public void processMessage(String content) {
// ...
}
}
----
TIP: Check {spring-amqp-javadoc}/rabbit/annotation/EnableRabbit.{dc-ext}[the Javadoc of `@EnableRabbit`]
for more details.
If you need to create more `RabbitListenerContainerFactory` instances or if you want to
override the default, Spring Boot provides a
`SimpleRabbitListenerContainerFactoryConfigurer` and
`DirectRabbitListenerContainerFactoryConfigurer` that you can use to initialize a
`SimpleRabbitListenerContainerFactory` and `DirectRabbitListenerContainerFactory` with the
same settings as the one used by the auto-configuration.
TIP: It doesn't matter which container type you've chosen, those two beans are exposed by
the auto-configuration.
For instance, the following exposes another factory that uses a specific
`MessageConverter`:
[source,java,indent=0]
----
@Configuration
static class RabbitConfiguration {
@Bean
public SimpleRabbitListenerContainerFactory myFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer) {
SimpleRabbitListenerContainerFactory factory =
new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setMessageConverter(myMessageConverter());
return factory;
}
}
----
Then you can use in any `@RabbitListener`-annotated method as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Component
public class MyBean {
@RabbitListener(queues = "someQueue", **containerFactory="myFactory"**)
public void processMessage(String content) {
// ...
}
}
----
You can enable retries to handle situations where your listener throws an exception. By
default `RejectAndDontRequeueRecoverer` is used but you can define a `MessageRecoverer`
of your own. When retries are exhausted, the message will be rejected and either dropped
or routed to a dead-letter exchange if the broker is configured so. Retries are disabled
by default.
IMPORTANT: If retries are not enabled and the listener throws an exception, by default the
delivery will be retried indefinitely. You can modify this behavior in two ways; set the
`defaultRequeueRejected` property to `false` and zero re-deliveries will be attempted; or,
throw an `AmqpRejectAndDontRequeueException` to signal the message should be rejected.
This is the mechanism used when retries are enabled and the maximum delivery attempts are
reached.
[[boot-features-kafka]]
=== Apache Kafka Support
http://kafka.apache.org/[Apache Kafka] is supported by providing auto-configuration of the
`spring-kafka` project.
Kafka configuration is controlled by external configuration properties in
`spring.kafka.*`. For example, you might declare the following section in
`application.properties`:
[source,properties,indent=0]
----
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=myGroup
----
TIP: To create a topic on startup, simply add a bean of type `NewTopic`. If the topic
already exists, the related bean is ignored.
See {sc-spring-boot-autoconfigure}/kafka/KafkaProperties.{sc-ext}[`KafkaProperties`]
for more of the supported options.
[[boot-features-kafka-sending-a-message]]
==== Sending a Message
Spring's `KafkaTemplate` is auto-configured and you can autowire them directly in your own
beans:
[source,java,indent=0]
----
@Component
public class MyBean {
private final KafkaTemplate kafkaTemplate;
@Autowired
public MyBean(KafkaTemplate kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
// ...
}
----
NOTE: If a `RecordMessageConverter` bean is defined, it is associated automatically to the
auto-configured `KafkaTemplate`.
[[boot-features-kafka-receiving-a-message]]
==== Receiving a Message
When the Apache Kafka infrastructure is present, any bean can be annotated with
`@KafkaListener` to create a listener endpoint. If no `KafkaListenerContainerFactory`
has been defined, a default one is configured automatically with keys defined in
`spring.kafka.listener.*`. Also, if a `RecordMessageConverter` bean is defined, it is
associated automatically to the default factory.
The following component creates a listener endpoint on the `someTopic` topic:
[source,java,indent=0]
----
@Component
public class MyBean {
@KafkaListener(topics = "someTopic")
public void processMessage(String content) {
// ...
}
}
----
[[boot-features-kafka-extra-props]]
==== Additional Kafka Properties
The properties supported by auto configuration are shown in
<<common-application-properties>>. Note that these properties (hyphenated or camelCase)
map directly to the Apache Kafka dotted properties for the most part, refer to the Apache
Kafka documentation for details.
The first few of these properties apply to both producers and consumers, but can be
specified at the producer or consumer level if you wish to use different values for each.
Apache Kafka designates properties with an importance: HIGH, MEDIUM and LOW. Spring Boot
auto configuration supports all HIGH importance properties, some selected MEDIUM and LOW,
and any that do not have a default value.
Only a subset of the properties supported by Kafka are available via the `KafkaProperties`
class. If you wish to configure the producer or consumer with additional properties that
are not directly supported, use the following:
[source,properties,indent=0]
----
spring.kafka.properties.foo.bar=baz
spring.kafka.consumer.properties.fiz.buz=qux
spring,kafka.producer.properties.baz.qux=fiz
----
This sets the common `foo.bar` Kafka property to `baz` (applies to both producers and
consumers), the consumer `fiz.buz` property to `qux` and the `baz.qux` producer property
to `fiz`.
IMPORTANT: Properties set in this way will override any configuration item that Spring
Boot explicitly supports.
[[boot-features-resttemplate]]
== Calling REST services with '`RestTemplate`'
If you need to call remote REST services from your application, you can use Spring
Framework's `RestTemplate` class. Since `RestTemplate` instances often need to be
customized before being used, Spring Boot does not provide any single auto-configured
`RestTemplate` bean. It does, however, auto-configure a `RestTemplateBuilder` which can be
used to create `RestTemplate` instances when needed. The auto-configured
`RestTemplateBuilder` will ensure that sensible `HttpMessageConverters` are applied
to `RestTemplate` instances.
Here's a typical example:
[source,java,indent=0]
----
@Service
public class MyService {
private final RestTemplate restTemplate;
public MyBean(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
public Details someRestCall(String name) {
return this.restTemplate.getForObject("/{name}/details", Details.class, name);
}
}
----
TIP: `RestTemplateBuilder` includes a number of useful methods that can be used to quickly
configure a `RestTemplate`. For example, to add BASIC auth support you can use
`builder.basicAuthorization("user", "password").build()`.
[[boot-features-resttemplate-customization]]
=== RestTemplate customization
There are three main approaches to `RestTemplate` customization, depending on how broadly
you want the customizations to apply.
To make the scope of any customizations as narrow as possible, inject the auto-configured
`RestTemplateBuilder` and then call its methods as required. Each method call returns a
new `RestTemplateBuilder` instance so the customizations will only affect this use of
the builder.
To make an application-wide, additive customization a `RestTemplateCustomizer` bean can be
used. All such beans are automatically registered with the auto-configured
`RestTemplateBuilder` and will be applied to any templates that are built with it.
Here's an example of a customizer that configures the use of a proxy for all hosts except
`192.168.0.5`:
[source,java,indent=0]
----
include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[tag=customizer]
----
Lastly, the most extreme (and rarely used) option is to create your own
`RestTemplateBuilder` bean. This will switch off the auto-configuration of a
`RestTemplateBuilder` and will prevent any `RestTemplateCustomizer` beans from being used.
[[boot-features-webclient]]
== Calling REST services with '`WebClient`'
If you have Spring WebFlux on your classpath, you can also choose to use `WebClient`
to call remote REST services; compared to `RestTemplate`, this client has more a
functional feel to it and is fully reactive. You can create your own client
instance with the builder `WebClient.create()`, which already provides a good
out-of-the-box experience. See the
{spring-reference}web.html#web-reactive-client[relevant section on WebClient].
Spring Boot will create and pre-configure such a builder for you; for example,
client HTTP codecs will be configured just like the server ones
(see <<boot-features-webflux-httpcodecs,WebFlux HTTP codecs auto-configuration>>).
Here's a typical example:
[source,java,indent=0]
----
@Service
public class MyService {
private final WebClient webClient;
public MyBean(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("http://example.org").build();
}
public Mono<Details> someRestCall(String name) {
return this.webClient.get().url("/{name}/details", name)
.retrieve().bodyToMono(Details.class);
}
}
----
[[boot-features-webclient-customization]]
=== WebClient customization
There are three main approaches to `WebClient` customization, depending on how broadly
you want the customizations to apply.
To make the scope of any customizations as narrow as possible, inject the auto-configured
`WebClient.Builder` and then call its methods as required. `WebClient.Builder` instances
are stateful; any change on the builder will be reflected in all clients subsequently
created with it. If you'd like to create several clients with the same builder, you can
also consider cloning the builder with `WebClient.Builder other = builder.clone();`.
To make an application-wide, additive customization to all `WebClient.Builder` instances,
you can declare `WebClientCustomizer` beans and change the `WebClient.Builder` as you
would do locally at the point of injection.
Lastly, you can fall back to the original API and just use `WebClient.create()`. In that
case, no auto-configuration nor `WebClientCustomizer` will be applied.
[[boot-features-validation]]
== Validation
The method validation feature supported by Bean Validation 1.1 is automatically enabled
as long as a JSR-303 implementation (e.g. Hibernate validator) is on the classpath. This
allows bean methods to be annotated with `javax.validation` constraints on their
parameters and/or on their return value. Target classes with such annotated methods need
to be annotated with the `@Validated` annotation at the type level for their methods to
be searched for inline constraint annotations.
For instance, the following service triggers the validation of the first argument, making
sure its size is between 8 and 10
[source,java,indent=0]
----
@Service
@Validated
public class MyBean {
public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
Author author) {
...
}
}
----
[[boot-features-email]]
== Sending email
The Spring Framework provides an easy abstraction for sending email using the
`JavaMailSender` interface and Spring Boot provides auto-configuration for it as well as
a starter module.
TIP: Check the {spring-reference}integration.html#mail[reference documentation] for a detailed
explanation of how you can use `JavaMailSender`.
If `spring.mail.host` and the relevant libraries (as defined by
`spring-boot-starter-mail`) are available, a default `JavaMailSender` is created if none
exists. The sender can be further customized by configuration items from the `spring.mail`
namespace, see the
{sc-spring-boot-autoconfigure}/mail/MailProperties.{sc-ext}[`MailProperties`] for more
details.
In particular, certain default timeout values are infinite and you may want to change that
to avoid having a thread blocked by an unresponsive mail server:
[source,properties,indent=0]
----
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000
----
[[boot-features-jta]]
== Distributed Transactions with JTA
Spring Boot supports distributed JTA transactions across multiple XA resources using
either an http://www.atomikos.com/[Atomikos] or https://github.com/bitronix/btm[Bitronix]
embedded transaction manager. JTA transactions are also supported when deploying to a
suitable Java EE Application Server.
When a JTA environment is detected, Spring's `JtaTransactionManager` will be used to
manage transactions. Auto-configured JMS, DataSource and JPA beans will be upgraded to
support XA transactions. You can use standard Spring idioms such as `@Transactional` to
participate in a distributed transaction. If you are within a JTA environment and still
want to use local transactions you can set the `spring.jta.enabled` property to `false` to
disable the JTA auto-configuration.
[[boot-features-jta-atomikos]]
=== Using an Atomikos transaction manager
Atomikos is a popular open source transaction manager which can be embedded into your
Spring Boot application. You can use the `spring-boot-starter-jta-atomikos` Starter to
pull in the appropriate Atomikos libraries. Spring Boot will auto-configure Atomikos and
ensure that appropriate `depends-on` settings are applied to your Spring beans for correct
startup and shutdown ordering.
By default Atomikos transaction logs will be written to a `transaction-logs` directory in
your application home directory (the directory in which your application jar file
resides). You can customize this directory by setting a `spring.jta.log-dir` property in
your `application.properties` file. Properties starting `spring.jta.atomikos.properties`
can also be used to customize the Atomikos `UserTransactionServiceImp`. See the
{dc-spring-boot}/jta/atomikos/AtomikosProperties.{dc-ext}[`AtomikosProperties` Javadoc]
for complete details.
NOTE: To ensure that multiple transaction managers can safely coordinate the same
resource managers, each Atomikos instance must be configured with a unique ID. By default
this ID is the IP address of the machine on which Atomikos is running. To ensure
uniqueness in production, you should configure the `spring.jta.transaction-manager-id`
property with a different value for each instance of your application.
[[boot-features-jta-bitronix]]
=== Using a Bitronix transaction manager
Bitronix is popular open source JTA transaction manager implementation. You can
use the `spring-boot-starter-jta-bitronix` starter to add the appropriate Bitronix
dependencies to your project. As with Atomikos, Spring Boot will automatically configure
Bitronix and post-process your beans to ensure that startup and shutdown ordering is
correct.
By default Bitronix transaction log files (`part1.btm` and `part2.btm`) will be written to
a `transaction-logs` directory in your application home directory. You can customize this
directory by using the `spring.jta.log-dir` property. Properties starting
`spring.jta.bitronix.properties` are also bound to the `bitronix.tm.Configuration` bean,
allowing for complete customization. See the
https://github.com/bitronix/btm/wiki/Transaction-manager-configuration[Bitronix documentation]
for details.
NOTE: To ensure that multiple transaction managers can safely coordinate the same
resource managers, each Bitronix instance must be configured with a unique ID. By default
this ID is the IP address of the machine on which Bitronix is running. To ensure
uniqueness in production, you should configure the `spring.jta.transaction-manager-id`
property with a different value for each instance of your application.
[[boot-features-jta-narayana]]
=== Using a Narayana transaction manager
Narayana is popular open source JTA transaction manager implementation supported by JBoss.
You can use the `spring-boot-starter-jta-narayana` starter to add the appropriate
Narayana dependencies to your project. As with Atomikos and Bitronix, Spring Boot will
automatically configure Narayana and post-process your beans to ensure that startup and
shutdown ordering is correct.
By default Narayana transaction logs will be written to a `transaction-logs` directory in
your application home directory (the directory in which your application jar file
resides). You can customize this directory by setting a `spring.jta.log-dir` property in
your `application.properties` file. Properties starting `spring.jta.narayana.properties`
can also be used to customize the Narayana configuration. See the
{dc-spring-boot}/jta/narayana/NarayanaProperties.{dc-ext}[`NarayanaProperties` Javadoc]
for complete details.
NOTE: To ensure that multiple transaction managers can safely coordinate the same
resource managers, each Narayana instance must be configured with a unique ID. By default
this ID is set to `1`. To ensure uniqueness in production, you should configure the
`spring.jta.transaction-manager-id` property with a different value for each instance of
your application.
[[boot-features-jta-javaee]]
=== Using a Java EE managed transaction manager
If you are packaging your Spring Boot application as a `war` or `ear` file and deploying
it to a Java EE application server, you can use your application servers built-in
transaction manager. Spring Boot will attempt to auto-configure a transaction manager by
looking at common JNDI locations (`java:comp/UserTransaction`,
`java:comp/TransactionManager` etc). If you are using a transaction service provided by
your application server, you will generally also want to ensure that all resources are
managed by the server and exposed over JNDI. Spring Boot will attempt to auto-configure
JMS by looking for a `ConnectionFactory` at the JNDI path `java:/JmsXA` or
`java:/XAConnectionFactory` and you can use the
<<boot-features-connecting-to-a-jndi-datasource, `spring.datasource.jndi-name` property>>
to configure your `DataSource`.
[[boot-features-jta-mixed-jms]]
=== Mixing XA and non-XA JMS connections
When using JTA, the primary JMS `ConnectionFactory` bean will be XA aware and participate
in distributed transactions. In some situations you might want to process certain JMS
messages using a non-XA `ConnectionFactory`. For example, your JMS processing logic might
take longer than the XA timeout.
If you want to use a non-XA `ConnectionFactory` you can inject the
`nonXaJmsConnectionFactory` bean rather than the `@Primary` `jmsConnectionFactory` bean.
For consistency the `jmsConnectionFactory` bean is also provided using the bean alias
`xaJmsConnectionFactory`.
For example:
[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;
// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;
// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;
----
[[boot-features-jta-supporting-alternative-embedded]]
=== Supporting an alternative embedded transaction manager
The {sc-spring-boot}/jta/XAConnectionFactoryWrapper.{sc-ext}[`XAConnectionFactoryWrapper`]
and {sc-spring-boot}/jta/XADataSourceWrapper.{sc-ext}[`XADataSourceWrapper`] interfaces
can be used to support alternative embedded transaction managers. The interfaces are
responsible for wrapping `XAConnectionFactory` and `XADataSource` beans and exposing them
as regular `ConnectionFactory` and `DataSource` beans which will transparently enroll in
the distributed transaction. DataSource and JMS auto-configuration will use JTA variants
as long as you have a `JtaTransactionManager` bean and appropriate XA wrapper beans
registered within your `ApplicationContext`.
The {sc-spring-boot}/jta/bitronix/BitronixXAConnectionFactoryWrapper.{sc-ext}[BitronixXAConnectionFactoryWrapper]
and {sc-spring-boot}/jta/bitronix/BitronixXADataSourceWrapper.{sc-ext}[BitronixXADataSourceWrapper]
provide good examples of how to write XA wrappers.
[[boot-features-hazelcast]]
== Hazelcast
If Hazelcast is on the classpath and a suitable configuration is found, Spring Boot
will auto-configure a `HazelcastInstance` that you can inject in your application.
You can define a `com.hazelcast.config.Config` bean and we'll use that. If your
configuration defines an instance name, we'll try to locate an existing instance rather
than creating a new one.
You could also specify the `hazelcast.xml` configuration file to use via configuration:
[source,properties,indent=0]
----
spring.hazelcast.config=classpath:config/my-hazelcast.xml
----
Otherwise, Spring Boot tries to find the Hazelcast configuration from the default
locations, that is `hazelcast.xml` in the working directory or at the root of the
classpath. We also check if the `hazelcast.config` system property is set. Check the
http://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for
more details.
If `hazelcast-client` is present on the classpath, Spring Boot will first attempt to
create a client with similar rules as above, that is:
* The presence of a `com.hazelcast.client.config.ClientConfig` bean
* A configuration file defined by the `spring.hazelcast.config` property
* The presence of the `hazelcast.client.config` system property
* A `hazelcast-client.xml` in the working directory or at the root of the classpath
NOTE: Spring Boot also has an
<<boot-features-caching-provider-hazelcast,explicit caching support for Hazelcast>>. The
`HazelcastInstance` is automatically wrapped in a `CacheManager` implementation if
caching is enabled.
[[boot-features-quartz]]
== Quartz Scheduler
Spring Boot offers several conveniences for working with the Quartz scheduler, including
the `spring-boot-starter-quartz` '`Starter`'. If Quartz is available, a `Scheduler` will
be auto-configured (via the `SchedulerFactoryBean` abstraction).
Beans of the following types will be automatically picked up and associated with the
the `Scheduler`:
* `JobDetail`: defines a particular Job. `JobDetail` instance can easily be built with
the `JobBuilder` API
* `Calendar`
* `Trigger`: defines when a particular job is triggered
By default, an in-memory `JobStore` will be used. However, it is possible to configure
a JDBC-based store if a `DataSource` bean is available in your application and if the
`spring.quartz.job-store-type` property is configured accordingly:
[source,properties,indent=0]
----
spring.quartz.job-store-type=jdbc
----
When the jdbc store is used, the schema can be initialized on startup:
[source,properties,indent=0]
----
spring.quartz.jdbc.initialize-schema=true
----
NOTE: The database is detected by default and initialized using the standard scripts
provided with the Quartz library. It is also possible to provide a custom script using the
`spring.quartz.jdbc.schema` property.
Quartz Scheduler configuration can be customized using Quartz configuration properties (see
`spring.quartz.properties.*`) and `SchedulerFactoryBeanCustomizer` beans which allow
programmatic `SchedulerFactoryBean` customization.
Job can define setters to inject data map properties. Regular beans can also be injected
in a similar manner:
[source,java,indent=0]
----
public class SampleJob extends QuartzJobBean {
private MyService myService;
private String name;
// Inject "MyService" bean
public void setMyService(MyService myService) { ... }
// Inject the "name" job data property
public void setName(String name) { ... }
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
...
}
}
----
[[boot-features-integration]]
== Spring Integration
Spring Boot offers several conveniences for working with Spring Integration, including
the `spring-boot-starter-integration` '`Starter`'. Spring Integration provides
abstractions over messaging and also other transports such as HTTP, TCP etc. If Spring
Integration is available on your classpath it will be initialized through the
`@EnableIntegration` annotation.
Spring Boot will also configure some features that are triggered by the presence of
additional Spring Integration modules. Message processing statistics will be published
over JMX if `'spring-integration-jmx'` is also on the classpath. If
`'spring-integration-jdbc'` is available, the default database schema can be created
on startup:
[source,properties,indent=0]
----
spring.integration.jdbc.initialize-schema=always
----
See the
{sc-spring-boot-autoconfigure}/integration/IntegrationAutoConfiguration.{sc-ext}[`IntegrationAutoConfiguration`]
and {sc-spring-boot-autoconfigure}/integration/IntegrationProperties.{sc-ext}[`IntegrationProperties`]
classes for more details.
[[boot-features-session]]
== Spring Session
Spring Boot provides Spring Session auto-configuration for a wide range of stores:
* JDBC
* Redis
* Hazelcast
* MongoDB
If Spring Session is available, you must choose the
{sc-spring-boot-autoconfigure}/session/StoreType.{sc-ext}[`StoreType`] that you wish to
use to store the sessions. For instance to use JDBC as backend store, you'd configure
your application as follows:
[source,properties,indent=0]
----
spring.session.store-type=jdbc
----
TIP: You can disable Spring Session by setting the `store-type` to `none`.
Each store has specific additional settings. For instance it is possible to customize
the name of the table for the jdbc store:
[source,properties,indent=0]
----
spring.session.jdbc.table-name=SESSIONS
----
[[boot-features-jmx]]
== Monitoring and management over JMX
Java Management Extensions (JMX) provide a standard mechanism to monitor and manage
applications. By default Spring Boot will create an `MBeanServer` with bean id
'`mbeanServer`' and expose any of your beans that are annotated with Spring JMX
annotations (`@ManagedResource`, `@ManagedAttribute`, `@ManagedOperation`).
See the
{sc-spring-boot-autoconfigure}/jmx/JmxAutoConfiguration.{sc-ext}[`JmxAutoConfiguration`]
class for more details.
[[boot-features-testing]]
== Testing
Spring Boot provides a number of utilities and annotations to help when testing your
application. Test support is provided by two modules; `spring-boot-test` contains core
items, and `spring-boot-test-autoconfigure` supports auto-configuration for tests.
Most developers will just use the `spring-boot-starter-test` '`Starter`' which
imports both Spring Boot test modules as well has JUnit, AssertJ, Hamcrest and a number
of other useful libraries.
[[boot-features-test-scope-dependencies]]
=== Test scope dependencies
If you use the
`spring-boot-starter-test` '`Starter`' (in the `test` `scope`), you will find
the following provided libraries:
* http://junit.org[JUnit] -- The de-facto standard for unit testing Java applications.
* {spring-reference}testing.html#integration-testing[Spring Test] & Spring Boot Test --
Utilities and integration test support for Spring Boot applications.
* http://joel-costigliola.github.io/assertj/[AssertJ] -- A fluent assertion library.
* http://hamcrest.org/JavaHamcrest/[Hamcrest] -- A library of matcher objects (also known
as constraints or predicates).
* http://mockito.org/[Mockito] -- A Java mocking framework.
* https://github.com/skyscreamer/JSONassert[JSONassert] -- An assertion library for JSON.
* https://github.com/jayway/JsonPath[JsonPath] -- XPath for JSON.
These are common libraries that we generally find useful when writing tests. You are free
to add additional test dependencies of your own if these don't suit your needs.
[[boot-features-testing-spring-applications]]
=== Testing Spring applications
One of the major advantages of dependency injection is that it should make your code
easier to unit test. You can simply instantiate objects using the `new` operator without
even involving Spring. You can also use _mock objects_ instead of real dependencies.
Often you need to move beyond '`unit testing`' and start '`integration testing`' (with
a Spring `ApplicationContext` actually involved in the process). It's useful to be able
to perform integration testing without requiring deployment of your application or
needing to connect to other infrastructure.
The Spring Framework includes a dedicated test module for just such integration testing.
You can declare a dependency directly to `org.springframework:spring-test` or use the
`spring-boot-starter-test` '`Starter`' to pull it in transitively.
If you have not used the `spring-test` module before you should start by reading the
{spring-reference}testing.html#testing[relevant section] of the Spring Framework reference
documentation.
[[boot-features-testing-spring-boot-applications]]
=== Testing Spring Boot applications
A Spring Boot application is just a Spring `ApplicationContext`, so nothing very special
has to be done to test it beyond what you would normally do with a vanilla Spring context.
One thing to watch out for though is that the external properties, logging and other
features of Spring Boot are only installed in the context by default if you use
`SpringApplication` to create it.
Spring Boot provides a `@SpringBootTest` annotation which can be used as an
alternative to the standard `spring-test` `@ContextConfiguration` annotation when you need
Spring Boot features. The annotation works by creating the `ApplicationContext` used
in your tests via `SpringApplication`.
You can use the `webEnvironment` attribute of `@SpringBootTest` to further refine
how your tests will run:
* `MOCK` -- Loads a `WebApplicationContext` and provides a mock servlet environment.
Embedded servlet containers are not started when using this annotation. If servlet
APIs are not on your classpath this mode will transparently fallback to creating a
regular non-web `ApplicationContext`. Can be used in conjunction with
`@AutoConfigureMockMvc` for `MockMvc`-based testing of your application.
* `RANDOM_PORT` -- Loads an `ServletWebServerApplicationContext` and provides a real
servlet environment. Embedded servlet containers are started and listening on a random
port.
* `DEFINED_PORT` -- Loads an `ServletWebServerApplicationContext` and provides a real
servlet environment. Embedded servlet containers are started and listening on a defined
port (i.e from your `application.properties` or on the default port `8080`).
* `NONE` -- Loads an `ApplicationContext` using `SpringApplication` but does not provide
_any_ servlet environment (mock or otherwise).
NOTE: If your test is `@Transactional`, it will rollback the transaction at the end of
each test method by default. However, as using this arrangement with either `RANDOM_PORT`
or `DEFINED_PORT` implicitly provides a real servlet environment, HTTP client and
server will run in separate threads, thus separate transactions. Any transaction
initiated on the server won't rollback in this case.
NOTE: In addition to `@SpringBootTest` a number of other annotations are also
provided for testing more specific slices of an application. See below for details.
TIP: Don't forget to also add `@RunWith(SpringRunner.class)` to your test, otherwise
the annotations will be ignored.
[[boot-features-testing-spring-boot-applications-detecting-config]]
==== Detecting test configuration
If you're familiar with the Spring Test Framework, you may be used to using
`@ContextConfiguration(classes=...)` in order to specify which Spring `@Configuration`
to load. Alternatively, you might have often used nested `@Configuration` classes within
your test.
When testing Spring Boot applications this is often not required.
Spring Boot's `@*Test` annotations will search for your primary configuration
automatically whenever you don't explicitly define one.
The search algorithm works up from the package that contains the test until it finds a
`@SpringBootApplication` or `@SpringBootConfiguration` annotated class. As long as you've
<<using-boot-structuring-your-code, structured your code>> in a sensible way your main
configuration is usually found.
If you want to customize the primary configuration, you can use a nested
`@TestConfiguration` class. Unlike a nested `@Configuration` class which would be used
instead of your application's primary configuration, a nested `@TestConfiguration` class
will be used in addition to your application's primary configuration.
NOTE: Spring's test framework will cache application contexts between tests. Therefore, as
long as your tests share the same configuration (no matter how it's discovered), the
potentially time consuming process of loading the context will only happen once.
[[boot-features-testing-spring-boot-applications-excluding-config]]
==== Excluding test configuration
If your application uses component scanning, for example if you use
`@SpringBootApplication` or `@ComponentScan`, you may find top-level configuration classes
created only for specific tests accidentally get picked up everywhere.
As we <<boot-features-testing-spring-boot-applications-detecting-config,have seen above>>,
`@TestConfiguration` can be used on an inner class of a test to customize the primary
configuration. When placed on a top-level class, `@TestConfiguration` indicates that
classes in `src/test/java` should not be picked up by scanning. You can then import that
class explicitly where it is required:
[source,java,indent=0]
----
@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyTestsConfiguration.class)
public class MyTests {
@Test
public void exampleTest() {
...
}
}
----
NOTE: If you directly use `@ComponentScan` (i.e. not via `@SpringBootApplication`) you
will need to register the `TypeExcludeFilter` with it. See
{dc-spring-boot}/context/TypeExcludeFilter.{dc-ext}[the Javadoc] for details.
[[boot-features-testing-spring-boot-applications-working-with-random-ports]]
==== Working with random ports
If you need to start a full running server for tests, we recommend that you use random
ports. If you use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)`
an available port will be picked at random each time your test runs.
The `@LocalServerPort` annotation can be used to
<<howto-discover-the-http-port-at-runtime,inject the actual port used>> into your test.
For convenience, tests that need to make REST calls to the started server can additionally
`@Autowire` a `TestRestTemplate` which will resolve relative links to the running server.
[source,java,indent=0]
----
include::{code-examples}/test/web/RandomPortExampleTests.java[tag=test-random-port]
----
[[boot-features-testing-spring-boot-applications-mocking-beans]]
==== Mocking and spying beans
It's sometimes necessary to mock certain components within your application context when
running tests. For example, you may have a facade over some remote service that's
unavailable during development. Mocking can also be useful when you want to simulate
failures that might be hard to trigger in a real environment.
Spring Boot includes a `@MockBean` annotation that can be used to define a Mockito mock
for a bean inside your `ApplicationContext`. You can use the annotation to add new beans,
or replace a single existing bean definition. The annotation can be used directly on test
classes, on fields within your test, or on `@Configuration` classes and fields. When used
on a field, the instance of the created mock will also be injected. Mock beans are
automatically reset after each test method.
[NOTE]
====
This feature is automatically enabled as long as your test uses one of Spring Boot's
test annotations (i.e. `@SpringBootTest`). To use this feature with a different
arrangement, a listener will need to be added explicitly:
[source,java,indent=0]
----
@TestExecutionListeners(MockitoTestExecutionListener.class)
----
====
Here's a typical example where we replace an existing `RemoteService` bean with a mock
implementation:
[source,java,indent=0]
----
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;
import org.springframework.test.context.junit4.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {
@MockBean
private RemoteService remoteService;
@Autowired
private Reverser reverser;
@Test
public void exampleTest() {
// RemoteService has been injected into the reverser bean
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}
}
----
Additionally you can also use `@SpyBean` to wrap any existing bean with a Mockito `spy`.
See the Javadoc for full details.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-tests]]
==== Auto-configured tests
Spring Boot's auto-configuration system works well for applications, but can sometimes be
a little too much for tests. It's often helpful to load only the parts of the
configuration that are required to test a '`slice`' of your application. For example, you
might want to test that Spring MVC controllers are mapping URLs correctly, and you don't
want to involve database calls in those tests; or you _might be wanting_ to test JPA
entities, and you're not interested in web layer when those tests run.
The `spring-boot-test-autoconfigure` module includes a number of annotations that can be
used to automatically configure such '`slices`'. Each of them works in a similar way,
providing a `@...Test` annotation that loads the `ApplicationContext` and one or
more `@AutoConfigure...` annotations that can be used to customize auto-configuration
settings.
NOTE: Each slice loads a very restricted set of auto-configuration classes. If you need to
exclude one of them, most `@...Test` annotations provide an `excludeAutoConfiguration`
attribute. Alternatively, you can use `@ImportAutoConfiguration#exclude`.
TIP: It's also possible to use the `@AutoConfigure...` annotations with the standard
`@SpringBootTest` annotation. You can use this combination if you're not interested
in '`slicing`' your application but you want some of the auto-configured test beans.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-json-tests]]
==== Auto-configured JSON tests
To test that Object JSON serialization and deserialization is working as expected you can
use the `@JsonTest` annotation. `@JsonTest` will auto-configure the available supported
json mapper:
* Jackson `ObjectMapper`, any `@JsonComponent` beans and any Jackson `Modules`
* `Gson`
* `Jsonb`
If you need to configure elements of the auto-configuration you can use the
`@AutoConfigureJsonTesters` annotation.
Spring Boot includes AssertJ based helpers that work with the JSONassert and JsonPath
libraries to check that JSON is as expected. The `JacksonTester`, `GsonTester`,
`JsonbTester` and `BasicJsonTester` classes can be used for Jackson, Gson, Jsonb and
Strings respectively. Any helper fields on the test class can be `@Autowired` when using
`@JsonTest`.
[source,java,indent=0]
----
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.json.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.json.*;
import org.springframework.test.context.junit4.*;
import static org.assertj.core.api.Assertions.*;
@RunWith(SpringRunner.class)
@JsonTest
public class MyJsonTests {
@Autowired
private JacksonTester<VehicleDetails> json;
@Test
public void testSerialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
.isEqualTo("Honda");
}
@Test
public void testDeserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content))
.isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}
}
----
NOTE: JSON helper classes can also be used directly in standard unit tests. Simply
call the `initFields` method of the helper in your `@Before` method if you aren't using
`@JsonTest`.
A list of the auto-configuration that is enabled by `@JsonTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests]]
==== Auto-configured Spring MVC tests
To test Spring MVC controllers are working as expected you can use the `@WebMvcTest`
annotation. `@WebMvcTest` will auto-configure the Spring MVC infrastructure and limit
scanned beans to `@Controller`, `@ControllerAdvice`, `@JsonComponent`, `Filter`,
`WebMvcConfigurer` and `HandlerMethodArgumentResolver`. Regular `@Component` beans
will not be scanned when using this annotation.
Often `@WebMvcTest` will be limited to a single controller and used in combination with
`@MockBean` to provide mock implementations for required collaborators.
`@WebMvcTest` also auto-configures `MockMvc`. Mock MVC offers a powerful way to quickly
test MVC controllers without needing to start a full HTTP server.
TIP: You can also auto-configure `MockMvc` in a non-`@WebMvcTest` (e.g. `SpringBootTest`)
by annotating it with `@AutoConfigureMockMvc`.
[source,java,indent=0]
----
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private UserVehicleService userVehicleService;
@Test
public void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
}
}
----
TIP: If you need to configure elements of the auto-configuration (for example when servlet
filters should be applied) you can use attributes in the `@AutoConfigureMockMvc`
annotation.
If you use HtmlUnit or Selenium, auto-configuration will also provide an HTMLUnit `WebClient` bean
and/or a `WebDriver` bean. Here is an example that uses HtmlUnit:
[source,java,indent=0]
----
import com.gargoylesoftware.htmlunit.*;
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyHtmlUnitTests {
@Autowired
private WebClient webClient;
@MockBean
private UserVehicleService userVehicleService;
@Test
public void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
}
}
----
NOTE: By default Spring Boot will put `WebDriver` beans in a special "`scope`" to ensure
that the driver is quit after each test, and that a new instance is injected. If you don't
want this behavior you can add `@Scope("singleton")` to your `WebDriver` `@Bean`
definition.
A list of the auto-configuration that is enabled by `@WebMvcTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-webflux-tests]]
==== Auto-configured Spring WebFlux tests
To test Spring WebFlux controllers are working as expected you can use the `@WebFluxTest`
annotation. `@WebFluxTest` will auto-configure the Spring WebFlux infrastructure and limit
scanned beans to `@Controller`, `@ControllerAdvice`, `@JsonComponent`,and
`WebFluxConfigurer`. Regular `@Component` beans will not be scanned when using this
annotation.
Often `@WebFluxTest` will be limited to a single controller and used in combination with
`@MockBean` to provide mock implementations for required collaborators.
`@WebFluxTest` also auto-configures `WebTestClient`, which offers a powerful way to quickly
test WebFlux controllers without needing to start a full HTTP server.
TIP: You can also auto-configure `WebTestClient` in a non-`@WebFluxTest`
(e.g. `SpringBootTest`) by annotating it with `@AutoConfigureWebTestClient`.
[source,java,indent=0]
----
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
@RunWith(SpringRunner.class)
@WebFluxTest(UserVehicleController.class)
public class MyControllerTests {
@Autowired
private WebTestClient webClient;
@MockBean
private UserVehicleService userVehicleService;
@Test
public void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Honda Civic");
}
}
----
A list of the auto-configuration that is enabled by `@WebFluxTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test]]
==== Auto-configured Data JPA tests
`@DataJpaTest` can be used if you want to test JPA applications. By default it will
configure an in-memory embedded database, scan for `@Entity` classes and configure Spring
Data JPA repositories. Regular `@Component` beans will not be loaded into the
`ApplicationContext`.
Data JPA tests are transactional and rollback at the end of each test by default,
see the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section] in the
Spring Reference Documentation for more details. If that's not what you want, you can
disable transaction management for a test or for the whole class as follows:
[source,java,indent=0]
----
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringRunner.class)
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ExampleNonTransactionalTests {
}
----
Data JPA tests may also inject a
{sc-spring-boot-test-autoconfigure}/orm/jpa/TestEntityManager.{sc-ext}[`TestEntityManager`]
bean which provides an alternative to the standard JPA `EntityManager` specifically
designed for tests. If you want to use `TestEntityManager` outside of `@DataJpaTests` you
can also use the `@AutoConfigureTestEntityManager` annotation. A `JdbcTemplate` is also
available if you need that.
[source,java,indent=0]
----
import org.junit.*;
import org.junit.runner.*;
import org.springframework.boot.test.autoconfigure.orm.jpa.*;
import static org.assertj.core.api.Assertions.*;
@RunWith(SpringRunner.class)
@DataJpaTest
public class ExampleRepositoryTests {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository repository;
@Test
public void testExample() throws Exception {
this.entityManager.persist(new User("sboot", "1234"));
User user = this.repository.findByUsername("sboot");
assertThat(user.getUsername()).isEqualTo("sboot");
assertThat(user.getVin()).isEqualTo("1234");
}
}
----
In-memory embedded databases generally work well for tests since they are fast and don't
require any developer installation. If, however, you prefer to run tests against a real
database you can use the `@AutoConfigureTestDatabase` annotation:
[source,java,indent=0]
----
@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class ExampleRepositoryTests {
// ...
}
----
A list of the auto-configuration that is enabled by `@DataJpaTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test]]
==== Auto-configured JDBC tests
`@JdbcTest` is similar to `@DataJpaTest` but for pure jdbc-related tests. By default it
will also configure an in-memory embedded database and a `JdbcTemplate`. Regular
`@Component` beans will not be loaded into the `ApplicationContext`.
JDBC tests are transactional and rollback at the end of each test by default,
see the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section] in the
Spring Reference Documentation for more details. If that's not what you want, you can
disable transaction management for a test or for the whole class as follows:
[source,java,indent=0]
----
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringRunner.class)
@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ExampleNonTransactionalTests {
}
----
If you prefer your test to run against a real database, you can use the
`@AutoConfigureTestDatabase` annotation the same way as for `DataJpaTest`.
A list of the auto-configuration that is enabled by `@JdbcTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jooq-test]]
==== Auto-configured jOOQ tests
`@JooqTest` can be used in a similar fashion as `@JdbcTest` but for jOOQ related tests. As
jOOQ relies heavily on a Java-based schema that corresponds with the database schema, the
existing `DataSource` will be used. If you want to replace it by an in-memory database you
can use `@AutoconfigureTestDatabase` to override those settings.
`@JooqTest` will configure a `DSLContext`. Regular `@Component` beans will not be loaded
into the `ApplicationContext`:
[source,java,indent=0]
----
import org.jooq.DSLContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.jooq.JooqTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@JooqTest
public class ExampleJooqTests {
@Autowired
private DSLContext dslContext;
}
----
JOOQ tests are transactional and rollback at the end of each test by default. If that's
not what you want, you can disable transaction management for a test or for the whole test
class as <<boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test,shown
in the example above>>.
A list of the auto-configuration that is enabled by `@JooqTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-mongo-test]]
==== Auto-configured Data MongoDB tests
`@DataMongoTest` can be used if you want to test MongoDB applications. By default, it will
configure an in-memory embedded MongoDB (if available), configure a `MongoTemplate`, scan
for `@Document` classes and configure Spring Data MongoDB repositories. Regular
`@Component` beans will not be loaded into the `ApplicationContext`:
[source,java,indent=0]
----
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataMongoTest
public class ExampleDataMongoTests {
@Autowired
private MongoTemplate mongoTemplate;
//
}
----
In-memory embedded MongoDB generally works well for tests since it is fast and doesn't
require any developer installation. If, however, you prefer to run tests against a real
MongoDB server you should exclude the embedded MongoDB auto-configuration:
[source,java,indent=0]
----
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
public class ExampleDataMongoNonEmbeddedTests {
}
----
A list of the auto-configuration that is enabled by `@DataMongoTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-neo4j-test]]
==== Auto-configured Data Neo4j tests
`@DataNeo4jTest` can be used if you want to test Neo4j applications. By default, it will
use an in-memory embedded Neo4j (if the embedded driver is available), scan for
`@NodeEntity` classes and configure Spring Data Neo4j repositories. Regular `@Component`
beans will not be loaded into the `ApplicationContext`:
[source,java,indent=0]
----
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataNeo4jTest
public class ExampleDataNeo4jTests {
@Autowired
private YourRepository repository;
//
}
----
Data Neo4j tests are transactional and rollback at the end of each test by default,
see the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section] in the
Spring Reference Documentation for more details. If that's not what you want, you can
disable transaction management for a test or for the whole class as follows:
[source,java,indent=0]
----
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringRunner.class)
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ExampleNonTransactionalTests {
}
----
A list of the auto-configuration that is enabled by `@DataNeo4jTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-redis-test]]
==== Auto-configured Data Redis tests
`@DataRedisTest` can be used if you want to test Redis applications. By default, it will
scan for `@RedisHash` classes and configure Spring Data Redis repositories. Regular
`@Component` beans will not be loaded into the `ApplicationContext`:
[source,java,indent=0]
----
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataRedisTest
public class ExampleDataRedisTests {
@Autowired
private YourRepository repository;
//
}
----
A list of the auto-configuration that is enabled by `@DataRedisTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-ldap-test]]
==== Auto-configured Data LDAP tests
`@DataLdapTest` can be used if you want to test LDAP applications. By default, it will
configure an in-memory embedded LDAP (if available), a `LdapTemplate`, scan for `@Entry`
classes and configure Spring Data LDAP repositories. Regular `@Component` beans will not
be loaded into the `ApplicationContext`:
[source,java,indent=0]
----
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataLdapTest
public class ExampleDataLdapTests {
@Autowired
private LdapTemplate ldapTemplate;
//
}
----
In-memory embedded LDAP generally works well for tests since it is fast and doesn't
require any developer installation. If, however, you prefer to run tests against a real
LDAP server you should exclude the embedded LDAP auto-configuration:
[source,java,indent=0]
----
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
public class ExampleDataLdapNonEmbeddedTests {
}
----
A list of the auto-configuration that is enabled by `@DataLdapTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-client]]
==== Auto-configured REST clients
The `@RestClientTest` annotation can be used if you want to test REST clients. By default
it will auto-configure Jackson, GSON and Jsonb support, configure a `RestTemplateBuilder`
and add support for `MockRestServiceServer`. The specific beans that you want to test
should be specified using `value` or `components` attribute of `@RestClientTest`:
[source,java,indent=0]
----
@RunWith(SpringRunner.class)
@RestClientTest(RemoteVehicleDetailsService.class)
public class ExampleRestClientTest {
@Autowired
private RemoteVehicleDetailsService service;
@Autowired
private MockRestServiceServer server;
@Test
public void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()
throws Exception {
this.server.expect(requestTo("/greet/details"))
.andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
String greeting = this.service.callRestService();
assertThat(greeting).isEqualTo("hello");
}
}
----
A list of the auto-configuration that is enabled by `@RestClientTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs]]
==== Auto-configured Spring REST Docs tests
The `@AutoConfigureRestDocs` annotation can be used if you want to use Spring REST Docs
in your tests with Mock MVC or REST Assured. It removes the need for Spring REST Docs'
JUnit rule.
`@AutoConfigureRestDocs` can be used to override the default output directory
(`target/generated-snippets` if you are using Maven or `build/generated-snippets` if you
are using Gradle). It can also be used to configure the host, scheme, and port that will
appear in any documented URIs.
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-mock-mvc]]
===== Auto-configured Spring REST Docs tests with Mock MVC
`@AutoConfigureRestDocs` customizes the `MockMvc` bean to use Spring REST Docs, Inject it
using `@Autowired` and use it in your tests as you normally would when using Mock MVC and
Spring REST Docs:
[source,java,indent=0]
----
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
public class UserDocumentationTests {
@Autowired
private MockMvc mvc;
@Test
public void listUsers() throws Exception {
this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andDo(document("list-users"));
}
}
----
If you require more control over Spring REST Docs' configuration than offered by the
attributes of `@AutoConfigureRestDocs`, a `RestDocsMockMvcConfigurationCustomizer` bean
can be used:
[source,java,indent=0]
----
@TestConfiguration
static class CustomizationConfiguration
implements RestDocsMockMvcConfigurationCustomizer {
@Override
public void customize(MockMvcRestDocumentationConfigurer configurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
}
}
----
If you want to make use of Spring REST Docs' support for a parameterized output directory,
you can create a `RestDocumentationResultHandler` bean. The auto-configuration will
call `alwaysDo` with this result handler, thereby causing each `MockMvc` call to
automatically generate the default snippets:
[source,java,indent=0]
----
@TestConfiguration
static class ResultHandlerConfiguration {
@Bean
public RestDocumentationResultHandler restDocumentation() {
return MockMvcRestDocumentation.document("{method-name}");
}
}
----
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-rest-assured]]
===== Auto-configured Spring REST Docs tests with REST Assured
`@AutoConfigureRestDocs` makes a `RequestSpecification` bean, preconfigured to use Spring REST
Docs, available to your tests. Inject it using `@Autowired` and use it in your tests as you
normally would when using REST Assured and Spring REST Docs:
[source,java,indent=0]
----
include::{code-examples}/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java[tag=source]
----
If you require more control over Spring REST Docs' configuration than offered by the
attributes of `@AutoConfigureRestDocs`, a `RestDocsRestAssuredConfigurationCustomizer`
bean can be used:
[source,java,indent=0]
----
include::{code-examples}/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java[tag=configuration]
----
[[boot-features-testing-spring-boot-applications-with-spock]]
==== Using Spock to test Spring Boot applications
If you wish to use Spock to test a Spring Boot application you should add a dependency
on Spock's `spock-spring` module to your application's build. `spock-spring` integrates
Spring's test framework into Spock. It is recommended that you use Spock 1.1 or later to
benefit from a number of recent improvements to Spock's Spring Framework and Spring Boot
integration. Please refer to http://spockframework.org/spock/docs/1.1/modules.html[the
documentation for Spock's Spring module] for further details.
[[boot-features-test-utilities]]
=== Test utilities
A few test utility classes are packaged as part of `spring-boot` that are generally
useful when testing your application.
[[boot-features-configfileapplicationcontextinitializer-test-utility]]
==== ConfigFileApplicationContextInitializer
`ConfigFileApplicationContextInitializer` is an `ApplicationContextInitializer` that
can apply to your tests to load Spring Boot `application.properties` files. You can use
this when you don't need the full features provided by `@SpringBootTest`.
[source,java,indent=0]
----
@ContextConfiguration(classes = Config.class,
initializers = ConfigFileApplicationContextInitializer.class)
----
NOTE: Using `ConfigFileApplicationContextInitializer` alone won't provide support for
`@Value("${...}")` injection. Its only job is to ensure that `application.properties` files
are loaded into Spring's `Environment`. For `@Value` support you need to either
additionally configure a `PropertySourcesPlaceholderConfigurer` or use `@SpringBootTest`
where one will be auto-configured for you.
[[boot-features-environment-test-utilities]]
==== EnvironmentTestUtils
`EnvironmentTestUtils` allows you to quickly add properties to a
`ConfigurableEnvironment` or `ConfigurableApplicationContext`. Simply call it with
`key=value` strings:
[source,java,indent=0]
----
EnvironmentTestUtils.addEnvironment(env, "org=Spring", "name=Boot");
----
[[boot-features-output-capture-test-utility]]
==== OutputCapture
`OutputCapture` is a JUnit `Rule` that you can use to capture `System.out` and
`System.err` output. Simply declare the capture as a `@Rule` then use `toString()`
for assertions:
[source,java,indent=0]
----
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.rule.OutputCapture;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class MyTest {
@Rule
public OutputCapture capture = new OutputCapture();
@Test
public void testName() throws Exception {
System.out.println("Hello World!");
assertThat(capture.toString(), containsString("World"));
}
}
----
[[boot-features-rest-templates-test-utility]]
==== TestRestTemplate
`TestRestTemplate` is a convenience alternative to Spring's `RestTemplate` that is useful
in integration tests. You can get a vanilla template or one that sends Basic HTTP
authentication (with a username and password). In either case the template will behave
in a test-friendly way by not throwing exceptions on server-side errors. It is
recommended, but not mandatory, to use Apache HTTP Client (version 4.3.2 or better), and
if you have that on your classpath the `TestRestTemplate` will respond by configuring
the client appropriately. If you do use Apache's HTTP client some additional test-friendly
features will be enabled:
* Redirects will not be followed (so you can assert the response location)
* Cookies will be ignored (so the template is stateless)
`TestRestTemplate` can be instantiated directly in your integration tests:
[source,java,indent=0]
----
public class MyTest {
private TestRestTemplate template = new TestRestTemplate();
@Test
public void testRequest() throws Exception {
HttpHeaders headers = template.getForEntity("http://myhost.com/example", String.class).getHeaders();
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
}
}
----
Alternatively, if you are using the `@SpringBootTest` annotation with
`WebEnvironment.RANDOM_PORT` or `WebEnvironment.DEFINED_PORT`, you can just inject a
fully configured `TestRestTemplate` and start using it. If necessary, additional
customizations can be applied via the `RestTemplateBuilder` bean. Any URLs that do not
specify a host and port will automatically connect to the embedded server:
[source,java,indent=0]
----
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private TestRestTemplate template;
@Test
public void testRequest() throws Exception {
HttpHeaders headers = template.getForEntity("/example", String.class).getHeaders();
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
}
@TestConfiguration
static class Config {
@Bean
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder()
.additionalMessageConverters(...)
.customizers(...);
}
}
}
----
[[boot-features-websockets]]
== WebSockets
Spring Boot provides WebSockets auto-configuration for embedded Tomcat (8 and 7), Jetty 9
and Undertow. If you're deploying a war file to a standalone container, Spring Boot
assumes that the container will be responsible for the configuration of its WebSocket
support.
Spring Framework provides {spring-reference}web.html#websocket[rich WebSocket support] that can
be easily accessed via the `spring-boot-starter-websocket` module.
[[boot-features-webservices]]
== Web Services
Spring Boot provides Web Services auto-configuration so that all is required is defining
your `Endpoints`.
The {spring-webservices-reference}[Spring Web Services features] can be easily accessed
via the `spring-boot-starter-webservices` module.
`SimpleWsdl11Definition` and `SimpleXsdSchema` beans can be automatically created for your
WSDLs and XSDs respectively. To do so, configure their location:
[source,properties,indent=0]
----
spring.webservices.wsdl-locations=classpath:/wsdl
----
[[boot-features-developing-auto-configuration]]
== Creating your own auto-configuration
If you work in a company that develops shared libraries, or if you work on an open-source
or commercial library, you might want to develop your own auto-configuration.
Auto-configuration classes can be bundled in external jars and still be picked-up by
Spring Boot.
Auto-configuration can be associated to a "starter" that provides the auto-configuration
code as well as the typical libraries that you would use with it. We will first cover what
you need to know to build your own auto-configuration and we will move on to the
<<boot-features-custom-starter,typical steps required to create a custom starter>>.
TIP: A https://github.com/snicoll-demos/spring-boot-master-auto-configuration[demo project]
is available to showcase how you can create a starter step by step.
[[boot-features-understanding-auto-configured-beans]]
=== Understanding auto-configured beans
Under the hood, auto-configuration is implemented with standard `@Configuration` classes.
Additional `@Conditional` annotations are used to constrain when the auto-configuration
should apply. Usually auto-configuration classes use `@ConditionalOnClass` and
`@ConditionalOnMissingBean` annotations. This ensures that auto-configuration only applies
when relevant classes are found and when you have not declared your own `@Configuration`.
You can browse the source code of {sc-spring-boot-autoconfigure}[`spring-boot-autoconfigure`]
to see the `@Configuration` classes that we provide (see the
{github-code}/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories[`META-INF/spring.factories`]
file).
[[boot-features-locating-auto-configuration-candidates]]
=== Locating auto-configuration candidates
Spring Boot checks for the presence of a `META-INF/spring.factories` file within your
published jar. The file should list your configuration classes under the
`EnableAutoConfiguration` key.
[indent=0]
----
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
----
You can use the
{sc-spring-boot-autoconfigure}/AutoConfigureAfter.{sc-ext}[`@AutoConfigureAfter`] or
{sc-spring-boot-autoconfigure}/AutoConfigureBefore.{sc-ext}[`@AutoConfigureBefore`]
annotations if your configuration needs to be applied in a specific order. For example, if
you provide web-specific configuration, your class may need to be applied after
`WebMvcAutoConfiguration`.
If you want to order certain auto-configurations that shouldn't have any direct
knowledge of each other, you can also use `@AutoconfigureOrder`. That annotation has the
same semantic as the regular `@Order` annotation but provides a dedicated order for
auto-configuration classes.
[NOTE]
====
Auto-configurations have to be loaded that way _only_. Make sure that they are defined in
a specific package space and that they are never the target of component scan in
particular.
====
[[boot-features-condition-annotations]]
=== Condition annotations
You almost always want to include one or more `@Conditional` annotations on your
auto-configuration class. The `@ConditionalOnMissingBean` is one common example that is
used to allow developers to '`override`' auto-configuration if they are not happy with
your defaults.
Spring Boot includes a number of `@Conditional` annotations that you can reuse in your own
code by annotating `@Configuration` classes or individual `@Bean` methods.
[[boot-features-class-conditions]]
==== Class conditions
The `@ConditionalOnClass` and `@ConditionalOnMissingClass` annotations allows
configuration to be included based on the presence or absence of specific classes. Due to
the fact that annotation metadata is parsed using http://asm.ow2.org/[ASM] you can
actually use the `value` attribute to refer to the real class, even though that class
might not actually appear on the running application classpath. You can also use the
`name` attribute if you prefer to specify the class name using a `String` value.
[TIP]
====
If you are using `@ConditionalOnClass` or `@ConditionalOnMissingClass` as a part of a
meta-annotation to compose your own composed annotations you must use `name` as referring
to the class in such a case is not handled.
====
[[boot-features-bean-conditions]]
==== Bean conditions
The `@ConditionalOnBean` and `@ConditionalOnMissingBean` annotations allow a bean
to be included based on the presence or absence of specific beans. You can use the `value`
attribute to specify beans by type, or `name` to specify beans by name. The `search`
attribute allows you to limit the `ApplicationContext` hierarchy that should be considered
when searching for beans.
When placed on a `@Bean` method, the target type defaults to the return type of the
method, for instance:
[source,java,indent=0]
----
@Configuration
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() { ... }
}
----
In the example above, the `myService` bean is going to be created if no bean of type
`MyService` is already contained in the `ApplicationContext`.
TIP: You need to be very careful about the order that bean definitions are added as these
conditions are evaluated based on what has been processed so far. For this reason,
we recommend only using `@ConditionalOnBean` and `@ConditionalOnMissingBean` annotations
on auto-configuration classes (since these are guaranteed to load after any user-defined
beans definitions have been added).
NOTE: `@ConditionalOnBean` and `@ConditionalOnMissingBean` do not prevent `@Configuration`
classes from being created. Using these conditions at the class level is equivalent to
marking each contained `@Bean` method with the annotation.
[[boot-features-property-conditions]]
==== Property conditions
The `@ConditionalOnProperty` annotation allows configuration to be included based on a
Spring Environment property. Use the `prefix` and `name` attributes to specify the
property that should be checked. By default any property that exists and is not equal to
`false` will be matched. You can also create more advanced checks using the `havingValue`
and `matchIfMissing` attributes.
[[boot-features-resource-conditions]]
==== Resource conditions
The `@ConditionalOnResource` annotation allows configuration to be included only when a
specific resource is present. Resources can be specified using the usual Spring
conventions, for example, `file:/home/user/test.dat`.
[[boot-features-web-application-conditions]]
==== Web application conditions
The `@ConditionalOnWebApplication` and `@ConditionalOnNotWebApplication` annotations
allow configuration to be included depending on whether the application is a 'web
application'. A web application is any application that is using a Spring
`WebApplicationContext`, defines a `session` scope or has a `StandardServletEnvironment`.
[[boot-features-spel-conditions]]
==== SpEL expression conditions
The `@ConditionalOnExpression` annotation allows configuration to be included based on the
result of a {spring-reference}core.html#expressions[SpEL expression].
[[boot-features-custom-starter]]
=== Creating your own starter
A full Spring Boot starter for a library may contain the following components:
* The `autoconfigure` module that contains the auto-configuration code.
* The `starter` module that provides a dependency to the autoconfigure module as well as
the library and any additional dependencies that are typically useful. In a nutshell,
adding the starter should be enough to start using that library.
TIP: You may combine the auto-configuration code and the dependency management in a single
module if you don't need to separate those two concerns.
[[boot-features-custom-starter-naming]]
==== Naming
Please make sure to provide a proper namespace for your starter. Do not start your module
names with `spring-boot`, even if you are using a different Maven groupId. We may offer an
official support for the thing you're auto-configuring in the future.
Here is a rule of thumb. Let's assume that you are creating a starter for "acme", name the
auto-configure module `acme-spring-boot-autoconfigure` and the starter
`acme-spring-boot-starter`. If you only have one module combining the two, use
`acme-spring-boot-starter`.
Besides, if your starter provides configuration keys, use a proper namespace for them. In
particular, do not include your keys in the namespaces that Spring Boot uses (e.g.
`server`, `management`, `spring`, etc). These are "ours" and we may improve/modify them
in the future in such a way it could break your things.
Make sure to
<<appendix-configuration-metadata#configuration-metadata-annotation-processor,trigger
meta-data generation>> so that IDE assistance is available for your keys as well. You
may want to review the generated meta-data (`META-INF/spring-configuration-metadata.json`)
to make sure your keys are properly documented.
[[boot-features-custom-starter-module-autoconfigure]]
==== Autoconfigure module
The autoconfigure module contains everything that is necessary to get started with the
library. It may also contain configuration keys definition (`@ConfigurationProperties`)
and any callback interface that can be used to further customize how the components are
initialized.
TIP: You should mark the dependencies to the library as optional so that you can include
the autoconfigure module in your projects more easily. If you do it that way, the library
won't be provided and Spring Boot will back off by default.
[[boot-features-custom-starter-module-starter]]
==== Starter module
The starter is an empty jar, really. Its only purpose is to provide the necessary
dependencies to work with the library; see it as an opinionated view of what is required
to get started.
Do not make assumptions about the project in which your starter is added. If the library
you are auto-configuring typically requires other starters, mention them as well. Providing
a proper set of _default_ dependencies may be hard if the number of optional dependencies
is high as you should avoid bringing unnecessary dependencies for a typical usage of the
library.
[[boot-features-whats-next]]
== What to read next
If you want to learn more about any of the classes discussed in this section you can
check out the {dc-root}[Spring Boot API documentation] or you can browse the
{github-code}[source code directly]. If you have specific questions, take a look at the
<<howto.adoc#howto, how-to>> section.
If you are comfortable with Spring Boot's core features, you can carry on and read
about <<production-ready-features.adoc#production-ready, production-ready features>>.