3712 lines
137 KiB
Plaintext
3712 lines
137 KiB
Plaintext
[[boot-features]]
|
|
= Spring Boot features
|
|
|
|
[partintro]
|
|
--
|
|
This section dives into the details of Spring Boot. Here you can learn about the key
|
|
features that you will want to use and customize. If you haven't already, you might want
|
|
to read the _<<getting-started.adoc#getting-started>>_ and
|
|
_<<using-spring-boot.adoc#using-boot>>_ sections so that you have a good grounding
|
|
of the basics.
|
|
--
|
|
|
|
|
|
|
|
[[boot-features-spring-application]]
|
|
== SpringApplication
|
|
The `SpringApplication` class provides a convenient way to bootstrap a Spring application
|
|
that will be started from a `main()` method. In many situations you can just delegate to
|
|
the static `SpringApplication.run` method:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(MySpringConfiguration.class, args);
|
|
}
|
|
----
|
|
|
|
When your application starts you should see something similar to the following:
|
|
|
|
[indent=0,subs="attributes"]
|
|
----
|
|
. ____ _ __ _ _
|
|
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
|
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
|
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
|
' |____| .__|_| |_|_| |_\__, | / / / /
|
|
=========|_|==============|___/=/_/_/_/
|
|
:: Spring Boot :: v{spring-boot-version}
|
|
|
|
2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
|
|
2013-07-31 00:08:16.166 INFO 56603 --- [ main] 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`).
|
|
|
|
You can use the following variables inside your `banner.txt` file:
|
|
|
|
.Banner variables
|
|
|===
|
|
| Variable | Description
|
|
|
|
|`${application.version}`
|
|
|The version number of your application as declared in `MANIFEST.MF`. For example `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.
|
|
|===
|
|
|
|
TIP: The `SpringBootApplication.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.
|
|
|
|
|
|
|
|
[[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.setShowBanner(false);
|
|
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()
|
|
.showBanner(false)
|
|
.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. Some events are actually
|
|
triggered before the `ApplicationContext` is created.
|
|
|
|
You can register event listeners in a number of ways, the most common being
|
|
`SpringApplication.addListeners(...)` method.
|
|
|
|
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 bound to structured objects.
|
|
|
|
Spring Boot uses a very particular `PropertySource` order that is designed to allow
|
|
sensible overriding of values, properties are considered in the following order:
|
|
|
|
. Command line arguments.
|
|
. 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).
|
|
. `@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;
|
|
|
|
// ...
|
|
|
|
}
|
|
----
|
|
|
|
You can bundle an `application.properties` inside your jar that provides a sensible
|
|
default `name`. When running in production, an `application.properties` can be provided
|
|
outside of your jar that overrides `name`; and for one-off testing, you can launch with
|
|
a specific command line switch (e.g. `java -jar app.jar --name="Spring"`).
|
|
|
|
|
|
|
|
[[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 or strings, e.g.
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
my.secret=${random.value}
|
|
my.number=${random.int}
|
|
my.bignumber=${random.long}
|
|
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` subdir of the current directory.
|
|
. The current directory
|
|
. A classpath `/config` package
|
|
. The classpath root
|
|
|
|
The list is ordered by precedence (locations higher in the list override lower items).
|
|
|
|
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
|
|
----
|
|
|
|
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). The default search path `classpath:,classpath:/config,file:,file:config/`
|
|
is always used, irrespective of the value of `spring.config.location`. 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 profiels 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.
|
|
|
|
|
|
|
|
[[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 '`starter POMs`' 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: 80000
|
|
---
|
|
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: 80000
|
|
security:
|
|
user:
|
|
password: weak
|
|
----
|
|
|
|
|
|
|
|
[[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]]
|
|
=== Typesafe 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.
|
|
|
|
When the `@EnableConfigurationProperties` annotation is applied to your `@Configuration`,
|
|
any beans annotated with `@ConfigurationProperties` will be automatically 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 {
|
|
}
|
|
----
|
|
|
|
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`
|
|
|Upper case format. Recommended when using a system environment variables.
|
|
|===
|
|
|
|
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).
|
|
|
|
|
|
|
|
[[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
|
|
|
|
private 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/[Log4J], 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 '`Starter POMs`', 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. To also log `DEBUG` level
|
|
messages to the console you can start your application with a `--debug` flag.
|
|
|
|
[indent=0]
|
|
----
|
|
$ java -jar myapp.jar --debug
|
|
----
|
|
|
|
NOTE: you can also specify `debug=true` in your `application.properties`.
|
|
|
|
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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
|
|
|
|
[[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. Example `application.properties`:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
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`.
|
|
|
|
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`
|
|
|
|
|Log4j
|
|
|`log4j-spring.properties`, `log4j-spring.xml`, `log4j.properties` or `log4j.xml`
|
|
|
|
|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.file`
|
|
|`LOG_FILE`
|
|
|Used in default log configuration if defined.
|
|
|
|
|`logging.path`
|
|
|`LOG_PATH`
|
|
|Used in default log configuration if defined.
|
|
|
|
|`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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<springProperty scope="context" name="fluentHost" source="myapp.fulentd.host"/>
|
|
<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.
|
|
|
|
If you want to take complete control of Spring MVC, you can add your own `@Configuration`
|
|
annotated with `@EnableWebMvc`. 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`.
|
|
|
|
|
|
|
|
[[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-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 and Velocity. 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-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]
|
|
* 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.
|
|
|
|
If you want more specific error pages for some conditions, the embedded servlet containers
|
|
support a uniform Java DSL for customizing the error handling. For example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public EmbeddedServletContainerCustomizer containerCustomizer(){
|
|
return new MyCustomizer();
|
|
}
|
|
|
|
// ...
|
|
|
|
private static class MyCustomizer implements EmbeddedServletContainerCustomizer {
|
|
|
|
@Override
|
|
public void customize(ConfigurableEmbeddedServletContainer container) {
|
|
container.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
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.
|
|
|
|
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}/org/springframework/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 Celtix 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);
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
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`. 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 packages 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 POM`' to obtain a fully configured
|
|
instance. By default the embedded server will listen for HTTP requests on port `8080`.
|
|
|
|
|
|
|
|
[[boot-features-embedded-container-servlets-and-filters]]
|
|
==== Servlets and Filters
|
|
When using an embedded servlet container you can register Servlets, Filters and all the
|
|
listeners from the Servlet spec (e.g. `HttpSessionListener`) directly as
|
|
Spring beans. 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. You can also register items directly if your bean implements
|
|
the `ServletContextInitializer` interface.
|
|
|
|
|
|
|
|
[[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:
|
|
|
|
* `server.port` -- The listen port for incoming HTTP requests.
|
|
* `server.address` -- The interface address to bind to.
|
|
* `server.session.timeout` -- A session timeout.
|
|
|
|
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 embdedded 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.
|
|
|
|
* Jetty does not currently work as an embedded container with JSPs.
|
|
|
|
* Undertow does not support JSPs.
|
|
|
|
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 Boot default configuration
|
|
completely in a web application you can add a bean with `@EnableWebSecurity`. To customize
|
|
it you normally use external properties and beans of type `WebSecurityConfigurerAdapter`
|
|
(e.g. to add form-based login). 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 (unsecure) paths for common static resource locations (`+/css/**+`, `+/js/**+`,
|
|
`+/images/**+` 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 autoconfigured
|
|
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 appplication 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 webapp into an OAuth2 client you can simply add `@EnableOAuth2Client` and
|
|
Spring Boot will create an `OAuth2RestTemplate` for you to `@Autowire`. It uses the
|
|
`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 `@Autowire` 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 switch it off, 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 unsecure.
|
|
* 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`.
|
|
|
|
|
|
|
|
[[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.
|
|
* If HikariCP is available we will use it.
|
|
* 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`
|
|
'`starter POMs`' you will automatically get a dependency to `tomcat-jdbc`.
|
|
|
|
NOTE: 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
|
|
----
|
|
|
|
See {sc-spring-boot-autoconfigure}/jdbc/DataSourceProperties.{sc-ext}[`DataSourceProperties`]
|
|
for more of the supported options. Note also that you can configure any of the
|
|
`DataSource` implementation specific properties via `+spring.datasource.*+`: refer to the
|
|
documentation of the connection pool implementation you are using for more details.
|
|
|
|
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.driverClassName=com.mysql.jdbc.Driver` then that class has to be
|
|
loadable.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
|
|
|
|
[[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-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 oder 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, Elasticsearch, and Solr; 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-redis` '`Starter POM`' 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 POM`'.
|
|
|
|
|
|
|
|
[[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`, or alternatively
|
|
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
|
|
----
|
|
|
|
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-gemfire]]
|
|
=== Gemfire
|
|
https://github.com/spring-projects/spring-data-gemfire[Spring Data Gemfire] provides
|
|
convenient Spring-friendly tools for accessing the
|
|
http://www.gopivotal.com/big-data/pivotal-gemfire#details[Pivotal Gemfire] data management
|
|
platform. There is a `spring-boot-starter-data-gemfire` '`Starter POM`' 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 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 POM`' for collecting the dependencies in a
|
|
convenient way.
|
|
|
|
|
|
|
|
[[boot-features-connecting-to-solr]]
|
|
==== Connecting to Solr
|
|
You can inject an auto-configured `SolrServer` 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 SolrServer solr;
|
|
|
|
@Autowired
|
|
public MyBean(SolrServer solr) {
|
|
this.solr = solr;
|
|
}
|
|
|
|
// ...
|
|
|
|
}
|
|
----
|
|
|
|
If you add a `@Bean` of your own of type `SolrServer` 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 POM`' for collecting the
|
|
dependencies in a convenient way.
|
|
|
|
|
|
|
|
[[boot-features-connecting-to-elasticsearch]]
|
|
==== Connecting to Elasticsearch
|
|
You can inject an auto-configured `ElasticsearchTemplate` or Elasticsearch `Client`
|
|
instance as you would any other Spring Bean. By default the instance will attempt to
|
|
connect to a local in-memory server (a `NodeClient` in Elasticsearch terms), but 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,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-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.
|
|
|
|
TIP: Use the `spring-boot-starter-cache` "`Starter POM`" 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.
|
|
|
|
Spring Boot tries to detect the following providers (in this order):
|
|
|
|
* <<boot-features-caching-provider-generic,Generic>>
|
|
* <<boot-features-caching-provider-ehcache2,EhCache 2.x>>
|
|
* <<boot-features-caching-provider-hazelcast,Hazelcast>>
|
|
* <<boot-features-caching-provider-infinispan,Infinispan>>
|
|
* <<boot-features-caching-provider-jcache,JCache (JSR-107)>>
|
|
* <<boot-features-caching-provider-redis,Redis>>
|
|
* <<boot-features-caching-provider-guava,Guava>>
|
|
* <<boot-features-caching-provider-simple,Simple>>
|
|
|
|
It is also possible to _force_ the cache provider to use via the `spring.cache.type`
|
|
property.
|
|
|
|
|
|
|
|
[[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-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
|
|
Hazelcast is used if a `hazelcast.xml` file can be found in the current working
|
|
directory, at the root of the classpath or a location specified via the `hazelcast.config`
|
|
system property. Spring Boot detects all of these and also allows for explicit location
|
|
using:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
spring.cache.hazelcast.config=classpath:config/my-hazelcast.xml
|
|
----
|
|
|
|
|
|
|
|
[[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-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 than more that 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
|
|
it is advised to set the `spring.cache.type` to `jcache` to force that mode if that's
|
|
what you want.
|
|
|
|
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-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.
|
|
|
|
|
|
|
|
[[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-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).
|
|
|
|
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`.
|
|
|
|
NOTE: You should not try and use Artemis and HornetQ and the same time.
|
|
|
|
|
|
|
|
[[boot-features-hornetq]]
|
|
==== HornetQ support
|
|
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
|
|
----
|
|
|
|
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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
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.
|
|
|
|
|
|
|
|
[[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.
|
|
|
|
|
|
|
|
=== 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 POM 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.` 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.
|
|
|
|
|
|
|
|
=== Using a Bitronix transaction manager
|
|
Bitronix is another popular open source JTA transaction manager implementation. You can
|
|
use the `spring-boot-starter-jta-bitronix` starter POM to add the appropriate Birtronix
|
|
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.`
|
|
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.
|
|
|
|
|
|
|
|
=== 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`.
|
|
|
|
|
|
|
|
=== 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;
|
|
----
|
|
|
|
|
|
|
|
=== 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/BitronixXAConnectionFactoryWrapper.{sc-ext}[BitronixXAConnectionFactoryWrapper]
|
|
and {sc-spring-boot}/jta/BitronixXADataSourceWrapper.{sc-ext}[BitronixXADataSourceWrapper]
|
|
provide good examples of how to write XA wrappers.
|
|
|
|
|
|
|
|
[[boot-features-integration]]
|
|
== Spring Integration
|
|
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 Session provides support for managing a user's session information. If you are
|
|
writing a web application and Spring Session and Spring Data Redis are both on the
|
|
classpath, Spring Boot will auto-configure Spring Session through its
|
|
`@EnableRedisHttpSession`. Session data will be stored in Redis and the session timeout
|
|
can be configured using the `server.session-timeout` property.
|
|
|
|
|
|
|
|
[[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 useful tools for testing your application. The
|
|
`spring-boot-starter-test` POM provides Spring Test, JUnit, Hamcrest and Mockito
|
|
dependencies. There are also useful test utilities in the core `spring-boot` module under
|
|
the `org.springframework.boot.test` package.
|
|
|
|
|
|
|
|
[[boot-features-test-scope-dependencies]]
|
|
=== Test scope dependencies
|
|
If you use the
|
|
`spring-boot-starter-test` '`Starter POM`' (in the `test` `scope`), you will find
|
|
the following provided libraries:
|
|
|
|
* Spring Test -- integration test support for Spring applications.
|
|
* JUnit -- The de-facto standard for unit testing Java applications.
|
|
* Hamcrest -- A library of matcher objects (also known as constraints or predicates)
|
|
allowing `assertThat` style JUnit assertions.
|
|
* Mockito -- A Java mocking framework.
|
|
|
|
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 POM`' 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 `@SpringApplicationConfiguration` annotation as an alternative
|
|
to the standard `spring-test` `@ContextConfiguration` annotation. If you use
|
|
`@SpringApplicationConfiguration` to configure the `ApplicationContext` used in your
|
|
tests, it will be created via `SpringApplication` and you will get the additional Spring
|
|
Boot features.
|
|
|
|
For example:
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
|
|
public class CityRepositoryIntegrationTests {
|
|
|
|
@Autowired
|
|
CityRepository repository;
|
|
|
|
// ...
|
|
|
|
}
|
|
----
|
|
|
|
TIP: The context loader guesses whether you want to test a web application or not (e.g.
|
|
with `MockMVC`) by looking for the `@WebIntegrationTest` or `@WebAppConfiguration`
|
|
annotations. (`MockMVC` and `@WebAppConfiguration` are part of `spring-test`).
|
|
|
|
If you want a web application to start up and listen on its normal port, so you can test
|
|
it with HTTP (e.g. using `RestTemplate`), annotate your test class (or one of its
|
|
superclasses) with `@WebIntegrationTest`. This can be very useful because it means you can
|
|
test the full stack of your application, but also inject its components into the test
|
|
class and use them to assert the internal state of the application after an HTTP
|
|
interaction. For example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
|
|
@WebIntegrationTest
|
|
public class CityRepositoryIntegrationTests {
|
|
|
|
@Autowired
|
|
CityRepository repository;
|
|
|
|
RestTemplate restTemplate = new TestRestTemplate();
|
|
|
|
// ... interact with the running server
|
|
|
|
}
|
|
----
|
|
|
|
NOTE: Spring's test framework will cache application contexts between tests. Therefore,
|
|
as long as your tests share the same configuration, the time consuming process of starting
|
|
and stopping the server will only happen once, regardless of the number of tests that
|
|
actually run.
|
|
|
|
To change the port you can add environment properties to `@WebIntegrationTest` as colon-
|
|
or equals-separated name-value pairs, e.g. `@WebIntegrationTest("server.port:9000")`.
|
|
Additionally you can set the `server.port` and `management.port` properties to `0`
|
|
in order to run your integration tests using random ports. For example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
@SpringApplicationConfiguration(classes = MyApplication.class)
|
|
@WebIntegrationTest({"server.port=0", "management.port=0"})
|
|
public class SomeIntegrationTests {
|
|
|
|
// ...
|
|
|
|
}
|
|
----
|
|
|
|
See <<howto-discover-the-http-port-at-runtime>> for a description of how you can discover
|
|
the actual port that was allocated for the duration of the tests.
|
|
|
|
|
|
|
|
[[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
|
|
`@WebIntegrationTest` 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 `@SpringApplicationConfiguration`.
|
|
|
|
[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.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 subclass of 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 {
|
|
|
|
RestTemplate 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-developing-auto-configuration]]
|
|
== Developing auto-configuration and using conditions
|
|
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.
|
|
|
|
|
|
|
|
[[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 `spring-boot-autoconfigure` to see the `@Configuration`
|
|
classes that we provide (see the `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`.
|
|
|
|
|
|
|
|
[[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 configurations
|
|
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.
|
|
|
|
NOTE: `@Conditional` annotations are processed when `@Configuration` classes are parsed.
|
|
Auto-configured `@Configuration` is always parsed last (after any user defined beans),
|
|
however, if you are using these annotations on regular `@Configuration` classes, care must
|
|
be taken not to refer to bean definitions that have not yet been created.
|
|
|
|
|
|
|
|
[[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-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-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.aoc#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>>.
|