You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5539 lines
204 KiB
5539 lines
204 KiB
[[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] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@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.TomcatEmbeddedServletContainerFactory : 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-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] |
|
---- |
|
new SpringApplicationBuilder() |
|
.bannerMode(Banner.Mode.OFF) |
|
.sources(Parent.class) |
|
.child(Application.class) |
|
.run(args); |
|
---- |
|
|
|
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 `ApplicationStartedEvent` 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 |
|
`AnnotationConfigEmbeddedWebApplicationContext` 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 the application ends. |
|
|
|
|
|
|
|
[[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: |
|
|
|
. {spring-javadoc}/test/context/TestPropertySource.{dc-ext}[`@TestPropertySource`] |
|
annotations 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. |
|
|
|
The default search path `classpath:,classpath:/config,file:,file:config/` |
|
is always used, irrespective of the value of `spring.config.location`. This search path |
|
is ordered from lowest to highest precedence (`file:config/` wins). If you do specify |
|
your own locations, they take precedence over all of the default locations and use the |
|
same lowest to highest precedence ordering. In that way you can set up default values for |
|
your application in `application.properties` (or whatever other basename you choose with |
|
`spring.config.name`) and override it at runtime with a different file, keeping the |
|
defaults. |
|
|
|
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; |
|
} |
|
} |
|
---- |
|
|
|
|
|
|
|
[[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-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. For example: |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Component |
|
@ConfigurationProperties(prefix="connection") |
|
public class ConnectionSettings { |
|
|
|
private String username; |
|
|
|
private InetAddress remoteAddress; |
|
|
|
// ... getters and setters |
|
|
|
} |
|
---- |
|
|
|
NOTE: The getters and setters are advisable, since binding is via standard Java Beans |
|
property descriptors, just like in Spring MVC. They are mandatory for immutable types or |
|
those that are directly coercible from `String`. As long as they are initialized, maps, |
|
collections, and arrays need a getter but not necessarily a setter since they can be |
|
mutated by the binder. If there is a setter, Maps, collections, and arrays can be created. |
|
Maps and collections can be expanded with only a getter, whereas arrays require a setter. |
|
Nested POJO properties can also be created (so a setter is not mandatory) if they have a |
|
default constructor, or a constructor accepting a single value that can be coerced from |
|
String. Some people use Project Lombok to add getters and setters automatically. |
|
|
|
NOTE: Contrary to `@Value`, SpEL expressions are not evaluated prior to injecting a value |
|
in the relevant `@ConfigurationProperties` bean. |
|
|
|
The `@EnableConfigurationProperties` annotation is automatically applied to your project |
|
so that any beans annotated with `@ConfigurationProperties` will be configured from the |
|
`Environment` properties. This style of configuration works particularly well with the |
|
`SpringApplication` external YAML configuration: |
|
|
|
[source,yaml,indent=0] |
|
---- |
|
# application.yml |
|
|
|
connection: |
|
username: admin |
|
remoteAddress: 192.168.1.1 |
|
|
|
# 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 { |
|
|
|
@Autowired |
|
private ConnectionSettings connection; |
|
|
|
//... |
|
|
|
@PostConstruct |
|
public void openConnection() { |
|
Server server = new Server(); |
|
this.connection.configure(server); |
|
} |
|
|
|
} |
|
---- |
|
|
|
It is also possible to shortcut the registration of `@ConfigurationProperties` bean |
|
definitions by simply listing the properties classes directly in the |
|
`@EnableConfigurationProperties` annotation: |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Configuration |
|
@EnableConfigurationProperties(ConnectionSettings.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 `connection-com.example.ConnectionSettings`, |
|
assuming that `ConnectionSettings` sits in the `com.example` package. |
|
==== |
|
|
|
TIP: Using `@ConfigurationProperties` also allows you to generate meta-data files that can |
|
be used by IDEs. 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 `@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 = "foo") |
|
@Bean |
|
public FooComponent fooComponent() { |
|
... |
|
} |
|
---- |
|
|
|
Any property defined with the `foo` prefix will be mapped onto that `FooComponent` bean |
|
in a similar manner as the `ConnectionSettings` 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] |
|
---- |
|
@Component |
|
@ConfigurationProperties(prefix="person") |
|
public class ConnectionSettings { |
|
|
|
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` |
|
|Dashed notation, recommended for use in `.properties` and `.yml` files. |
|
|
|
|`person.first_name` |
|
|Underscore notation, alternative format for use in `.properties` and `.yml` files. |
|
|
|
|`PERSON_FIRST_NAME` |
|
|Upper case format. Recommended when using a system environment variables. |
|
|=== |
|
|
|
|
|
|
|
[[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 external configuration, by default using JSR-303 |
|
(if it is on the classpath). You can simply add JSR-303 `javax.validation` constraint |
|
annotations to your `@ConfigurationProperties` class: |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Component |
|
@ConfigurationProperties(prefix="connection") |
|
public class ConnectionSettings { |
|
|
|
@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 |
|
`ConnectionSettings` example: |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Component |
|
@ConfigurationProperties(prefix="connection") |
|
public class ConnectionSettings { |
|
|
|
@NotNull |
|
@Valid |
|
private RemoteAddress remoteAddress; |
|
|
|
// ... getters and setters |
|
|
|
public static class RemoteAddress { |
|
|
|
@NotEmpty |
|
public String hostname; |
|
|
|
// ... getters and setters |
|
|
|
} |
|
|
|
} |
|
---- |
|
|
|
You can also add a custom Spring `Validator` by creating a bean definition called |
|
`configurationPropertiesValidator`. There is a |
|
{github-code}/spring-boot-samples/spring-boot-sample-property-validation[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 `/configprops` |
|
or use the equivalent JMX endpoint. See the |
|
_<<production-ready-features.adoc#production-ready-endpoints, Production ready features>>_. |
|
section for details. |
|
|
|
|
|
[[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/7/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. |
|
|
|
|
|
|
|
==== 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> |
|
---- |
|
|
|
TIP: The `RelaxedPropertyResolver` is used to access `Environment` properties. If specify |
|
the `source` in dashed notation (`my-property-name`) all the relaxed variations will be |
|
tried (`myPropertyName`, `MY_PROPERTY_NAME` etc). |
|
|
|
|
|
|
|
[[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, or Undertow. Most web |
|
applications will use the `spring-boot-starter-web` module to get up and running quickly. |
|
|
|
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}#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. |
|
* 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}#mvc[MVC configuration] (interceptors, |
|
formatters, view controllers etc.) you can add your own `@Bean` of type |
|
`WebMvcConfigurerAdapter`, 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 `WebMvcConfigurerAdapter` 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`. |
|
|
|
You can customize the static resource locations using `spring.resources.staticLocations` |
|
(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: 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. |
|
|
|
For example, 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, Velocity 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}/#mvc-config-static-resources[reference documentation]. |
|
==== |
|
|
|
|
|
|
|
[[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 Velocity, 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://velocity.apache.org[Velocity] (deprecated in 1.4) |
|
* 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 `CustomerErrorType` 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}/#mvc-exceptionhandlers[`@ExceptionHandler` methods] and |
|
{spring-reference}/#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}/#cors[supports CORS] out of the box. |
|
Using {spring-reference}/#_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}/#_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 WebMvcConfigurerAdapter() { |
|
@Override |
|
public void addCorsMappings(CorsRegistry registry) { |
|
registry.addMapping("/api/**"); |
|
} |
|
}; |
|
} |
|
} |
|
---- |
|
|
|
|
|
|
|
[[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); |
|
} |
|
|
|
} |
|
---- |
|
|
|
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`. |
|
|
|
|
|
|
|
[[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.context.embedded.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 EmbeddedWebApplicationContext |
|
Under the hood Spring Boot uses a new type of `ApplicationContext` for embedded servlet |
|
container support. The `EmbeddedWebApplicationContext` is a special type of |
|
`WebApplicationContext` that bootstraps itself by searching for a single |
|
`EmbeddedServletContainerFactory` bean. Usually a `TomcatEmbeddedServletContainerFactory`, |
|
`JettyEmbeddedServletContainerFactory`, or `UndertowEmbeddedServletContainerFactory` 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 |
|
`EmbeddedServletContainerFactory` 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 `EmbeddedServletContainerCustomizer` interface. |
|
`EmbeddedServletContainerCustomizer` provides access to the |
|
`ConfigurableEmbeddedServletContainer` which includes numerous customization setter |
|
methods. |
|
|
|
[source,java,indent=0] |
|
---- |
|
import org.springframework.boot.context.embedded.*; |
|
import org.springframework.stereotype.Component; |
|
|
|
@Component |
|
public class CustomizationBean implements EmbeddedServletContainerCustomizer { |
|
|
|
@Override |
|
public void customize(ConfigurableEmbeddedServletContainer container) { |
|
container.setPort(9000); |
|
} |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[boot-features-customizing-configurableembeddedservletcontainerfactory-directly]] |
|
===== Customizing ConfigurableEmbeddedServletContainer directly |
|
If the above customization techniques are too limited, you can register the |
|
`TomcatEmbeddedServletContainerFactory`, `JettyEmbeddedServletContainerFactory` or |
|
`UndertowEmbeddedServletContainerFactory` bean yourself. |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Bean |
|
public EmbeddedServletContainerFactory servletContainer() { |
|
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); |
|
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 security configuration |
|
completely you can add a bean with `@EnableWebSecurity` (this does not disable the |
|
authentication manager configuration). To customize |
|
it you normally use external properties and beans of type `WebSecurityConfigurerAdapter` |
|
(e.g. to add form-based login). 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)`. |
|
|
|
|
|
|
|
[[boot-features-security-oauth2]] |
|
=== OAuth2 |
|
If you have `spring-security-oauth2` on your classpath you can take advantage of some |
|
auto-configuration to make it easy to set up Authorization or Resource Server. |
|
|
|
|
|
|
|
[[boot-features-security-oauth2-authorization-server]] |
|
==== Authorization Server |
|
To create an Authorization Server and grant access tokens you need to use |
|
`@EnableAuthorizationServer` and provide `security.oauth2.client.client-id` and |
|
`security.oauth2.client.client-secret]` properties. The client will be registered for you |
|
in an in-memory repository. |
|
|
|
Having done that you will be able to use the client credentials to create an access token, |
|
for example: |
|
|
|
[indent=0] |
|
---- |
|
$ curl client:secret@localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd |
|
---- |
|
|
|
The basic auth credentials for the `/token` endpoint are the `client-id` and |
|
`client-secret`. The user credentials are the normal Spring Security user details (which |
|
default in Spring Boot to "`user`" and a random password). |
|
|
|
To switch off the auto-configuration and configure the Authorization Server features |
|
yourself just add a `@Bean` of type `AuthorizationServerConfigurer`. |
|
|
|
|
|
|
|
[[boot-features-security-oauth2-resource-server]] |
|
==== Resource Server |
|
To use the access token you need a Resource Server (which can be the same as the |
|
Authorization Server). Creating a Resource Server is easy, just add |
|
`@EnableResourceServer` and provide some configuration to allow the server to decode |
|
access tokens. If your application is also an Authorization Server it already knows how |
|
to decode tokens, so there is nothing else to do. If your app is a standalone service then you |
|
need to give it some more configuration, one of the following options: |
|
|
|
* `security.oauth2.resource.user-info-uri` to use the `/me` resource (e.g. |
|
`\https://uaa.run.pivotal.io/userinfo` on PWS) |
|
|
|
* `security.oauth2.resource.token-info-uri` to use the token decoding endpoint (e.g. |
|
`\https://uaa.run.pivotal.io/check_token` on PWS). |
|
|
|
If you specify both the `user-info-uri` and the `token-info-uri` then you can set a flag |
|
to say that one is preferred over the other (`prefer-token-info=true` is the default). |
|
|
|
Alternatively (instead of `user-info-uri` or `token-info-uri`) if the tokens are JWTs you |
|
can configure a `security.oauth2.resource.jwt.key-value` to decode them locally (where the |
|
key is a verification key). The verification key value is either a symmetric secret or |
|
PEM-encoded RSA public key. If you don't have the key and it's public you can provide a |
|
URI where it can be downloaded (as a JSON object with a "`value`" field) with |
|
`security.oauth2.resource.jwt.key-uri`. E.g. on PWS: |
|
|
|
[indent=0] |
|
---- |
|
$ curl https://uaa.run.pivotal.io/token_key |
|
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"} |
|
---- |
|
|
|
WARNING: If you use the `security.oauth2.resource.jwt.key-uri` the authorization server |
|
needs to be running when your application starts up. It will log a warning if it can't |
|
find the key, and tell you what to do to fix it. |
|
|
|
|
|
|
|
[[boot-features-security-oauth2-token-type]] |
|
=== Token Type in User Info |
|
Google, and certain other 3rd party identity providers, are more strict about the token |
|
type name that is sent in the headers to the user info endpoint. The default is "`Bearer`" |
|
which suits most providers and matches the spec, but if you need to change it you can set |
|
`security.oauth2.resource.token-type`. |
|
|
|
|
|
|
|
[[boot-features-security-custom-user-info]] |
|
=== Customizing the User Info RestTemplate |
|
If you have a `user-info-uri`, the resource server features use an `OAuth2RestTemplate` |
|
internally to fetch user details for authentication. This is provided as a qualified |
|
`@Bean` with id `userInfoRestTemplate`, but you shouldn't need to know that to just |
|
use it. The default should be fine for most providers, but occasionally you might need to |
|
add additional interceptors, or change the request authenticator (which is how the token |
|
gets attached to outgoing requests). To add a customization just create a bean of type |
|
`UserInfoRestTemplateCustomizer` - it has a single method that will be called after the |
|
bean is created but before it is initialized. The rest template that is being customized |
|
here is _only_ used internally to carry out authentication. |
|
|
|
[TIP] |
|
==== |
|
To set an RSA key value in YAML use the "`pipe`" continuation marker to split it over |
|
multiple lines ("`|`") and remember to indent the key value (it's a standard YAML |
|
language feature). Example: |
|
|
|
[source,yaml,indent=0] |
|
---- |
|
security: |
|
oauth2: |
|
resource: |
|
jwt: |
|
keyValue: | |
|
-----BEGIN PUBLIC KEY----- |
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC... |
|
-----END PUBLIC KEY----- |
|
---- |
|
==== |
|
|
|
|
|
|
|
[[boot-features-security-custom-user-info-client]] |
|
==== Client |
|
To make your web-app into an OAuth2 client you can simply add `@EnableOAuth2Client` and |
|
Spring Boot will create a `OAuth2ClientContext` and `OAuth2ProtectedResourceDetails` that |
|
are necessary to create an `OAuth2RestOperations`. Spring Boot does not automatically |
|
create such bean but you can easily create your own: |
|
|
|
[source,java,indent=0] |
|
---- |
|
|
|
@Bean |
|
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext, |
|
OAuth2ProtectedResourceDetails details) { |
|
return new OAuth2RestTemplate(details, oauth2ClientContext); |
|
} |
|
---- |
|
|
|
NOTE: You may want to add a qualifier and review your configuration as more than one |
|
`RestTemplate` may be defined in your application. |
|
|
|
This configuration uses `security.oauth2.client.*` as credentials (the same as you might |
|
be using in the Authorization Server), but in addition it will need to know the |
|
authorization and token URIs in the Authorization Server. For example: |
|
|
|
.application.yml |
|
[source,yaml,indent=0] |
|
---- |
|
security: |
|
oauth2: |
|
client: |
|
clientId: bd1c0a783ccdd1c9b9e4 |
|
clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1 |
|
accessTokenUri: https://github.com/login/oauth/access_token |
|
userAuthorizationUri: https://github.com/login/oauth/authorize |
|
clientAuthenticationScheme: form |
|
---- |
|
|
|
An application with this configuration will redirect to Github for authorization when you |
|
attempt to use the `OAuth2RestTemplate`. If you are already signed into Github you won't |
|
even notice that it has authenticated. These specific credentials will only work if your |
|
application is running on port 8080 (register your own client app in Github or other |
|
provider for more flexibility). |
|
|
|
To limit the scope that the client asks for when it obtains an access token you can set |
|
`security.oauth2.client.scope` (comma separated or an array in YAML). By default the scope |
|
is empty and it is up to Authorization Server to decide what the defaults should be, |
|
usually depending on the settings in the client registration that it holds. |
|
|
|
NOTE: There is also a setting for `security.oauth2.client.client-authentication-scheme` |
|
which defaults to "`header`" (but you might need to set it to "`form`" if, like Github for |
|
instance, your OAuth2 provider doesn't like header authentication). In fact, the |
|
`security.oauth2.client.*` properties are bound to an instance of |
|
`AuthorizationCodeResourceDetails` so all its properties can be specified. |
|
|
|
TIP: In a non-web application you can still create an `OAuth2RestOperations` and it |
|
is still wired into the `security.oauth2.client.*` configuration. In this case it is a |
|
"`client credentials token grant`" you will be asking for if you use it (and there is no |
|
need to use `@EnableOAuth2Client` or `@EnableOAuth2Sso`). To prevent that infrastructure |
|
to be defined, just remove the `security.oauth2.client.client-id` from your configuration |
|
(or make it the empty string). |
|
|
|
|
|
|
|
[[boot-features-security-oauth2-single-sign-on]] |
|
==== Single Sign On |
|
An OAuth2 Client can be used to fetch user details from the provider (if such features are |
|
available) and then convert them into an `Authentication` token for Spring Security. |
|
The Resource Server above support this via the `user-info-uri` property This is the basis |
|
for a Single Sign On (SSO) protocol based on OAuth2, and Spring Boot makes it easy to |
|
participate by providing an annotation `@EnableOAuth2Sso`. The Github client above can |
|
protect all its resources and authenticate using the Github `/user/` endpoint, by adding |
|
that annotation and declaring where to find the endpoint (in addition to the |
|
`security.oauth2.client.*` configuration already listed above): |
|
|
|
.application.yml |
|
[source,yaml,indent=0]] |
|
---- |
|
security: |
|
oauth2: |
|
... |
|
resource: |
|
userInfoUri: https://api.github.com/user |
|
preferTokenInfo: false |
|
---- |
|
|
|
Since all paths are secure by default, there is no "`home`" page that you can show to |
|
unauthenticated users and invite them to login (by visiting the `/login` path, or the |
|
path specified by `security.oauth2.sso.login-path`). |
|
|
|
To customize the access rules or paths to protect, so you can add a "`home`" page for |
|
instance, `@EnableOAuth2Sso` can be added to a `WebSecurityConfigurerAdapter` and the |
|
annotation will cause it to be decorated and enhanced with the necessary pieces to get |
|
the `/login` path working. For example, here we simply allow unauthenticated access |
|
to the home page at "/" and keep the default for everything else: |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Configuration |
|
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { |
|
|
|
@Override |
|
public void init(WebSecurity web) { |
|
web.ignore("/"); |
|
} |
|
|
|
@Override |
|
protected void configure(HttpSecurity http) throws Exception { |
|
http.antMatcher("/**").authorizeRequests().anyRequest().authenticated(); |
|
} |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[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 `AuditEvents` and published to the `AuditService`. |
|
* The default user will have the `ADMIN` 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. |
|
|
|
|
|
|
|
[[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. |
|
|
|
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 the Tomcat pooling `DataSource` for its performance and concurrency, so if |
|
that is available we always choose it. |
|
* Otherwise, if HikariCP is available we will use it. |
|
* If neither the Tomcat pooling datasource nor HikariCP are available and if Commons DBCP |
|
is available we will use it, but we don't recommend it in production. |
|
* Lastly, 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 `tomcat-jdbc`. |
|
|
|
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 |
|
---- |
|
|
|
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.tomcat.*+`, |
|
`+spring.datasource.hikari.*+`, `+spring.datasource.dbcp.*+` 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; |
|
} |
|
|
|
// ... |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[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. |
|
|
|
|
|
[NOTE] |
|
==== |
|
By default, Spring Boot uses Hibernate 5.0.x. However it's also possible to use 4.3.x |
|
or 5.2.x if you wish. Please refer to the |
|
{github-code}/spring-boot-samples/spring-boot-sample-hibernate4[Hibernate 4] and |
|
{github-code}/spring-boot-samples/spring-boot-sample-hibernate52[Hibernate 5.2] samples |
|
to see how to do so. |
|
==== |
|
|
|
|
|
[[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-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-sql-h2-console-securing]] |
|
==== Securing the H2 console |
|
When Spring Security is on the classpath and basic auth is enabled, the H2 console will be |
|
automatically secured using basic auth. The following properties can be used to customize |
|
the security configuration: |
|
|
|
* `security.user.role` |
|
* `security.basic.authorize-mode` |
|
* `security.basic.enabled` |
|
|
|
|
|
|
|
[[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); |
|
} |
|
---- |
|
|
|
|
|
|
|
=== Customizing jOOQ |
|
You can customize the SQL dialect used by jOOQ by setting `spring.jooq.sql-dialect` in |
|
your `application.properties`. For example, to specify Postgres you would add: |
|
|
|
[source,properties,indent=0] |
|
---- |
|
spring.jooq.sql-dialect=Postgres |
|
---- |
|
|
|
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-couchbase/[Couchbase] and |
|
http://projects.spring.io/spring-data-cassandra/[Cassandra]. |
|
Spring Boot provides auto-configuration for Redis, MongoDB, Neo4j, Elasticsearch, Solr |
|
and Cassandra; 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/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. |
|
|
|
|
|
|
|
[[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; |
|
} |
|
|
|
// ... |
|
|
|
} |
|
---- |
|
|
|
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` '`Starter`'. |
|
|
|
|
|
|
|
[[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. |
|
|
|
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 |
|
|
|
NOTE: Neo4j's embedded mode is subject to a different licensing, make sure to review it |
|
before integrating the dependency in your application. |
|
|
|
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 |
|
---- |
|
|
|
|
|
|
|
[[boot-features-neo4j-ogm-session]] |
|
==== Neo4jSession |
|
|
|
By default, the lifetime of the session is scope to the application. If you are running a |
|
web application you can change it to scope or request easily: |
|
|
|
---- |
|
spring.data.neo4j.session.scope=session |
|
---- |
|
|
|
|
|
|
|
[[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 `@NodeEntityScan` 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 |
|
---- |
|
|
|
To take full control over the registration, define a `JestClient` bean. |
|
|
|
|
|
|
|
[[boot-features-connecting-to-elasticsearch-spring-data]] |
|
==== Connecting to Elasticsearch using Spring Data |
|
You can inject an auto-configured `ElasticsearchTemplate` or Elasticsearch `Client` |
|
instance as you would any other Spring Bean. By default the instance will embed a |
|
local in-memory server (a `Node` in Elasticsearch terms) and use the current working |
|
directory as the home directory for the server. In this setup, the first thing to do |
|
is to tell Elasticsearch where to store its files: |
|
|
|
[source,properties,indent=0] |
|
---- |
|
spring.data.elasticsearch.properties.path.home=/foo/bar |
|
---- |
|
|
|
Alternatively, you can switch to a remote server (i.e. a `TransportClient`) by setting |
|
`spring.data.elasticsearch.cluster-nodes` to a comma-separated '`host:port`' list. |
|
|
|
[source,properties,indent=0] |
|
---- |
|
spring.data.elasticsearch.cluster-nodes=localhost:9300 |
|
---- |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Component |
|
public class MyBean { |
|
|
|
private ElasticsearchTemplate template; |
|
|
|
@Autowired |
|
public MyBean(ElasticsearchTemplate template) { |
|
this.template = template; |
|
} |
|
|
|
// ... |
|
|
|
} |
|
---- |
|
|
|
If you add a `@Bean` of your own of type `ElasticsearchTemplate` 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). If you want to |
|
bypass the auto-configuration for Spring Data Couchbase, provide your own |
|
`org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration` |
|
implementation. |
|
|
|
|
|
[source,java,indent=0] |
|
---- |
|
@Component |
|
public class MyBean { |
|
|
|
private final CouchbaseTemplate template; |
|
|
|
@Autowired |
|
public MyBean(CouchbaseTemplate template) { |
|
this.template = template; |
|
} |
|
|
|
// ... |
|
|
|
} |
|
---- |
|
|
|
If you add a `@Bean` of your own of type `CouchbaseTemplate` named `couchbaseTemplate` it |
|
will replace the default. |
|
|
|
|
|
|
|
[[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. |
|
|
|
NOTE: Check the {spring-reference}/#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 javax.cache.annotation.CacheResult; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
@Component |
|
public class MathService { |
|
|
|
@CacheResult |
|
public int computePiDecimal(int i) { |
|
// ... |
|
} |
|
|
|
} |
|
---- |
|
|
|
NOTE: You can either use the standard JSR-107 (JCache) annotations or Spring's own |
|
caching annotations transparently. We strongly advise you however to not mix and match |
|
them. |
|
|
|
TIP: It is also possible to {spring-reference}/#cache-annotations-put[update] or |
|
{spring-reference}/#cache-annotations-evict[evict] data from the cache transparently. |
|
|
|
|
|
|
|
=== 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. Spring Boot auto-configures a |
|
suitable `CacheManager` according to the implementation as long as the caching support is |
|
enabled via the `@EnableCaching` annotation. |
|
|
|
NOTE: If you are using the cache infrastructure with beans that are not interface-based, |
|
make sure to enable the `proxyTargetClass` attribute of `@EnableCaching`. |
|
|
|
TIP: Use the `spring-boot-starter-cache` '`Starter`' to quickly add required caching |
|
dependencies. If you are adding dependencies manually you should note that certain |
|
implementations are only provided by the `spring-context-support` jar. |
|
|
|
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)>> |
|
* <<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-guava,Guava>> |
|
* <<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). |
|
|
|
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 the cache names to use. |
|
|
|
[source,java,indent=0] |
|
---- |
|
@Bean |
|
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() { |
|
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() { |
|
@Override |
|
public void customize(ConcurrentMapCacheManager cacheManager) { |
|
cacheManager.setCacheNames(Arrays.asList("one", "two")); |
|
} |
|
}; |
|
} |
|
---- |
|
|
|
[NOTE] |
|
==== |
|
In the example above, a `ConcurrentMapCacheManager` is expected to be configured. If that |
|
is not the case, 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 them is configured. |
|
|
|
|
|
|
|
[[boot-features-caching-provider-jcache]] |
|
==== JCache |
|
JCache is bootstrapped via the presence of a `javax.cache.spi.CachingProvider` on the |
|
classpath (i.e. a JSR-107 compliant caching library). 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. |
|
|
|
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 a `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 and such file is present it is used to bootstrap the cache |
|
manager. An alternate configuration file can be provide a 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`. |
|
|
|
If for some reason you need a different `HazelcastInstance` for caching, you can |
|
request Spring Boot to create a separate one that will be only used by the |
|
`CacheManager`: |
|
|
|
[source,properties,indent=0] |
|
---- |
|
spring.cache.hazelcast.config=classpath:config/my-cache-hazelcast.xml |
|
---- |
|
|
|
TIP: If a separate `HazelcastInstance` is created that way, it is not registered |
|
in the application context. |
|
|
|
|
|
|
|
[[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. |
|
|
|
|
|
|
|
[[boot-features-caching-provider-couchbase]] |
|
==== Couchbase |
|
If Couchbase is available and <<boot-features-couchbase,configured>>, a |
|
`CouchbaseCacheManager` is 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()) |
|
.withExpirationInMillis(2000)); |
|
}; |
|
} |
|
|
|
} |
|
---- |
|
|
|
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 and will supersede the Guava support in |
|
Spring Boot 2.0. If Caffeine is present, a `CaffeineCacheManager` 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`. |
|
|
|
|
|
|
|
[[boot-features-caching-provider-guava]] |
|
==== Guava |
|
If Guava is present, a `GuavaCacheManager` 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.guava.spec` |
|
2. A `com.google.common.cache.CacheBuilderSpec` bean is defined |
|
3. A `com.google.common.cache.CacheBuilder` 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.guava.spec=maximumSize=500,expireAfterAccess=600s |
|
---- |
|
|
|
Besides, if a `com.google.common.cache.CacheLoader` bean is defined, it is automatically |
|
associated to the `GuavaCacheManager`. |
|
|
|
|
|
|
|
[[boot-features-caching-provider-simple]] |
|
==== Simple |
|
If none of these options worked out, a simple implementation using `ConcurrentHashMap` |
|
as cache store is configured. This is the default if no caching library is present in |
|
your application. |
|
|
|
|
|
|
|
[[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. |
|
|
|
|
|
|
|
[[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}/#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 |
|
---- |
|
|
|
See |
|
{sc-spring-boot-autoconfigure}/jms/activemq/ActiveMQProperties.{sc-ext}[`ActiveMQProperties`] |
|
for more of the supported options. |
|
|
|
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 |
|
Apache Artemis was formed in 2015 when HornetQ was donated to the Apache Foundation. All |
|
the features listed in the <<boot-features-hornetq>> section below can be applied to |
|
Artemis. Simply replace `+++spring.hornetq.*+++` properties with `+++spring.artemis.*+++` |
|
and use `spring-boot-starter-artemis` instead of `spring-boot-starter-hornetq`. If you |
|
want to embed Artemis, make sure to add `org.apache.activemq:artemis-jms-server` to the |
|
dependencies of your application. |
|
|
|
NOTE: You should not try and use Artemis and HornetQ and the same time. |
|
|
|
|
|
|
|
[[boot-features-hornetq]] |
|
==== HornetQ support |
|
|
|
NOTE: HornetQ is deprecated in 1.4, consider migrating to <<boot-features-artemis,artemis>> |
|
|
|
Spring Boot can auto-configure a `ConnectionFactory` when it detects that HornetQ 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-hornetq` the necessary dependencies to |
|
connect to an existing HornetQ instance are provided, as well as the Spring infrastructure |
|
to integrate with JMS. Adding `org.hornetq:hornetq-jms-server` to your application allows |
|
you to use the embedded mode. |
|
|
|
HornetQ configuration is controlled by external configuration properties in |
|
`+spring.hornetq.*+`. For example, you might declare the following section in |
|
`application.properties`: |
|
|
|
[source,properties,indent=0] |
|
---- |
|
spring.hornetq.mode=native |
|
spring.hornetq.host=192.168.1.210 |
|
spring.hornetq.port=9876 |
|
spring.hornetq.user=admin |
|
spring.hornetq.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.hornetq.jms.server.config.JMSQueueConfiguration` or |
|
`org.hornetq.jms.server.config.TopicConfiguration`, for advanced queue and topic |
|
configurations respectively. |
|
|
|
See |
|
{sc-spring-boot-autoconfigure}/jms/hornetq/HornetQProperties.{sc-ext}[`HornetQProperties`] |
|
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 HornetQ 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 one is configured automatically. If a `MessageConverter` |
|
beans is defined, it is 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` that you can use to initialize a |
|
`SimpleRabbitListenerContainerFactory` 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 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. |
|
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-restclient]] |
|
== Calling REST services |
|
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 MyBean { |
|
|
|
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-restclient-customization]] |
|
=== RestTemplate customization |
|
When a `RestTemplateBuilder` builds a `RestTemplate` it can be further customized using |
|
a `RestTemplateCustomizer`. Any `RestTemplateCustomizer` beans will be automatically |
|
added to the auto-configured `RestTemplateBuilder`. Furthermore, a new |
|
`RestTemplateBuilder` with additional customizers can be created by calling |
|
`additionalCustomizers(RestTemplateCustomizer...)`. |
|
|
|
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] |
|
---- |
|
|
|
|
|
|
|
[[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}/#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. |
|
|
|
|
|
|
|
[[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, Spring Boot will auto-configure an `HazelcastInstance` |
|
that you can inject in your application. The `HazelcastInstance` is only created if a |
|
configuration is found. |
|
|
|
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. |
|
|
|
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-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. Message processing statistics will be published over JMX |
|
if `'spring-integration-jmx'` is also on the classpath. See the |
|
{sc-spring-boot-autoconfigure}/integration/IntegrationAutoConfiguration.{sc-ext}[`IntegrationAutoConfiguration`] |
|
class for more details. |
|
|
|
|
|
|
|
[[boot-features-session]] |
|
== Spring Session |
|
Spring Boot provides Spring Session auto-configuration for a wide range of stores: |
|
|
|
* JDBC |
|
* MongoDB |
|
* Redis |
|
* Hazelcast |
|
* HashMap |
|
|
|
If Spring Session is available, you only need to 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 |
|
---- |
|
|
|
NOTE: For backward compatibility if Redis is available Spring Session will be automatically |
|
configured to use Redis. |
|
|
|
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}/#integration-testing.html[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[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`. |
|
* `RANDOM_PORT` -- Loads an `EmbeddedWebApplicationContext` and provides a real |
|
servlet environment. Embedded servlet containers are started and listening on a random |
|
port. |
|
* `DEFINED_PORT` -- Loads an `EmbeddedWebApplicationContext` 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: 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 a 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 components or configurations |
|
created only for specific tests accidentally get picked up everywhere. |
|
|
|
To help prevent this, Spring Boot provides `@TestComponent` and `@TestConfiguration` |
|
annotations that can be used on classes in `src/test/java` to indicate that they should |
|
not be picked up by scanning. |
|
|
|
NOTE: `@TestComponent` and `@TestConfiguration` are only needed on top level classes. If |
|
you define `@Configuration` or `@Component` as inner-classes within a test, they will be |
|
automatically filtered. |
|
|
|
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] |
|
---- |
|
import org.junit.*; |
|
import org.junit.runner.*; |
|
import org.springframework.boot.test.context.web.*; |
|
import org.springframework.boot.test.web.client.*; |
|
import org.springframework.test.context.junit4.*; |
|
|
|
import static org.assertj.core.api.Assertions.* |
|
|
|
@RunWith(SpringRunner.class) |
|
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) |
|
public class MyWebIntegrationTests { |
|
|
|
@Autowired |
|
private TestRestTemplate restTemplate; |
|
|
|
@Test |
|
public void exampleTest() { |
|
String body = this.restTemplate.getForObject("/", String.class); |
|
assertThat(body).isEqualTo("Hello World"); |
|
} |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[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. |
|
|
|
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. |
|
|
|
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 Jackson `ObjectMapper`, |
|
any `@JsonComponent` beans and any Jackson `Modules`. It also configures `Gson` |
|
if you happen to be using that instead of, or as well as, Jackson. 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 `JacksonHelper`, `GsonHelper` and |
|
`BasicJsonTester` classes can be used for Jackson, Gson and Strings respectively. Any |
|
helper fields on the test class will be automatically initialized when using `@JsonTest`. |
|
|
|
[source,java,indent=0] |
|
---- |
|
import org.junit.*; |
|
import org.junit.runner.*; |
|
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 { |
|
|
|
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` is meta-annotated with `@AutoConfigureMockMvc` which provides |
|
auto-configuration of `MockMvc`. Mock MVC offers a powerful way to quickly test MVC |
|
controllers without needing to start a full HTTP server. |
|
|
|
[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 a `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"); |
|
} |
|
|
|
} |
|
---- |
|
|
|
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-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}#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. |
|
|
|
[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-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 and GSON 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. It will automatically configure `MockMvc` to use Spring REST Docs and |
|
remove the need for Spring REST Docs' JUnit rule. |
|
|
|
[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("target/generated-snippets") |
|
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")); |
|
} |
|
|
|
} |
|
---- |
|
|
|
In addition to configuring the output directory, `@AutoConfigureRestDocs` can also |
|
configure the host, scheme, and port that will appear in any documented URIs. If you |
|
require more control over Spring REST Docs' configuration 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-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. |
|
|
|
NOTE: The annotations <<boot-features-testing-spring-boot-applications,described above>> |
|
can be used with Spock, i.e. you can annotate your `Specification` with |
|
`@SpringBootTest` to suit the needs of your tests. |
|
|
|
|
|
|
|
[[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) |
|
---- |
|
|
|
|
|
|
|
[[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: not following redirects (so you can assert the response location), |
|
ignoring cookies (so the template is stateless), and 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. |
|
|
|
[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", String.class).getHeaders(); |
|
assertThat(headers.getLocation().toString(), containsString("myotherhost")); |
|
} |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[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}/#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. |
|
|
|
|
|
|
|
[[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-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. |
|
|
|
|
|
|
|
[[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. |
|
|
|
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-define |
|
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}/#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>>.
|
|
|