3212 lines
129 KiB
Plaintext
3212 lines
129 KiB
Plaintext
[[howto]]
|
|
= '`How-to`' guides
|
|
|
|
[partintro]
|
|
--
|
|
This section provides answers to some common '`how do I do that...`' questions
|
|
that often arise when using Spring Boot. Its coverage is not exhaustive, but it
|
|
does cover quite a lot.
|
|
|
|
If you have a specific problem that we do not cover here, you might want to check out
|
|
https://stackoverflow.com/tags/spring-boot[stackoverflow.com] to see if someone has
|
|
already provided an answer. This is also a great place to ask new questions (please use
|
|
the `spring-boot` tag).
|
|
|
|
We are also more than happy to extend this section. If you want to add a '`how-to`',
|
|
send us a {github-code}[pull request].
|
|
--
|
|
|
|
|
|
|
|
[[howto-spring-boot-application]]
|
|
== Spring Boot Application
|
|
|
|
This section includes topics relating directly to Spring Boot applications.
|
|
|
|
|
|
|
|
[[howto-failure-analyzer]]
|
|
=== Create Your Own FailureAnalyzer
|
|
{dc-spring-boot}/diagnostics/FailureAnalyzer.{dc-ext}[`FailureAnalyzer`] is a great way
|
|
to intercept an exception on startup and turn it into a human-readable message, wrapped
|
|
in a {dc-spring-boot}/diagnostics/FailureAnalysis.{dc-ext}[`FailureAnalysis`]. Spring
|
|
Boot provides such an analyzer for application-context-related exceptions, JSR-303
|
|
validations, and more. You can also create your own.
|
|
|
|
`AbstractFailureAnalyzer` is a convenient extension of `FailureAnalyzer` that checks the
|
|
presence of a specified exception type in the exception to handle. You can extend from
|
|
that so that your implementation gets a chance to handle the exception only when it is
|
|
actually present. If, for whatever reason, you cannot handle the exception, return `null`
|
|
to give another implementation a chance to handle the exception.
|
|
|
|
`FailureAnalyzer` implementations must be registered in `META-INF/spring.factories`.
|
|
The following example registers `ProjectConstraintViolationFailureAnalyzer`:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
|
com.example.ProjectConstraintViolationFailureAnalyzer
|
|
----
|
|
|
|
NOTE: If you need access to the `BeanFactory` or the `Environment`, your `FailureAnalyzer`
|
|
can simply implement `BeanFactoryAware` or `EnvironmentAware` respectively.
|
|
|
|
|
|
|
|
[[howto-troubleshoot-auto-configuration]]
|
|
=== Troubleshoot Auto-configuration
|
|
The Spring Boot auto-configuration tries its best to "`do the right thing`", but
|
|
sometimes things fail, and it can be hard to tell why.
|
|
|
|
There is a really useful `ConditionEvaluationReport` available in any Spring Boot
|
|
`ApplicationContext`. You can see it if you enable `DEBUG` logging output. If you use
|
|
the `spring-boot-actuator` (see <<production-ready-features.adoc,the Actuator chapter>>),
|
|
there is also a `conditions` endpoint that renders the report in JSON. Use that endpoint
|
|
to debug the application and see what features have been added (and which have not been
|
|
added) by Spring Boot at runtime.
|
|
|
|
Many more questions can be answered by looking at the source code and the Javadoc. When
|
|
reading the code, remember the following rules of thumb:
|
|
|
|
* Look for classes called `+*AutoConfiguration+` and read their sources. Pay special
|
|
attention to the `+@Conditional*+` annotations to find out what features they enable and
|
|
when. Add `--debug` to the command line or a System property `-Ddebug` to get a log on the
|
|
console of all the auto-configuration decisions that were made in your app. In a running
|
|
Actuator app, look at the `conditions` endpoint (`/actuator/conditions` or the JMX
|
|
equivalent) for the same information.
|
|
* Look for classes that are `@ConfigurationProperties` (such as
|
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`])
|
|
and read from there the available external configuration options. The
|
|
`@ConfigurationProperties` annotation has a `name` attribute that acts as a prefix to
|
|
external properties. Thus, `ServerProperties` has `prefix="server"` and its configuration
|
|
properties are `server.port`, `server.address`, and others. In a running Actuator app,
|
|
look at the `configprops` endpoint.
|
|
* Look for uses of the `bind` method on the `Binder` to pull configuration values
|
|
explicitly out of the `Environment` in a relaxed manner. It is often used with a prefix.
|
|
* Look for `@Value` annotations that bind directly to the `Environment`.
|
|
* Look for `@ConditionalOnExpression` annotations that switch features on and off in
|
|
response to SpEL expressions, normally evaluated with placeholders resolved from the
|
|
`Environment`.
|
|
|
|
|
|
|
|
[[howto-customize-the-environment-or-application-context]]
|
|
=== Customize the Environment or ApplicationContext Before It Starts
|
|
A `SpringApplication` has `ApplicationListeners` and `ApplicationContextInitializers` that
|
|
are used to apply customizations to the context or environment. Spring Boot loads a number
|
|
of such customizations for use internally from `META-INF/spring.factories`. There is more
|
|
than one way to register additional customizations:
|
|
|
|
* Programmatically, per application, by calling the `addListeners` and `addInitializers`
|
|
methods on `SpringApplication` before you run it.
|
|
* Declaratively, per application, by setting the `context.initializer.classes` or
|
|
`context.listener.classes` properties.
|
|
* Declaratively, for all applications, by adding a `META-INF/spring.factories` and packaging
|
|
a jar file that the applications all use as a library.
|
|
|
|
The `SpringApplication` sends some special `ApplicationEvents` to the listeners (some
|
|
even before the context is created) and then registers the listeners for events published
|
|
by the `ApplicationContext` as well. See
|
|
"`<<spring-boot-features.adoc#boot-features-application-events-and-listeners>>`" in the
|
|
'`Spring Boot features`' section for a complete list.
|
|
|
|
It is also possible to customize the `Environment` before the application context is
|
|
refreshed by using `EnvironmentPostProcessor`. Each implementation should be registered in
|
|
`META-INF/spring.factories`, as shown in the following example:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
|
|
----
|
|
|
|
The implementation can load arbitrary files and add them to the `Environment`. For
|
|
instance, the following example loads a YAML configuration file from the classpath:
|
|
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/context/EnvironmentPostProcessorExample.java[tag=example]
|
|
----
|
|
|
|
TIP: The `Environment` has already been prepared with all the usual property sources
|
|
that Spring Boot loads by default. It is therefore possible to get the location of the
|
|
file from the environment. The preceding example adds the `custom-resource` property
|
|
source at the end of the list so that a key defined in any of the usual other locations
|
|
takes precedence. A custom implementation may define another order.
|
|
|
|
CAUTION: While using `@PropertySource` on your `@SpringBootApplication` may seem to be a
|
|
convenient and easy way to load a custom resource in the `Environment`, we do not
|
|
recommend it, because Spring Boot prepares the `Environment` before the
|
|
`ApplicationContext` is refreshed. Any key defined with `@PropertySource` is loaded too
|
|
late to have any effect on auto-configuration.
|
|
|
|
|
|
|
|
[[howto-build-an-application-context-hierarchy]]
|
|
=== Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)
|
|
You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext`
|
|
hierarchies. See "`<<spring-boot-features.adoc#boot-features-fluent-builder-api>>`"
|
|
in the '`Spring Boot features`' section for more information.
|
|
|
|
|
|
|
|
[[howto-create-a-non-web-application]]
|
|
=== Create a Non-web Application
|
|
Not all Spring applications have to be web applications (or web services). If you want to
|
|
execute some code in a `main` method but also bootstrap a Spring application to set up
|
|
the infrastructure to use, you can use the `SpringApplication` features of Spring
|
|
Boot. A `SpringApplication` changes its `ApplicationContext` class, depending on whether it
|
|
thinks it needs a web application or not. The first thing you can do to help it is to
|
|
leave the servlet API dependencies off the classpath. If you cannot do that (for example, you
|
|
run two applications from the same code base) then you can explicitly call
|
|
`setWebEnvironment(false)` on your `SpringApplication` instance or set the
|
|
`applicationContextClass` property (through the Java API or with external properties).
|
|
Application code that you want to run as your business logic can be implemented as a
|
|
`CommandLineRunner` and dropped into the context as a `@Bean` definition.
|
|
|
|
|
|
|
|
[[howto-properties-and-configuration]]
|
|
== Properties and Configuration
|
|
|
|
This section includes topics about setting and reading properties and configuration
|
|
settings and their interaction with Spring Boot applications.
|
|
|
|
[[howto-automatic-expansion]]
|
|
=== Automatically Expand Properties at Build Time
|
|
Rather than hardcoding some properties that are also specified in your project's build
|
|
configuration, you can automatically expand them by instead using the existing build
|
|
configuration. This is possible in both Maven and Gradle.
|
|
|
|
|
|
|
|
[[howto-automatic-expansion-maven]]
|
|
==== Automatic Property Expansion Using Maven
|
|
You can automatically expand properties from the Maven project by using resource
|
|
filtering. If you use the `spring-boot-starter-parent`, you can then refer to your
|
|
Maven '`project properties`' with `@..@` placeholders, as shown in the following example:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.encoding=@project.build.sourceEncoding@
|
|
app.java.version=@java.version@
|
|
----
|
|
|
|
NOTE: Only production configuration is filtered that way (in other words, no filtering is
|
|
applied on `src/test/resources`).
|
|
|
|
TIP: If you enable the `addResources` flag, the `spring-boot:run` goal can add
|
|
`src/main/resources` directly to the classpath (for hot reloading purposes). Doing so
|
|
circumvents the resource filtering and this feature. Instead, you can use the `exec:java`
|
|
goal or customize the plugin's configuration. See the
|
|
{spring-boot-maven-plugin-site}/usage.html[plugin usage page] for more details.
|
|
|
|
If you do not use the starter parent, you need to include the following element inside
|
|
the `<build/>` element of your `pom.xml`:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<resources>
|
|
<resource>
|
|
<directory>src/main/resources</directory>
|
|
<filtering>true</filtering>
|
|
</resource>
|
|
</resources>
|
|
----
|
|
|
|
You also need to include the following element inside `<plugins/>`:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<plugin>
|
|
<groupId>org.apache.maven.plugins</groupId>
|
|
<artifactId>maven-resources-plugin</artifactId>
|
|
<version>2.7</version>
|
|
<configuration>
|
|
<delimiters>
|
|
<delimiter>@</delimiter>
|
|
</delimiters>
|
|
<useDefaultDelimiters>false</useDefaultDelimiters>
|
|
</configuration>
|
|
</plugin>
|
|
----
|
|
|
|
NOTE: The `useDefaultDelimiters` property is important if you use standard Spring
|
|
placeholders (such as `${placeholder}`) in your configuration. If that property is not
|
|
set to `false`, these may be expanded by the build.
|
|
|
|
|
|
|
|
[[howto-automatic-expansion-gradle]]
|
|
==== Automatic Property Expansion Using Gradle
|
|
You can automatically expand properties from the Gradle project by configuring the
|
|
Java plugin's `processResources` task to do so, as shown in the following example:
|
|
|
|
[source,groovy,indent=0]
|
|
----
|
|
processResources {
|
|
expand(project.properties)
|
|
}
|
|
----
|
|
|
|
You can then refer to your Gradle project's properties by using placeholders, as shown in the
|
|
following example:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.name=${name}
|
|
app.description=${description}
|
|
----
|
|
|
|
NOTE: Gradle's `expand` method uses Groovy's `SimpleTemplateEngine`, which transforms
|
|
`${..}` tokens. The `${..}` style conflicts with Spring's own property placeholder
|
|
mechanism. To use Spring property placeholders together with automatic expansion, escape
|
|
the Spring property placeholders as follows: `\${..}`.
|
|
|
|
|
|
|
|
|
|
[[howto-externalize-configuration]]
|
|
=== Externalize the Configuration of `SpringApplication`
|
|
A `SpringApplication` has bean properties (mainly setters), so you can use its Java API as
|
|
you create the application to modify its behavior. Alternatively, you can externalize the
|
|
configuration by setting properties in `+spring.main.*+`. For example, in
|
|
`application.properties`, you might have the following settings:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.main.web-environment=false
|
|
spring.main.banner-mode=off
|
|
----
|
|
|
|
Then the Spring Boot banner is not printed on startup, and the application is
|
|
not a web application.
|
|
|
|
NOTE: The preceding example also demonstrates how flexible binding allows the use of
|
|
underscores (`_`) as well as dashes (`-`) in property names.
|
|
|
|
Properties defined in external configuration override the values specified with the Java
|
|
API, with the notable exception of the sources used to create the `ApplicationContext`.
|
|
Consider the following application:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
new SpringApplicationBuilder()
|
|
.bannerMode(Banner.Mode.OFF)
|
|
.sources(demo.MyApp.class)
|
|
.run(args);
|
|
----
|
|
|
|
Now consider the following configuration:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.main.sources=com.acme.Config,com.acme.ExtraConfig
|
|
spring.main.banner-mode=console
|
|
----
|
|
|
|
The actual application _now_ shows the banner (as overridden by configuration) and uses
|
|
three sources for the `ApplicationContext` (in the following order): `demo.MyApp`,
|
|
`com.acme.Config`, and `com.acme.ExtraConfig`.
|
|
|
|
|
|
|
|
[[howto-change-the-location-of-external-properties]]
|
|
=== Change the Location of External Properties of an Application
|
|
By default, properties from different sources are added to the Spring `Environment` in a
|
|
defined order (see "`<<spring-boot-features.adoc#boot-features-external-config>>`" in
|
|
the '`Spring Boot features`' section for the exact order).
|
|
|
|
A nice way to augment and modify this ordering is to add `@PropertySource` annotations to your
|
|
application sources. Classes passed to the `SpringApplication` static convenience
|
|
methods and those added using `setSources()` are inspected to see if they have
|
|
`@PropertySources`. If they do, those properties are added to the `Environment` early
|
|
enough to be used in all phases of the `ApplicationContext` lifecycle. Properties added
|
|
in this way have lower priority than any added by using the default locations (such as
|
|
`application.properties`), system properties, environment variables, or the command line.
|
|
|
|
You can also provide the following System properties (or environment variables) to change
|
|
the behavior:
|
|
|
|
* `spring.config.name` (`SPRING_CONFIG_NAME`): Defaults to `application` as the root of
|
|
the file name.
|
|
* `spring.config.location` (`SPRING_CONFIG_LOCATION`): The file to load (such as a
|
|
classpath resource or a URL). A separate `Environment` property source is set up for this
|
|
document and it can be overridden by system properties, environment variables, or the
|
|
command line.
|
|
|
|
No matter what you set in the environment, Spring Boot always loads
|
|
`application.properties` as described above. By default, if YAML is used, then files with
|
|
the '`.yml`' extension are also added to the list.
|
|
|
|
Spring Boot logs the configuration files that are loaded at the `DEBUG` level and the
|
|
candidates it has not found at `TRACE` level.
|
|
|
|
See {sc-spring-boot}/context/config/ConfigFileApplicationListener.{sc-ext}[`ConfigFileApplicationListener`]
|
|
for more detail.
|
|
|
|
|
|
|
|
[[howto-use-short-command-line-arguments]]
|
|
=== Use '`Short`' Command Line Arguments
|
|
Some people like to use (for example) `--port=9000` instead of `--server.port=9000` to
|
|
set configuration properties on the command line. You can enable this behavior by using
|
|
placeholders in `application.properties`, as shown in the following example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.port=${port:8080}
|
|
----
|
|
|
|
TIP: If you inherit from the `spring-boot-starter-parent` POM, the default filter
|
|
token of the `maven-resources-plugins` has been changed from `+${*}+` to `@` (that is,
|
|
`@maven.token@` instead of `${maven.token}`) to prevent conflicts with Spring-style
|
|
placeholders. If you have enabled Maven filtering for the `application.properties`
|
|
directly, you may want to also change the default filter token to use
|
|
https://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#delimiters[other
|
|
delimiters].
|
|
|
|
NOTE: In this specific case, the port binding works in a PaaS environment such as Heroku
|
|
or Cloud Foundry. In those two platforms, the `PORT` environment variable is set
|
|
automatically and Spring can bind to capitalized synonyms for `Environment` properties.
|
|
|
|
|
|
|
|
[[howto-use-yaml-for-external-properties]]
|
|
=== Use YAML for External Properties
|
|
YAML is a superset of JSON and, as such, is a convenient syntax for storing external
|
|
properties in a hierarchical format, as shown in the following example:
|
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring:
|
|
application:
|
|
name: cruncher
|
|
datasource:
|
|
driverClassName: com.mysql.jdbc.Driver
|
|
url: jdbc:mysql://localhost/test
|
|
server:
|
|
port: 9000
|
|
----
|
|
|
|
Create a file called `application.yml` and put it in the root of your classpath.
|
|
Then add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already
|
|
included if you use the `spring-boot-starter`). A YAML file is parsed to a Java
|
|
`Map<String,Object>` (like a JSON object), and Spring Boot flattens the map so that it
|
|
is one level deep and has period-separated keys, as many people are used to with
|
|
`Properties` files in Java.
|
|
|
|
The preceding example YAML corresponds to the following `application.properties` file:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.application.name=cruncher
|
|
spring.datasource.driverClassName=com.mysql.jdbc.Driver
|
|
spring.datasource.url=jdbc:mysql://localhost/test
|
|
server.port=9000
|
|
----
|
|
|
|
See "`<<spring-boot-features.adoc#boot-features-external-config-yaml>>`" in
|
|
the '`Spring Boot features`' section for more information
|
|
about YAML.
|
|
|
|
[[howto-set-active-spring-profiles]]
|
|
=== Set the Active Spring Profiles
|
|
The Spring `Environment` has an API for this, but you would normally set a System property
|
|
(`spring.profiles.active`) or an OS environment variable (`SPRING_PROFILES_ACTIVE`).
|
|
Also, you can launch your application with a `-D` argument (remember to put it before the
|
|
main class or jar archive), as follows:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
|
|
----
|
|
|
|
In Spring Boot, you can also set the active profile in `application.properties`, as shown
|
|
in the following example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.profiles.active=production
|
|
----
|
|
|
|
A value set this way is replaced by the System property or environment variable setting
|
|
but not by the `SpringApplicationBuilder.profiles()` method. Thus, the latter Java API can
|
|
be used to augment the profiles without changing the defaults.
|
|
|
|
See "`<<spring-boot-features.adoc#boot-features-profiles>>`" in
|
|
the "`Spring Boot features`" section for more information.
|
|
|
|
|
|
|
|
[[howto-change-configuration-depending-on-the-environment]]
|
|
=== Change Configuration Depending on the Environment
|
|
A YAML file is actually a sequence of documents separated by `---` lines, and each
|
|
document is parsed separately to a flattened map.
|
|
|
|
If a YAML document contains a `spring.profiles` key, then the profiles value
|
|
(a comma-separated list of profiles) is fed into the Spring
|
|
`Environment.acceptsProfiles()` method. If any of those profiles is active, that document
|
|
is included in the final merge (otherwise, it is not), as shown in the following example:
|
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server:
|
|
port: 9000
|
|
---
|
|
|
|
spring:
|
|
profiles: development
|
|
server:
|
|
port: 9001
|
|
|
|
---
|
|
|
|
spring:
|
|
profiles: production
|
|
server:
|
|
port: 0
|
|
----
|
|
|
|
In the preceding example, the default port is 9000. However, if the Spring profile called
|
|
'`development`' is active, then the port is 9001. If '`production`' is active, then the
|
|
port is 0.
|
|
|
|
NOTE: The YAML documents are merged in the order in which they are encountered. Later
|
|
values override earlier values.
|
|
|
|
To do the same thing with properties files, you can use
|
|
`application-${profile}.properties` to specify profile-specific values.
|
|
|
|
|
|
|
|
[[howto-discover-build-in-options-for-external-properties]]
|
|
=== Discover Built-in Options for External Properties
|
|
Spring Boot binds external properties from `application.properties` (or `.yml` files and
|
|
other places) into an application at runtime. There is not (and technically cannot be) an
|
|
exhaustive list of all supported properties in a single location, because contributions
|
|
can come from additional jar files on your classpath.
|
|
|
|
A running application with the Actuator features has a `configprops` endpoint that shows
|
|
all the bound and bindable properties available through `@ConfigurationProperties`.
|
|
|
|
The appendix includes an <<appendix-application-properties#common-application-properties,
|
|
`application.properties`>> example with a list of the most common properties supported by
|
|
Spring Boot. The definitive list comes from searching the source code for
|
|
`@ConfigurationProperties` and `@Value` annotations as well as the occasional use of
|
|
`Binder`. For more about the exact ordering of loading properties, see
|
|
"<<spring-boot-features#boot-features-external-config>>".
|
|
|
|
|
|
|
|
[[howto-embedded-web-servers]]
|
|
== Embedded Web Servers
|
|
|
|
Each Spring Boot web application includes an embedded web server. This feature leads to a
|
|
number of how-to questions, including how to change the embedded server and how to
|
|
configure the embedded server. This section answers those questions.
|
|
|
|
[[howto-use-another-web-server]]
|
|
=== Use Another Web Server
|
|
Many Spring Boot starters include default embedded containers. `spring-boot-starter-web`
|
|
includes Tomcat by including `spring-boot-starter-tomcat`, but you can use
|
|
`spring-boot-starter-jetty` or `spring-boot-starter-undertow` instead.
|
|
`spring-boot-starter-webflux` includes Reactor Netty by including
|
|
`spring-boot-starter-reactor-netty`, but you can use `spring-boot-starter-tomcat`,
|
|
`spring-boot-starter-jetty`, or `spring-boot-starter-undertow` instead.
|
|
|
|
NOTE: Many starters support only Spring MVC, so they transitively bring
|
|
`spring-boot-starter-web` into your application classpath.
|
|
|
|
If you need to use a different HTTP server, you need to exclude the default dependencies
|
|
and include the one you need. Spring Boot provides separate starters for
|
|
HTTP servers to help make this process as easy as possible.
|
|
|
|
The following Maven example shows how to exclude Tomcat and include Jetty for Spring MVC:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
<exclusions>
|
|
<!-- Exclude the Tomcat dependency -->
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<!-- Use Jetty instead -->
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
The following Gradle example shows how to exclude Netty and include Undertow for Spring
|
|
WebFlux:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
configurations {
|
|
// exclude Reactor Netty
|
|
compile.exclude module: 'spring-boot-starter-reactor-netty'
|
|
}
|
|
|
|
dependencies {
|
|
compile 'org.springframework.boot:spring-boot-starter-webflux'
|
|
// Use Undertow instead
|
|
compile 'org.springframework.boot:spring-boot-starter-undertow'
|
|
// ...
|
|
}
|
|
----
|
|
|
|
NOTE: `spring-boot-starter-reactor-netty` is required to use the `WebClient` class, so
|
|
you may need to keep a dependency on Netty even when you need to include a different HTTP
|
|
server.
|
|
|
|
|
|
|
|
[[howto-configure-jetty]]
|
|
=== Configure Jetty
|
|
Generally, you can follow the advice from
|
|
"`<<howto-discover-build-in-options-for-external-properties>>`" about
|
|
`@ConfigurationProperties` (`ServerProperties` is the main one here). However, you should
|
|
also look at
|
|
{dc-spring-boot}/web/server/WebServerFactoryCustomizer.html[`WebServerFactoryCustomizer`].
|
|
The Jetty APIs are quite rich, so, once you have access to the
|
|
`JettyServletWebServerFactory`, you can modify it in a number of ways. Alternatively, if
|
|
you need more control and customization, you can add your own
|
|
`JettyServletWebServerFactory`.
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener]]
|
|
=== Add a Servlet, Filter, or Listener to an Application
|
|
There are two ways to add `Servlet`, `Filter`, `ServletContextListener`, and the other
|
|
listeners supported by the Servlet spec to your application:
|
|
|
|
* <<howto-add-a-servlet-filter-or-listener-as-spring-bean>>
|
|
* <<howto-add-a-servlet-filter-or-listener-using-scanning>>
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener-as-spring-bean]]
|
|
==== Add a Servlet, Filter, or Listener by Using a Spring Bean
|
|
To add a `Servlet`, `Filter`, or Servlet `*Listener` by using a Spring bean, you must
|
|
provide a `@Bean` definition for it. Doing so can be very useful when you want to inject
|
|
configuration or dependencies. However, you must be very careful that they do not cause
|
|
eager initialization of too many other beans, because they have to be installed in the
|
|
container very early in the application lifecycle. (For example, it is not a good idea to
|
|
have them depend on your `DataSource` or JPA configuration.) You can work around such
|
|
restrictions by initializing the beans lazily when first used instead of on
|
|
initialization.
|
|
|
|
In the case of `Filters` and `Servlets`, you can also add mappings and init parameters by
|
|
adding a `FilterRegistrationBean` or a `ServletRegistrationBean` instead of or in
|
|
addition to the underlying component.
|
|
|
|
[NOTE]
|
|
====
|
|
If no `dispatcherType` is specified on a filter registration, `REQUEST` is used. This
|
|
aligns with the Servlet Specification's default dispatcher type.
|
|
====
|
|
|
|
Like any other Spring bean, you can define the order of Servlet filter beans; please
|
|
make sure to check the
|
|
"`<<spring-boot-features.adoc#boot-features-embedded-container-servlets-filters-listeners-beans>>`"
|
|
section.
|
|
|
|
|
|
|
|
[[howto-disable-registration-of-a-servlet-or-filter]]
|
|
===== Disable Registration of a Servlet or Filter
|
|
As <<howto-add-a-servlet-filter-or-listener-as-spring-bean,described earlier>>, any
|
|
`Servlet` or `Filter` beans are registered with the servlet container automatically. To
|
|
disable registration of a particular `Filter` or `Servlet` bean, create a registration
|
|
bean for it and mark it as disabled, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public FilterRegistrationBean registration(MyFilter filter) {
|
|
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
|
|
registration.setEnabled(false);
|
|
return registration;
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener-using-scanning]]
|
|
==== Add Servlets, Filters, and Listeners by Using Classpath Scanning
|
|
`@WebServlet`, `@WebFilter`, and `@WebListener` annotated classes can be automatically
|
|
registered with an embedded servlet container by annotating a `@Configuration` class
|
|
with `@ServletComponentScan` and specifying the package(s) containing the components
|
|
that you want to register. By default, `@ServletComponentScan` scans from the package
|
|
of the annotated class.
|
|
|
|
|
|
|
|
[[howto-change-the-http-port]]
|
|
=== Change the HTTP Port
|
|
In a standalone application, the main HTTP port defaults to `8080` but can be set with
|
|
`server.port` (for example, in `application.properties` or as a System property). Thanks
|
|
to relaxed binding of `Environment` values, you can also use `SERVER_PORT` (for example,
|
|
as an OS environment variable).
|
|
|
|
To switch off the HTTP endpoints completely but still create a `WebApplicationContext`,
|
|
use `server.port=-1`. (Doing so is sometimes useful for testing.)
|
|
|
|
For more details, see
|
|
"`<<spring-boot-features.adoc#boot-features-customizing-embedded-containers>>`"
|
|
in the '`Spring Boot features`' section, or the
|
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] source
|
|
code.
|
|
|
|
|
|
|
|
[[howto-user-a-random-unassigned-http-port]]
|
|
=== Use a Random Unassigned HTTP Port
|
|
To scan for a free port (using OS natives to prevent clashes) use `server.port=0`.
|
|
|
|
|
|
|
|
[[howto-discover-the-http-port-at-runtime]]
|
|
=== Discover the HTTP Port at Runtime
|
|
You can access the port the server is running on from log output or from the
|
|
`ServletWebServerApplicationContext` through its `WebServer`. The best way to get that and
|
|
be sure that it has been initialized is to add a `@Bean` of type
|
|
`ApplicationListener<ServletWebServerInitializedEvent>` and pull the container
|
|
out of the event when it is published.
|
|
|
|
Tests that use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)` can
|
|
also inject the actual port into a field by using the `@LocalServerPort` annotation, as
|
|
shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
|
|
public class MyWebIntegrationTests {
|
|
|
|
@Autowired
|
|
ServletWebServerApplicationContext server;
|
|
|
|
@LocalServerPort
|
|
int port;
|
|
|
|
// ...
|
|
|
|
}
|
|
----
|
|
|
|
[NOTE]
|
|
====
|
|
`@LocalServerPort` is a meta-annotation for `@Value("${local.server.port}")`. Do not try
|
|
to inject the port in a regular application. As we just saw, the value is set only after
|
|
the container has been initialized. Contrary to a test, application code callbacks are
|
|
processed early (before the value is actually available).
|
|
====
|
|
|
|
|
|
|
|
[[howto-configure-ssl]]
|
|
=== Configure SSL
|
|
SSL can be configured declaratively by setting the various `+server.ssl.*+` properties,
|
|
typically in `application.properties` or `application.yml`. The following example shows
|
|
setting SSL properties in `application.properties`:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.port=8443
|
|
server.ssl.key-store=classpath:keystore.jks
|
|
server.ssl.key-store-password=secret
|
|
server.ssl.key-password=another-secret
|
|
----
|
|
|
|
See {sc-spring-boot}/web/server/Ssl.{sc-ext}[`Ssl`] for details of all of the
|
|
supported properties.
|
|
|
|
Using configuration such as the preceding example means the application no longer supports
|
|
a plain HTTP connector at port 8080. Spring Boot does not support the configuration of
|
|
both an HTTP connector and an HTTPS connector through `application.properties`. If you
|
|
want to have both, you need to configure one of them programmatically. We recommend using
|
|
`application.properties` to configure HTTPS, as the HTTP connector is the easier of the
|
|
two to configure programmatically. See the
|
|
{github-code}/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors[`spring-boot-sample-tomcat-multi-connectors`]
|
|
sample project for an example.
|
|
|
|
|
|
|
|
[[howto-configure-http2]]
|
|
=== Configure HTTP/2
|
|
You can enable HTTP/2 support in your Spring Boot application with the
|
|
`+server.http2.enabled+` configuration property. This support depends on the chosen web
|
|
server and the application environment, since that protocol is not supported
|
|
out-of-the-box by JDK8.
|
|
|
|
[NOTE]
|
|
====
|
|
Spring Boot does not support `h2c`, the cleartext version of the HTTP/2 protocol. So you
|
|
must <<howto-configure-ssl, configure SSL first>>.
|
|
====
|
|
|
|
|
|
|
|
[[howto-configure-http2-undertow]]
|
|
==== HTTP/2 with Undertow
|
|
As of Undertow 1.4.0+, HTTP/2 is supported without any additional requirement on JDK8.
|
|
|
|
|
|
|
|
[[howto-configure-http2-jetty]]
|
|
==== HTTP/2 with Jetty
|
|
As of Jetty 9.4.8, HTTP/2 is also supported with the
|
|
https://www.conscrypt.org/[Conscrypt library].
|
|
To enable that support, your application needs to have two additional dependencies:
|
|
`org.eclipse.jetty:jetty-alpn-conscrypt-server` and `org.eclipse.jetty.http2:http2-server`.
|
|
|
|
|
|
|
|
[[howto-configure-http2-tomcat]]
|
|
==== HTTP/2 with Tomcat
|
|
Spring Boot ships by default with Tomcat 8.5.x. With that version, HTTP/2 is only
|
|
supported if the `libtcnative` library and its dependencies are installed on the host
|
|
operating system.
|
|
|
|
The library folder must be made available, if not already, to the JVM library path. You
|
|
can do so with a JVM argument such as
|
|
`-Djava.library.path=/usr/local/opt/tomcat-native/lib`. More on this in the
|
|
https://tomcat.apache.org/tomcat-8.5-doc/apr.html[official Tomcat documentation].
|
|
|
|
Starting Tomcat 8.5.x without that native support logs the following error:
|
|
|
|
[indent=0,subs="attributes"]
|
|
----
|
|
ERROR 8787 --- [ main] o.a.coyote.http11.Http11NioProtocol : The upgrade handler [org.apache.coyote.http2.Http2Protocol] for [h2] only supports upgrade via ALPN but has been configured for the ["https-jsse-nio-8443"] connector that does not support ALPN.
|
|
----
|
|
|
|
This error is not fatal, and the application still starts with HTTP/1.1 SSL support.
|
|
|
|
Running your application with Tomcat 9.0.x and JDK9 does not require any native library to
|
|
be installed. To use Tomcat 9, you can override the `tomcat.version` build property with
|
|
the version of your choice.
|
|
|
|
|
|
|
|
[[howto-configure-accesslogs]]
|
|
=== Configure Access Logging
|
|
Access logs can be configured for Tomcat, Undertow, and Jetty through their respective
|
|
namespaces.
|
|
|
|
For instance, the following settings log access on Tomcat with a
|
|
{tomcat-documentation}/config/valve.html#Access_Logging[custom pattern].
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.tomcat.basedir=my-tomcat
|
|
server.tomcat.accesslog.enabled=true
|
|
server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)
|
|
----
|
|
|
|
NOTE: The default location for logs is a `logs` directory relative to the Tomcat base
|
|
directory. By default, the `logs` directory is a temporary directory, so you may want to
|
|
fix Tomcat's base directory or use an absolute path for the logs. In the preceding
|
|
example, the logs are available in `my-tomcat/logs` relative to the working directory of
|
|
the application.
|
|
|
|
Access logging for Undertow can be configured in a similar fashion, as shown in the
|
|
following example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.undertow.accesslog.enabled=true
|
|
server.undertow.accesslog.pattern=%t %a "%r" %s (%D ms)
|
|
----
|
|
|
|
Logs are stored in a `logs` directory relative to the working directory of the
|
|
application. You can customize this location by setting the
|
|
`server.undertow.accesslog.directory` property.
|
|
|
|
Finally, access logging for Jetty can also be configured as follows:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.jetty.accesslog.enabled=true
|
|
server.jetty.accesslog.filename=/var/log/jetty-access.log
|
|
----
|
|
|
|
By default, logs are redirected to `System.err`. For more details, see
|
|
{jetty-documentation}/configuring-jetty-request-logs.html[the Jetty documentation].
|
|
|
|
|
|
|
|
[[howto-use-behind-a-proxy-server]]
|
|
[[howto-use-tomcat-behind-a-proxy-server]]
|
|
=== Running Behind a Front-end Proxy Server
|
|
Your application might need to send `302` redirects or render content with absolute links
|
|
back to itself. When running behind a proxy, the caller wants a link to the proxy and not
|
|
to the physical address of the machine hosting your app. Typically, such situations are
|
|
handled through a contract with the proxy, which adds headers to tell the back end how to
|
|
construct links to itself.
|
|
|
|
If the proxy adds conventional `X-Forwarded-For` and `X-Forwarded-Proto` headers (most
|
|
proxy servers do so), the absolute links should be rendered correctly, provided
|
|
`server.use-forward-headers` is set to `true` in your `application.properties`.
|
|
|
|
NOTE: If your application runs in Cloud Foundry or Heroku, the
|
|
`server.use-forward-headers` property defaults to `true`. In all
|
|
other instances, it defaults to `false`.
|
|
|
|
|
|
|
|
[[howto-customize-tomcat-behind-a-proxy-server]]
|
|
==== Customize Tomcat's Proxy Configuration
|
|
If you use Tomcat, you can additionally configure the names of the headers used to
|
|
carry "`forwarded`" information, as shown in the following example:
|
|
|
|
[indent=0]
|
|
----
|
|
server.tomcat.remote-ip-header=x-your-remote-ip-header
|
|
server.tomcat.protocol-header=x-your-protocol-header
|
|
----
|
|
|
|
Tomcat is also configured with a default regular expression that matches internal
|
|
proxies that are to be trusted. By default, IP addresses in `10/8`, `192.168/16`,
|
|
`169.254/16` and `127/8` are trusted. You can customize the valve's configuration by
|
|
adding an entry to `application.properties`, as shown in the following example:
|
|
|
|
[indent=0]
|
|
----
|
|
server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3}
|
|
----
|
|
|
|
NOTE: The double backslashes are required only when you use a properties file for
|
|
configuration. If you use YAML, single backslashes are sufficient, and a value
|
|
equivalent to that shown in the preceding example would be `192\.168\.\d{1,3}\.\d{1,3}`.
|
|
|
|
NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but do not do
|
|
so in production).
|
|
|
|
You can take complete control of the configuration of Tomcat's `RemoteIpValve` by
|
|
switching the automatic one off (to do so, set `server.use-forward-headers=false`) and
|
|
adding a new valve instance in a `TomcatServletWebServerFactory` bean.
|
|
|
|
|
|
|
|
[[howto-configure-tomcat]]
|
|
=== Configure Tomcat
|
|
Generally, you can follow the advice from
|
|
"`<<howto-discover-build-in-options-for-external-properties>>`" about
|
|
`@ConfigurationProperties` (`ServerProperties` is the main one here). However, you should
|
|
also look at `WebServerFactoryCustomizer` and various Tomcat-specific
|
|
`+*Customizers+` that you can add. The Tomcat APIs are quite rich. Consequently, once you
|
|
have access to the `TomcatServletWebServerFactory`, you can modify it in a number of ways.
|
|
Alternatively, if you need more control and customization, you can add your own
|
|
`TomcatServletWebServerFactory`.
|
|
|
|
|
|
|
|
[[howto-enable-multiple-connectors-in-tomcat]]
|
|
=== Enable Multiple Connectors with Tomcat
|
|
You can add an `org.apache.catalina.connector.Connector` to the
|
|
`TomcatServletWebServerFactory`, which can allow multiple connectors, including HTTP and
|
|
HTTPS connectors, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public ServletWebServerFactory servletContainer() {
|
|
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
|
|
tomcat.addAdditionalTomcatConnectors(createSslConnector());
|
|
return tomcat;
|
|
}
|
|
|
|
private Connector createSslConnector() {
|
|
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
|
|
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
|
|
try {
|
|
File keystore = new ClassPathResource("keystore").getFile();
|
|
File truststore = new ClassPathResource("keystore").getFile();
|
|
connector.setScheme("https");
|
|
connector.setSecure(true);
|
|
connector.setPort(8443);
|
|
protocol.setSSLEnabled(true);
|
|
protocol.setKeystoreFile(keystore.getAbsolutePath());
|
|
protocol.setKeystorePass("changeit");
|
|
protocol.setTruststoreFile(truststore.getAbsolutePath());
|
|
protocol.setTruststorePass("changeit");
|
|
protocol.setKeyAlias("apitester");
|
|
return connector;
|
|
}
|
|
catch (IOException ex) {
|
|
throw new IllegalStateException("can't access keystore: [" + "keystore"
|
|
+ "] or truststore: [" + "keystore" + "]", ex);
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-tomcat-legacycookieprocessor]]
|
|
=== Use Tomcat's LegacyCookieProcessor
|
|
By default, the embedded Tomcat used by Spring Boot does not support "Version 0" of the
|
|
Cookie format, so you may see the following error:
|
|
|
|
[indent=0]
|
|
----
|
|
java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
|
|
----
|
|
|
|
If at all possible, you should consider updating your code to only store values
|
|
compliant with later Cookie specifications. If, however, you cannot change the
|
|
way that cookies are written, you can instead configure Tomcat to use a
|
|
`LegacyCookieProcessor`. To switch to the `LegacyCookieProcessor`, use an
|
|
`WebServerFactoryCustomizer` bean that adds a `TomcatContextCustomizer`, as shown
|
|
in the following example:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/context/embedded/TomcatLegacyCookieProcessorExample.java[tag=customizer]
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-undertow]]
|
|
=== Configure Undertow
|
|
Generally you can follow the advice from
|
|
"`<<howto-discover-build-in-options-for-external-properties>>`" about
|
|
`@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow` are the
|
|
main ones here). However, you should also look at `WebServerFactoryCustomizer`.
|
|
Once you have access to the `UndertowServletWebServerFactory`, you can use an
|
|
`UndertowBuilderCustomizer` to modify Undertow's configuration to meet your needs.
|
|
Alternatively, if you need more control and customization, you can add your own
|
|
`UndertowServletWebServerFactory`.
|
|
|
|
|
|
|
|
[[howto-enable-multiple-listeners-in-undertow]]
|
|
=== Enable Multiple Listeners with Undertow
|
|
Add an `UndertowBuilderCustomizer` to the `UndertowServletWebServerFactory` and
|
|
add a listener to the `Builder`, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public UndertowServletWebServerFactory servletWebServerFactory() {
|
|
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
|
|
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
|
|
|
|
@Override
|
|
public void customize(Builder builder) {
|
|
builder.addHttpListener(8080, "0.0.0.0");
|
|
}
|
|
|
|
});
|
|
return factory;
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-create-websocket-endpoints-using-serverendpoint]]
|
|
=== Create WebSocket Endpoints Using @ServerEndpoint
|
|
If you want to use `@ServerEndpoint` in a Spring Boot application that used an embedded
|
|
container, you must declare a single `ServerEndpointExporter` `@Bean`, as shown in the
|
|
following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public ServerEndpointExporter serverEndpointExporter() {
|
|
return new ServerEndpointExporter();
|
|
}
|
|
----
|
|
|
|
The bean shown in the preceding example registers any `@ServerEndpoint` annotated beans
|
|
with the underlying WebSocket container. When deployed to a standalone servlet container,
|
|
this role is performed by a servlet container initializer, and the
|
|
`ServerEndpointExporter` bean is not required.
|
|
|
|
|
|
|
|
[[how-to-enable-http-response-compression]]
|
|
=== Enable HTTP Response Compression
|
|
HTTP response compression is supported by Jetty, Tomcat, and Undertow. It can be enabled
|
|
in `application.properties`, as follows:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
server.compression.enabled=true
|
|
----
|
|
|
|
By default, responses must be at least 2048 bytes in length for compression to be
|
|
performed. You can configure this behavior by setting the
|
|
`server.compression.min-response-size` property.
|
|
|
|
By default, responses are compressed only if their content type is one of the
|
|
following:
|
|
|
|
* `text/html`
|
|
* `text/xml`
|
|
* `text/plain`
|
|
* `text/css`
|
|
|
|
You can configure this behavior by setting the `server.compression.mime-types` property.
|
|
|
|
|
|
|
|
[[howto-spring-mvc]]
|
|
== Spring MVC
|
|
|
|
Spring Boot has a number of starters that include Spring MVC. Note that some starters
|
|
include a dependency on Spring MVC rather than include it directly. This section answers
|
|
common questions about Spring MVC and Spring Boot.
|
|
|
|
[[howto-write-a-json-rest-service]]
|
|
=== Write a JSON REST Service
|
|
Any Spring `@RestController` in a Spring Boot application should render JSON response by
|
|
default as long as Jackson2 is on the classpath, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@RestController
|
|
public class MyController {
|
|
|
|
@RequestMapping("/thing")
|
|
public MyThing thing() {
|
|
return new MyThing();
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
As long as `MyThing` can be serialized by Jackson2 (true for a normal POJO or Groovy
|
|
object), then `http://localhost:8080/thing` serves a JSON representation of it by
|
|
default. Note that, in a browser, you might sometimes see XML responses, because browsers
|
|
tend to send accept headers that prefer XML.
|
|
|
|
|
|
|
|
[[howto-write-an-xml-rest-service]]
|
|
=== Write an XML REST Service
|
|
If you have the Jackson XML extension (`jackson-dataformat-xml`) on the classpath, you
|
|
can use it to render XML responses. The previous example that we used for JSON would
|
|
work. To use the Jackson XML renderer, add the following dependency to your project:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
|
<artifactId>jackson-dataformat-xml</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
You may also want to add a dependency on Woodstox. It is faster than the default StAX
|
|
implementation provided by the JDK and also adds pretty-print support and improved
|
|
namespace handling. The following listing shows how to include a dependency on
|
|
https://github.com/FasterXML/woodstox[Woodstox]:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.codehaus.woodstox</groupId>
|
|
<artifactId>woodstox-core-asl</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
If Jackson's XML extension is not available, JAXB (provided by default in the JDK) is
|
|
used, with the additional requirement of having `MyThing` annotated as
|
|
`@XmlRootElement`, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@XmlRootElement
|
|
public class MyThing {
|
|
private String name;
|
|
// .. getters and setters
|
|
}
|
|
----
|
|
|
|
To get the server to render XML instead of JSON, you might have to send an
|
|
`Accept: text/xml` header (or use a browser).
|
|
|
|
|
|
|
|
[[howto-customize-the-jackson-objectmapper]]
|
|
=== Customize the Jackson ObjectMapper
|
|
Spring MVC (client and server side) uses `HttpMessageConverters` to negotiate content
|
|
conversion in an HTTP exchange. If Jackson is on the classpath, you already get the
|
|
default converter(s) provided by `Jackson2ObjectMapperBuilder`, an instance of which
|
|
is auto-configured for you.
|
|
|
|
The `ObjectMapper` (or `XmlMapper` for Jackson XML converter) instance (created by
|
|
default) has the following customized properties:
|
|
|
|
* `MapperFeature.DEFAULT_VIEW_INCLUSION` is disabled
|
|
* `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` is disabled
|
|
* `SerializationFeature.WRITE_DATES_AS_TIMESTAMPS` is disabled
|
|
|
|
Spring Boot also has some features to make it easier to customize this behavior.
|
|
|
|
You can configure the `ObjectMapper` and `XmlMapper` instances by using the environment.
|
|
Jackson provides an extensive suite of simple on/off features that can be used to
|
|
configure various aspects of its processing. These features are described in six enums (in
|
|
Jackson) that map onto properties in the environment:
|
|
|
|
|===
|
|
|Jackson enum|Environment property
|
|
|
|
|`com.fasterxml.jackson.databind.DeserializationFeature`
|
|
|`spring.jackson.deserialization.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.core.JsonGenerator.Feature`
|
|
|`spring.jackson.generator.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.databind.MapperFeature`
|
|
|`spring.jackson.mapper.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.core.JsonParser.Feature`
|
|
|`spring.jackson.parser.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.databind.SerializationFeature`
|
|
|`spring.jackson.serialization.<feature_name>=true\|false`
|
|
|
|
|`com.fasterxml.jackson.annotation.JsonInclude.Include`
|
|
|`spring.jackson.default-property-inclusion=always\|non_null\|non_absent\|non_default\|non_empty`
|
|
|===
|
|
|
|
For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`.
|
|
Note that, thanks to the use of <<boot-features-external-config-relaxed-binding,
|
|
relaxed binding>>, the case of `indent_output` does not have to match the case of the
|
|
corresponding enum constant, which is `INDENT_OUTPUT`.
|
|
|
|
This environment-based configuration is applied to the auto-configured
|
|
`Jackson2ObjectMapperBuilder` bean and applies to any mappers created by
|
|
using the builder, including the auto-configured `ObjectMapper` bean.
|
|
|
|
The context's `Jackson2ObjectMapperBuilder` can be customized by one or more
|
|
`Jackson2ObjectMapperBuilderCustomizer` beans. Such customizer beans can be ordered
|
|
(Boot's own customizer has an order of 0), letting additional customization be applied
|
|
both before and after Boot's customization.
|
|
|
|
Any beans of type `com.fasterxml.jackson.databind.Module` are automatically registered
|
|
with the auto-configured `Jackson2ObjectMapperBuilder` and are applied to any `ObjectMapper`
|
|
instances that it creates. This provides a global mechanism for contributing custom
|
|
modules when you add new features to your application.
|
|
|
|
If you want to replace the default `ObjectMapper` completely, either define a `@Bean` of
|
|
that type and mark it as `@Primary` or, if you prefer the builder-based
|
|
approach, define a `Jackson2ObjectMapperBuilder` `@Bean`. Note that, in either case,
|
|
doing so disables all auto-configuration of the `ObjectMapper`.
|
|
|
|
If you provide any `@Beans` of type `MappingJackson2HttpMessageConverter`,
|
|
they replace the default value in the MVC configuration. Also, a convenience bean of type
|
|
`HttpMessageConverters` is provided (and is always available if you use the default MVC
|
|
configuration). It has some useful methods to access the default and user-enhanced
|
|
message converters.
|
|
|
|
See the "`<<howto-customize-the-responsebody-rendering>>`" section and the
|
|
{sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
|
source code for more details.
|
|
|
|
|
|
|
|
[[howto-customize-the-responsebody-rendering]]
|
|
=== Customize the @ResponseBody Rendering
|
|
Spring uses `HttpMessageConverters` to render `@ResponseBody` (or responses from
|
|
`@RestController`). You can contribute additional converters by adding beans of the
|
|
appropriate type in a Spring Boot context. If a bean you add is of a type that would have
|
|
been included by default anyway (such as `MappingJackson2HttpMessageConverter` for JSON
|
|
conversions), it replaces the default value. A convenience bean of type
|
|
`HttpMessageConverters` is provided and is always available if you use the default MVC
|
|
configuration. It has some useful methods to access the default and user-enhanced message
|
|
converters (For example, it can be useful if you want to manually inject them into a
|
|
custom `RestTemplate`).
|
|
|
|
As in normal MVC usage, any `WebMvcConfigurer` beans that you provide can also
|
|
contribute converters by overriding the `configureMessageConverters` method. However, unlike
|
|
with normal MVC, you can supply only additional converters that you need (because Spring
|
|
Boot uses the same mechanism to contribute its defaults). Finally, if you opt out of the
|
|
Spring Boot default MVC configuration by providing your own `@EnableWebMvc` configuration,
|
|
you can take control completely and do everything manually by using
|
|
`getMessageConverters` from `WebMvcConfigurationSupport`.
|
|
|
|
See the
|
|
{sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
|
source code for more details.
|
|
|
|
|
|
|
|
[[howto-multipart-file-upload-configuration]]
|
|
=== Handling Multipart File Uploads
|
|
Spring Boot embraces the Servlet 3 `javax.servlet.http.Part` API to support uploading
|
|
files. By default, Spring Boot configures Spring MVC with a maximum size of 1MB per
|
|
file and a maximum of 10MB of file data in a single request. You may override these
|
|
values, the location to which intermediate data is stored (for example, to the `/tmp`
|
|
directory), and the threshold past which data is flushed to disk by using the properties
|
|
exposed in the `MultipartProperties` class. For example, if you want to specify that
|
|
files be unlimited, set the `spring.servlet.multipart.max-file-size` property to `-1`.
|
|
|
|
The multipart support is helpful when you want to receive multipart encoded file data as
|
|
a `@RequestParam`-annotated parameter of type `MultipartFile` in a Spring MVC controller
|
|
handler method.
|
|
|
|
See the
|
|
{sc-spring-boot-autoconfigure}/web/servlet/MultipartAutoConfiguration.{sc-ext}[`MultipartAutoConfiguration`]
|
|
source for more details.
|
|
|
|
|
|
|
|
[[howto-switch-off-the-spring-mvc-dispatcherservlet]]
|
|
=== Switch Off the Spring MVC DispatcherServlet
|
|
Spring Boot wants to serve all content from the root of your application (`/`) down. If
|
|
you would rather map your own servlet to that URL, you can do it. However, you may lose
|
|
some of the other Boot MVC features. To add your own servlet and map it to the root
|
|
resource, declare a `@Bean` of type `Servlet` and give it the special bean name,
|
|
`dispatcherServlet`. (You can also create a bean of a different type with that name if
|
|
you want to switch it off and not replace it.)
|
|
|
|
|
|
|
|
[[howto-switch-off-default-mvc-configuration]]
|
|
=== Switch off the Default MVC Configuration
|
|
The easiest way to take complete control over MVC configuration is to provide your own
|
|
`@Configuration` with the `@EnableWebMvc` annotation. Doing so leaves all MVC
|
|
configuration in your hands.
|
|
|
|
|
|
|
|
[[howto-customize-view-resolvers]]
|
|
=== Customize ViewResolvers
|
|
A `ViewResolver` is a core component of Spring MVC, translating view names in
|
|
`@Controller` to actual `View` implementations. Note that `ViewResolvers` are mainly
|
|
used in UI applications, rather than REST-style services (a `View` is not used to render
|
|
a `@ResponseBody`). There are many implementations of `ViewResolver` to choose from, and
|
|
Spring on its own is not opinionated about which ones you should use. Spring Boot, on the
|
|
other hand, installs one or two for you, depending on what it finds on the classpath and
|
|
in the application context. The `DispatcherServlet` uses all the resolvers it finds in
|
|
the application context, trying each one in turn until it gets a result, so, if you
|
|
add your own, you have to be aware of the order and in which position your resolver is
|
|
added.
|
|
|
|
`WebMvcAutoConfiguration` adds the following `ViewResolvers` to your context:
|
|
|
|
* An `InternalResourceViewResolver` named '`defaultViewResolver`'. This one locates
|
|
physical resources that can be rendered by using the `DefaultServlet` (including static
|
|
resources and JSP pages, if you use those). It applies a prefix and a suffix to the
|
|
view name and then looks for a physical resource with that path in the servlet context
|
|
(the defaults are both empty but are accessible for external configuration through
|
|
`spring.mvc.view.prefix` and `spring.mvc.view.suffix`). You can override it by
|
|
providing a bean of the same type.
|
|
* A `BeanNameViewResolver` named '`beanNameViewResolver`'. This is a useful member of the
|
|
view resolver chain and picks up any beans with the same name as the `View` being
|
|
resolved. It should not be necessary to override or replace it.
|
|
* A `ContentNegotiatingViewResolver` named '`viewResolver`' is added only if there *are*
|
|
actually beans of type `View` present. This is a '`master`' resolver, delegating to all
|
|
the others and attempting to find a match to the '`Accept`' HTTP header sent by the
|
|
client. There is a useful
|
|
https://spring.io/blog/2013/06/03/content-negotiation-using-views[blog about
|
|
`ContentNegotiatingViewResolver`] that you might like to study to learn more, and you
|
|
might also look at the source code for detail. You can switch off the auto-configured
|
|
`ContentNegotiatingViewResolver` by defining a bean named '`viewResolver`'.
|
|
* If you use Thymeleaf, you also have a `ThymeleafViewResolver` named
|
|
'`thymeleafViewResolver`'. It looks for resources by surrounding the view name with a
|
|
prefix and suffix. The prefix is `spring.thymeleaf.prefix`, and the suffix is
|
|
`spring.thymeleaf.suffix`. The values of the prefix and suffix default to
|
|
'`classpath:/templates/`' and '`.html`', respectively. You can override
|
|
`ThymeleafViewResolver` by providing a bean of the same name.
|
|
* If you use FreeMarker, you also have a `FreeMarkerViewResolver` named
|
|
'`freeMarkerViewResolver`'. It looks for resources in a loader path (which is
|
|
externalized to `spring.freemarker.templateLoaderPath` and has a default value of
|
|
'`classpath:/templates/`') by surrounding the view name with a prefix and a suffix. The
|
|
prefix is externalized to `spring.freemarker.prefix`, and the suffix is externalized to
|
|
`spring.freemarker.suffix`. The default values of the prefix and suffix are empty and
|
|
'`.ftl`', respectively. You can override `FreeMarkerViewResolver` by providing a bean
|
|
of the same name.
|
|
* If you use Groovy templates (actually, if `groovy-templates` is on your classpath), you
|
|
also have a `GroovyMarkupViewResolver` named '`groovyMarkupViewResolver`'. It looks for
|
|
resources in a loader path by surrounding the view name with a prefix and suffix
|
|
(externalized to `spring.groovy.template.prefix` and `spring.groovy.template.suffix`).
|
|
The prefix and suffix have default values of '`classpath:/templates/`' and '`.tpl`',
|
|
respectively. You can override `GroovyMarkupViewResolver` by providing a bean of the
|
|
same name.
|
|
|
|
For more detail, see the following sections:
|
|
|
|
* {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
|
* {sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`]
|
|
* {sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`]
|
|
* {sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`]
|
|
|
|
|
|
|
|
[[howto-http-clients]]
|
|
== HTTP Clients
|
|
|
|
Spring Boot offers a number of starters that work with HTTP clients. This section answers
|
|
questions related to using them.
|
|
|
|
[[howto-http-clients-proxy-configuration]]
|
|
=== Configure RestTemplate to Use a Proxy
|
|
As described in <<spring-boot-features.adoc#boot-features-resttemplate-customization>>,
|
|
you can use a `RestTemplateCustomizer` with `RestTemplateBuilder` to build a customized
|
|
`RestTemplate`. This is the recommended approach for creating a `RestTemplate` configured
|
|
to use a proxy.
|
|
|
|
The exact details of the proxy configuration depend on the underlying client request
|
|
factory that is being used. The following example configures
|
|
`HttpComponentsClientRequestFactory` with an `HttpClient` that uses a proxy for all hosts
|
|
except `192.168.0.5`:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[tag=customizer]
|
|
----
|
|
|
|
|
|
|
|
[[howto-logging]]
|
|
== Logging
|
|
|
|
Spring Boot has no mandatory logging dependency, except for the Commons Logging API, which
|
|
is typically provided by Spring Framework's `spring-jcl` module. To use
|
|
http://logback.qos.ch[Logback], you need to include it and `spring-jcl` on the classpath.
|
|
The simplest way to do that is through the starters, which all depend on
|
|
`spring-boot-starter-logging`. For a web application, you need only
|
|
`spring-boot-starter-web`, since it depends transitively on the logging starter. If you
|
|
use Maven, the following dependency adds logging for you:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
Spring Boot has a `LoggingSystem` abstraction that attempts to configure logging based on
|
|
the content of the classpath. If Logback is available, it is the first choice.
|
|
|
|
If the only change you need to make to logging is to set the levels of various loggers,
|
|
you can do so in `application.properties` by using the "logging.level" prefix, as shown
|
|
in the following example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
logging.level.org.springframework.web=DEBUG
|
|
logging.level.org.hibernate=ERROR
|
|
----
|
|
|
|
You can also set the location of a file to which to write the log (in addition to the
|
|
console) by using "logging.file".
|
|
|
|
To configure the more fine-grained settings of a logging system, you need to use the native
|
|
configuration format supported by the `LoggingSystem` in question. By default, Spring Boot
|
|
picks up the native configuration from its default location for the system (such as
|
|
`classpath:logback.xml` for Logback), but you can set the location of the config file by
|
|
using the "logging.config" property.
|
|
|
|
|
|
|
|
[[howto-configure-logback-for-logging]]
|
|
=== Configure Logback for Logging
|
|
If you put a `logback.xml` in the root of your classpath, it is picked up from there (or
|
|
from `logback-spring.xml`, to take advantage of the templating features provided by
|
|
Boot). Spring Boot provides a default base configuration that you can include if you
|
|
want to set levels, as shown in the following example:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<configuration>
|
|
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
|
<logger name="org.springframework.web" level="DEBUG"/>
|
|
</configuration>
|
|
----
|
|
|
|
If you look at `base.xml` in the spring-boot jar, you can see that it uses
|
|
some useful System properties that the `LoggingSystem` takes care of creating for you:
|
|
|
|
* `${PID}`: The current process ID.
|
|
* `${LOG_FILE}`: Whether `logging.file` was set in Boot's external configuration.
|
|
* `${LOG_PATH}`: Whether `logging.path` (representing a directory for
|
|
log files to live in) was set in Boot's external configuration.
|
|
* `${LOG_EXCEPTION_CONVERSION_WORD}`: Whether `logging.exception-conversion-word` was set
|
|
in Boot's external configuration.
|
|
|
|
Spring Boot also provides some nice ANSI color terminal output on a console (but not in
|
|
a log file) by using a custom Logback converter. See the default `base.xml` configuration
|
|
for details.
|
|
|
|
If Groovy is on the classpath, you should be able to configure Logback with
|
|
`logback.groovy` as well. If present, this setting is given preference.
|
|
|
|
|
|
|
|
[[howto-configure-logback-for-logging-fileonly]]
|
|
==== Configure Logback for File-only Output
|
|
If you want to disable console logging and write output only to a file, you need a custom
|
|
`logback-spring.xml` that imports `file-appender.xml` but not `console-appender.xml`, as
|
|
shown in the following example:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<configuration>
|
|
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
|
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
|
|
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
|
|
<root level="INFO">
|
|
<appender-ref ref="FILE" />
|
|
</root>
|
|
</configuration>
|
|
----
|
|
|
|
You also need to add `logging.file` to your `application.properties`, as shown in the
|
|
following example:
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
logging.file=myapplication.log
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-log4j-for-logging]]
|
|
=== Configure Log4j for Logging
|
|
Spring Boot supports http://logging.apache.org/log4j/2.x[Log4j 2] for logging
|
|
configuration if it is on the classpath. If you use the starters for
|
|
assembling dependencies, you have to exclude Logback and then include log4j 2
|
|
instead. If you do not use the starters, you need to provide (at least) `spring-jcl` in
|
|
addition to Log4j 2.
|
|
|
|
The simplest path is probably through the starters, even though it requires some
|
|
jiggling with excludes. The following example shows how to set up the starters in Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-logging</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-log4j2</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
NOTE: The Log4j starters gather together the dependencies for common logging
|
|
requirements (such as having Tomcat use `java.util.logging` but configuring the
|
|
output using Log4j 2). See the
|
|
{github-code}/spring-boot-samples/spring-boot-sample-actuator-log4j2[Actuator Log4j 2]
|
|
samples for more detail and to see it in action.
|
|
|
|
NOTE: To ensure that debug logging performed using `java.util.logging` is routed into
|
|
Log4j 2, configure its https://logging.apache.org/log4j/2.0/log4j-jul/index.html[JDK
|
|
logging adapter] by setting the `java.util.logging.manager` system property to
|
|
`org.apache.logging.log4j.jul.LogManager`.
|
|
|
|
|
|
|
|
[[howto-configure-log4j-for-logging-yaml-or-json-config]]
|
|
==== Use YAML or JSON to Configure Log4j 2
|
|
In addition to its default XML configuration format, Log4j 2 also supports YAML and JSON
|
|
configuration files. To configure Log4j 2 to use an alternative configuration file format,
|
|
add the appropriate dependencies to the classpath and name your
|
|
configuration files to match your chosen file format, as shown in the following example:
|
|
|
|
[cols="10,75,15"]
|
|
|===
|
|
|Format|Dependencies|File names
|
|
|
|
|YAML
|
|
a| `com.fasterxml.jackson.core:jackson-databind` +
|
|
`com.fasterxml.jackson.dataformat:jackson-dataformat-yaml`
|
|
a| `log4j2.yaml` +
|
|
`log4j2.yml`
|
|
|
|
|JSON
|
|
a| `com.fasterxml.jackson.core:jackson-databind`
|
|
a| `log4j2.json` +
|
|
`log4j2.jsn`
|
|
|===
|
|
|
|
[[howto-data-access]]
|
|
== Data Access
|
|
|
|
Spring Boot includes a number of starters for working with data sources. This section
|
|
answers questions related to doing so.
|
|
|
|
[[howto-configure-a-datasource]]
|
|
=== Configure a Custom DataSource
|
|
To configure your own `DataSource`, define a `@Bean` of that type in your configuration.
|
|
Spring Boot reuses your `DataSource` anywhere one is required, including database
|
|
initialization. If you need to externalize some settings, you can bind your
|
|
`DataSource` to the environment (see
|
|
"`<<spring-boot-features.adoc#boot-features-external-config-3rd-party-configuration>>`").
|
|
|
|
The following example shows how to define a data source in a bean:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
@ConfigurationProperties(prefix="app.datasource")
|
|
public DataSource dataSource() {
|
|
return new FancyDataSource();
|
|
}
|
|
----
|
|
|
|
The following example shows how to define a data source by setting properties:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.url=jdbc:h2:mem:mydb
|
|
app.datasource.username=sa
|
|
app.datasource.pool-size=30
|
|
----
|
|
|
|
Assuming that your `FancyDataSource` has regular JavaBean properties for the URL, the
|
|
username, and the pool size, these settings are bound automatically before the
|
|
`DataSource` is made available to other components. The regular
|
|
<<howto-initialize-a-database-using-spring-jdbc,database initialization>> also happens
|
|
(so the relevant sub-set of `spring.datasource.*` can still be used with your custom
|
|
configuration).
|
|
|
|
You can apply the same principle if you configure a custom JNDI `DataSource`, as shown in
|
|
the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean(destroyMethod="")
|
|
@ConfigurationProperties(prefix="app.datasource")
|
|
public DataSource dataSource() throws Exception {
|
|
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
|
|
return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
|
|
}
|
|
----
|
|
|
|
Spring Boot also provides a utility builder class, called `DataSourceBuilder`, that can
|
|
be used to create one of the standard data sources (if it is on the classpath). The
|
|
builder can detect the one to use based on what's available on the classpath. It also
|
|
auto-detects the driver based on the JDBC URL.
|
|
|
|
The following example shows how to create a data source by using a `DataSourceBuilder`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/BasicDataSourceExample.java[tag=configuration]
|
|
----
|
|
|
|
To run an app with that `DataSource`, all you need is the connection
|
|
information. Pool-specific settings can also be provided. Check the implementation that
|
|
is going to be used at runtime for more details.
|
|
|
|
The following example shows how to define a JDBC data source by setting properties:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.url=jdbc:mysql://localhost/test
|
|
app.datasource.username=dbuser
|
|
app.datasource.password=dbpass
|
|
app.datasource.pool-size=30
|
|
----
|
|
|
|
However, there is a catch. Because the actual type of the connection pool is not exposed,
|
|
no keys are generated in the metadata for your custom `DataSource` and no completion is
|
|
available in your IDE (because the `DataSource` interface exposes no properties). Also, if
|
|
you happen to have Hikari on the classpath, this basic setup does not work, because Hikari
|
|
has no `url` property (but does have a `jdbcUrl` property). In that case, you must rewrite
|
|
your configuration as follows:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.jdbc-url=jdbc:mysql://localhost/test
|
|
app.datasource.username=dbuser
|
|
app.datasource.password=dbpass
|
|
app.datasource.maximum-pool-size=30
|
|
----
|
|
|
|
You can fix that by forcing the connection pool to use and return a dedicated
|
|
implementation rather than `DataSource`. You cannot change the implementation
|
|
at runtime, but the list of options will be explicit.
|
|
|
|
The following example shows how create a `HikariDataSource` with `DataSourceBuilder`:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/SimpleDataSourceExample.java[tag=configuration]
|
|
----
|
|
|
|
You can even go further by leveraging what `DataSourceProperties` does for you -- that is,
|
|
by providing a default embedded database with a sensible username and password if no URL
|
|
is provided. You can easily initialize a `DataSourceBuilder` from the state of any
|
|
`DataSourceProperties` object, so you could also inject the DataSource that Spring Boot
|
|
creates automatically. However, that would split your configuration into two namespaces:
|
|
`url`, `username`, `password`, `type`, and `driver` on `spring.datasource` and the rest on
|
|
your custom namespace (`app.datasource`). To avoid that, you can redefine a custom
|
|
`DataSourceProperties` on your custom namespace, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configuration]
|
|
----
|
|
|
|
This setup puts you _in sync_ with what Spring Boot does for you by default, except that
|
|
a dedicated connection pool is chosen (in code) and its settings are exposed in the same
|
|
namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl`
|
|
translation for you, you can configure it as follows:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.url=jdbc:mysql://localhost/test
|
|
app.datasource.username=dbuser
|
|
app.datasource.password=dbpass
|
|
app.datasource.maximum-pool-size=30
|
|
----
|
|
|
|
NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type`
|
|
has no effect. In practice, the builder is initialized with whatever value you
|
|
might set there and then overridden by the call to `.type()`.
|
|
|
|
See "`<<spring-boot-features.adoc#boot-features-configure-datasource>>`" in the
|
|
"`Spring Boot features`" section and the
|
|
{sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`]
|
|
class for more details.
|
|
|
|
|
|
|
|
[[howto-two-datasources]]
|
|
=== Configure Two DataSources
|
|
If you need to configure multiple data sources, you can apply the same tricks that are
|
|
described in the previous section. You must, however, mark one of the `DataSource`
|
|
instances as `@Primary`, because various auto-configurations down the road expect to be
|
|
able to get one by type.
|
|
|
|
If you create your own `DataSource`, the auto-configuration backs off. In the following
|
|
example, we provide the _exact_ same feature set as the auto-configuration provides
|
|
on the primary data source:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/SimpleTwoDataSourcesExample.java[tag=configuration]
|
|
----
|
|
|
|
TIP: `firstDataSourceProperties` has to be flagged as `@Primary` so that the database
|
|
initializer feature uses your copy (if you use the initializer).
|
|
|
|
Both data sources are also bound for advanced customizations. For instance, you could
|
|
configure them as follows:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
app.datasource.first.type=com.zaxxer.hikari.HikariDataSource
|
|
app.datasource.first.maximum-pool-size=30
|
|
|
|
app.datasource.second.url=jdbc:mysql://localhost/test
|
|
app.datasource.second.username=dbuser
|
|
app.datasource.second.password=dbpass
|
|
app.datasource.second.max-total=30
|
|
----
|
|
|
|
You can apply the same concept to the secondary `DataSource` as well, as shown in the
|
|
following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
include::{code-examples}/jdbc/CompleteTwoDataSourcesExample.java[tag=configuration]
|
|
----
|
|
|
|
The preceding example configures two data sources on custom namespaces with the same
|
|
logic as Spring Boot would use in auto-configuration.
|
|
|
|
|
|
|
|
[[howto-use-spring-data-repositories]]
|
|
=== Use Spring Data Repositories
|
|
Spring Data can create implementations of `@Repository` interfaces of various flavors.
|
|
Spring Boot handles all of that for you, as long as those `@Repositories` are included in
|
|
the same package (or a sub-package) of your `@EnableAutoConfiguration` class.
|
|
|
|
For many applications, all you need is to put the right Spring Data dependencies on
|
|
your classpath (there is a `spring-boot-starter-data-jpa` for JPA and a
|
|
`spring-boot-starter-data-mongodb` for Mongodb) and create some repository interfaces to
|
|
handle your `@Entity` objects. Examples are in the
|
|
{github-code}/spring-boot-samples/spring-boot-sample-data-jpa[JPA sample] and the
|
|
{github-code}/spring-boot-samples/spring-boot-sample-data-mongodb[Mongodb sample].
|
|
|
|
Spring Boot tries to guess the location of your `@Repository` definitions, based on the
|
|
`@EnableAutoConfiguration` it finds. To get more control, use the `@EnableJpaRepositories`
|
|
annotation (from Spring Data JPA).
|
|
|
|
For more about Spring Data, see the {spring-data}[Spring Data project page].
|
|
|
|
|
|
|
|
[[howto-separate-entity-definitions-from-spring-configuration]]
|
|
=== Separate @Entity Definitions from Spring Configuration
|
|
Spring Boot tries to guess the location of your `@Entity` definitions, based on the
|
|
`@EnableAutoConfiguration` it finds. To get more control, you can use the `@EntityScan`
|
|
annotation, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
@EnableAutoConfiguration
|
|
@EntityScan(basePackageClasses=City.class)
|
|
public class Application {
|
|
|
|
//...
|
|
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-jpa-properties]]
|
|
=== Configure JPA Properties
|
|
Spring Data JPA already provides some vendor-independent configuration options (such as
|
|
those for SQL logging), and Spring Boot exposes those options and a few more for Hibernate
|
|
as external configuration properties. Some of them are automatically detected according to
|
|
the context so you should not have to set them.
|
|
|
|
The `spring.jpa.hibernate.ddl-auto` is a special case, because, depending on runtime
|
|
conditions, it has different defaults. If an embedded database is used and no schema
|
|
manager (such as Liquibase or Flyway) is handling the `DataSource`, it defaults to
|
|
`create-drop`. In all other cases, it defaults to `none`.
|
|
|
|
The dialect to use is also automatically detected based on the current `DataSource`, but
|
|
you can set `spring.jpa.database` yourself if you want to be explicit and bypass that
|
|
check on startup.
|
|
|
|
NOTE: Specifying a `database` leads to the configuration of a well-defined Hibernate
|
|
dialect. Several databases have more than one `Dialect`, and this may not suit your needs.
|
|
In that case, you can either set `spring.jpa.database` to `default` to let Hibernate
|
|
figure things out or set the dialect by setting the `spring.jpa.database-platform`
|
|
property.
|
|
|
|
The most common options to set are shown in the following example:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
|
|
spring.jpa.show-sql=true
|
|
----
|
|
|
|
In addition, all properties in `+spring.jpa.properties.*+` are passed through as normal
|
|
JPA properties (with the prefix stripped) when the local `EntityManagerFactory` is
|
|
created.
|
|
|
|
TIP: If you need to apply advanced customization to Hibernate properties, consider
|
|
registering a `HibernatePropertiesCustomizer` bean that will be invoked prior to creating
|
|
the `EntityManagerFactory`. This takes precedence to anything that is applied by the
|
|
auto-configuration.
|
|
|
|
|
|
|
|
[[howto-configure-hibernate-naming-strategy]]
|
|
=== Configure Hibernate Naming Strategy
|
|
Hibernate uses {hibernate-documentation}#naming[two different naming strategies] to map
|
|
names from the object model to the corresponding database names. The fully qualified
|
|
class name of the physical and the implicit strategy implementations can be configured by
|
|
setting the `spring.jpa.hibernate.naming.physical-strategy` and
|
|
`spring.jpa.hibernate.naming.implicit-strategy` properties, respectively. Alternatively,
|
|
if `ImplicitNamingStrategy` or `PhysicalNamingStrategy` beans are available in the
|
|
application context, Hibernate will be automatically configured to use them.
|
|
|
|
By default, Spring Boot configures the physical naming strategy with
|
|
`SpringPhysicalNamingStrategy`. This implementation provides the same table structure as
|
|
Hibernate 4: all dots are replaced by underscores and camel casing is replaced by
|
|
underscores as well. By default, all table names are generated in lower case, but it is
|
|
possible to override that flag if your schema requires it.
|
|
|
|
For example, a `TelephoneNumber` entity is mapped to the `telephone_number` table.
|
|
|
|
If you prefer to use Hibernate 5's default instead, set the following property:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
|
----
|
|
|
|
Alternatively, you can configure the following bean:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Bean
|
|
public PhysicalNamingStrategy physicalNamingStrategy() {
|
|
return new PhysicalNamingStrategyStandardImpl();
|
|
}
|
|
----
|
|
|
|
See {sc-spring-boot-autoconfigure}/orm/jpa/HibernateJpaAutoConfiguration.{sc-ext}[`HibernateJpaAutoConfiguration`]
|
|
and {sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBaseConfiguration`]
|
|
for more details.
|
|
|
|
|
|
|
|
[[howto-use-custom-entity-manager]]
|
|
=== Use a Custom EntityManagerFactory
|
|
To take full control of the configuration of the `EntityManagerFactory`, you need to add
|
|
a `@Bean` named '`entityManagerFactory`'. Spring Boot auto-configuration switches off its
|
|
entity manager in the presence of a bean of that type.
|
|
|
|
|
|
|
|
[[howto-use-two-entity-managers]]
|
|
=== Use Two EntityManagers
|
|
Even if the default `EntityManagerFactory` works fine, you need to define a new one.
|
|
Otherwise, the presence of the second bean of that type switches off the
|
|
default. To make it easy to do, you can use the convenient `EntityManagerBuilder`
|
|
provided by Spring Boot. Alternatively, you can just the
|
|
`LocalContainerEntityManagerFactoryBean` directly from Spring ORM, as shown in the
|
|
following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
// add two data sources configured as above
|
|
|
|
@Bean
|
|
public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
|
|
EntityManagerFactoryBuilder builder) {
|
|
return builder
|
|
.dataSource(customerDataSource())
|
|
.packages(Customer.class)
|
|
.persistenceUnit("customers")
|
|
.build();
|
|
}
|
|
|
|
@Bean
|
|
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
|
|
EntityManagerFactoryBuilder builder) {
|
|
return builder
|
|
.dataSource(orderDataSource())
|
|
.packages(Order.class)
|
|
.persistenceUnit("orders")
|
|
.build();
|
|
}
|
|
----
|
|
|
|
The configuration above almost works on its own. To complete the picture, you need to
|
|
configure `TransactionManagers` for the two `EntityManagers` as well. If you mark one of
|
|
them as `@Primary`, it could be picked up by the default `JpaTransactionManager` in Spring
|
|
Boot. The other would have to be explicitly injected into a new instance. Alternatively,
|
|
you might be able to use a JTA transaction manager that spans both.
|
|
|
|
If you use Spring Data, you need to configure `@EnableJpaRepositories` accordingly,
|
|
as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
@EnableJpaRepositories(basePackageClasses = Customer.class,
|
|
entityManagerFactoryRef = "customerEntityManagerFactory")
|
|
public class CustomerConfiguration {
|
|
...
|
|
}
|
|
|
|
@Configuration
|
|
@EnableJpaRepositories(basePackageClasses = Order.class,
|
|
entityManagerFactoryRef = "orderEntityManagerFactory")
|
|
public class OrderConfiguration {
|
|
...
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[howto-use-traditional-persistence-xml]]
|
|
=== Use a Traditional `persistence.xml` File
|
|
Spring does not require the use of XML to configure the JPA provider, and Spring Boot
|
|
assumes you want to take advantage of that feature. If you prefer to use
|
|
`persistence.xml`, you need to define your own `@Bean` of type
|
|
`LocalEntityManagerFactoryBean` (with an ID of '`entityManagerFactory`') and set the
|
|
persistence unit name there.
|
|
|
|
See
|
|
{sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBaseConfiguration`]
|
|
for the default settings.
|
|
|
|
|
|
|
|
[[howto-use-spring-data-jpa--and-mongo-repositories]]
|
|
=== Use Spring Data JPA and Mongo Repositories
|
|
|
|
Spring Data JPA and Spring Data Mongo can both automatically create `Repository`
|
|
implementations for you. If they are both present on the classpath, you might have to do
|
|
some extra configuration to tell Spring Boot which repositories to create. The most
|
|
explicit way to do that is to use the standard Spring Data `+@EnableJpaRepositories+` and
|
|
`+@EnableMongoRepositories+` annotations and provide the location of your `Repository`
|
|
interfaces.
|
|
|
|
There are also flags (`+spring.data.*.repositories.enabled+` and
|
|
`+spring.data.*.repositories.type+`) that you can use to switch the auto-configured
|
|
repositories on and off in external configuration. Doing so is useful, for instance, in
|
|
case you want to switch off the Mongo repositories and still use the auto-configured
|
|
`MongoTemplate`.
|
|
|
|
The same obstacle and the same features exist for other auto-configured Spring Data
|
|
repository types (Elasticsearch, Solr, and others). To work with them, change the names of
|
|
the annotations and flags accordingly.
|
|
|
|
|
|
|
|
[[howto-use-exposing-spring-data-repositories-rest-endpoint]]
|
|
=== Expose Spring Data Repositories as REST Endpoint
|
|
Spring Data REST can expose the `Repository` implementations as REST endpoints for you,
|
|
provided Spring MVC has been enabled for the application.
|
|
|
|
Spring Boot exposes a set of useful properties (from the `spring.data.rest` namespace)
|
|
that customize the
|
|
{spring-data-rest-javadoc}/core/config/RepositoryRestConfiguration.{dc-ext}[`RepositoryRestConfiguration`].
|
|
If you need to provide additional customization, you should use a
|
|
{spring-data-rest-javadoc}/webmvc/config/RepositoryRestConfigurer.{dc-ext}[`RepositoryRestConfigurer`]
|
|
bean.
|
|
|
|
NOTE: If you do not specify any order on your custom `RepositoryRestConfigurer`, it runs
|
|
after the one Spring Boot uses internally. If you need to specify an order, make sure it
|
|
is higher than 0.
|
|
|
|
|
|
|
|
[[howto-configure-a-component-that-is-used-by-JPA]]
|
|
=== Configure a Component that is Used by JPA
|
|
If you want to configure a component that JPA uses, then you need to ensure
|
|
that the component is initialized before JPA. When the component is auto-configured,
|
|
Spring Boot takes care of this for you. For example, when Flyway is auto-configured,
|
|
Hibernate is configured to depend upon Flyway so that Flyway has a chance to
|
|
initialize the database before Hibernate tries to use it.
|
|
|
|
If you are configuring a component yourself, you can use an
|
|
`EntityManagerFactoryDependsOnPostProcessor` subclass as a convenient way of setting up
|
|
the necessary dependencies. For example, if you use Hibernate Search with
|
|
Elasticsearch as its index manager, any `EntityManagerFactory` beans must be
|
|
configured to depend on the `elasticsearchClient` bean, as shown in the following example:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
include::{code-examples}/elasticsearch/HibernateSearchElasticsearchExample.java[tag=configuration]
|
|
----
|
|
|
|
|
|
|
|
[[howto-configure-jOOQ-with-multiple-datasources]]
|
|
=== Configure jOOQ with Two DataSources
|
|
If you need to use jOOQ with multiple data sources, you should create your own
|
|
`DSLContext` for each one. Refer to
|
|
{sc-spring-boot-autoconfigure}/jooq/JooqAutoConfiguration.{sc-ext}[JooqAutoConfiguration]
|
|
for more details.
|
|
|
|
TIP: In particular, `JooqExceptionTranslator` and `SpringTransactionProvider` can be
|
|
reused to provide similar features to what the auto-configuration does with a single
|
|
`DataSource`.
|
|
|
|
|
|
|
|
[[howto-database-initialization]]
|
|
== Database Initialization
|
|
An SQL database can be initialized in different ways depending on what your stack is.
|
|
Of course, you can also do it manually, provided the database is a separate process.
|
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-jpa]]
|
|
=== Initialize a Database Using JPA
|
|
JPA has features for DDL generation, and these can be set up to run on startup against the
|
|
database. This is controlled through two external properties:
|
|
|
|
* `spring.jpa.generate-ddl` (boolean) switches the feature on and off and is vendor
|
|
independent.
|
|
* `spring.jpa.hibernate.ddl-auto` (enum) is a Hibernate feature that controls the
|
|
behavior in a more fine-grained way. This feature is described in more detail later in
|
|
this guide.
|
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-hibernate]]
|
|
=== Initialize a Database Using Hibernate
|
|
You can set `spring.jpa.hibernate.ddl-auto` explicitly and the standard Hibernate property
|
|
values are `none`, `validate`, `update`, `create`, and `create-drop`. Spring Boot chooses
|
|
a default value for you based on whether it thinks your database is embedded. It defaults
|
|
to `create-drop` if no schema manager has been detected or `none` in all other cases. An
|
|
embedded database is detected by looking at the `Connection` type. `hsqldb`, `h2`, and
|
|
`derby` are embedded, and others are not. Be careful when switching from in-memory to a
|
|
'`real`' database that you do not make assumptions about the existence of the tables and
|
|
data in the new platform. You either have to set `ddl-auto` explicitly or use one of the
|
|
other mechanisms to initialize the database.
|
|
|
|
NOTE: You can output the schema creation by enabling the `org.hibernate.SQL` logger. This
|
|
is done for you automatically if you enable the
|
|
<<boot-features-logging-console-output,debug mode>>.
|
|
|
|
In addition, a file named `import.sql` in the root of the classpath is executed on
|
|
startup if Hibernate creates the schema from scratch (that is, if the `ddl-auto` property
|
|
is set to `create` or `create-drop`). This can be useful for demos and for testing if you
|
|
are careful but is probably not something you want to be on the classpath in production.
|
|
It is a Hibernate feature (and has nothing to do with Spring).
|
|
|
|
|
|
[[howto-initialize-a-database-using-spring-jdbc]]
|
|
=== Initialize a Database
|
|
Spring Boot can automatically create the schema (DDL scripts) of your `DataSource` and
|
|
initialize it (DML scripts). It loads SQL from the standard root classpath locations:
|
|
`schema.sql` and `data.sql`, respectively. In addition, Spring Boot processes the
|
|
`schema-${platform}.sql` and `data-${platform}.sql` files (if present), where `platform`
|
|
is the value of `spring.datasource.platform`. This allows you to switch to
|
|
database-specific scripts if necessary. For example, you might choose to set it to the
|
|
vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`, `postgresql`, and so on).
|
|
|
|
Spring Boot automatically creates the schema of an embedded `DataSource`. This behavior
|
|
can be customized by using the `spring.datasource.initialization-mode` property (and it
|
|
can also be `always` or `never`).
|
|
|
|
By default, Spring Boot enables the fail-fast feature of the Spring JDBC initializer. This
|
|
means that, if the scripts cause exceptions, the application fails to start. You can tune
|
|
that behavior by setting `spring.datasource.continue-on-error`.
|
|
|
|
NOTE: In a JPA-based app, you can choose to let Hibernate create the schema or use
|
|
`schema.sql`, but you cannot do both. Make sure to disable
|
|
`spring.jpa.hibernate.ddl-auto` if you use `schema.sql`.
|
|
|
|
|
|
|
|
[[howto-initialize-a-spring-batch-database]]
|
|
=== Initialize a Spring Batch Database
|
|
If you use Spring Batch, it comes pre-packaged with SQL initialization scripts for most
|
|
popular database platforms. Spring Boot can detect your database type and execute those
|
|
scripts on startup. If you use an embedded database, this happens by default. You can also
|
|
enable it for any database type, as shown in the following example:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
spring.batch.initialize-schema=always
|
|
----
|
|
|
|
You can also switch off the initialization explicitly by setting
|
|
`spring.batch.initialize-schema=never`.
|
|
|
|
|
|
|
|
[[howto-use-a-higher-level-database-migration-tool]]
|
|
=== Use a Higher-level Database Migration Tool
|
|
Spring Boot supports two higher-level migration tools: https://flywaydb.org/[Flyway]
|
|
and http://www.liquibase.org/[Liquibase].
|
|
|
|
[[howto-execute-flyway-database-migrations-on-startup]]
|
|
==== Execute Flyway Database Migrations on Startup
|
|
To automatically run Flyway database migrations on startup, add the
|
|
`org.flywaydb:flyway-core` to your classpath.
|
|
|
|
The migrations are scripts in the form `V<VERSION>__<NAME>.sql` (with `<VERSION>` an
|
|
underscore-separated version, such as '`1`' or '`2_1`'). By default, they are in a folder
|
|
called `classpath:db/migration`, but you can modify that location by setting
|
|
`spring.flyway.locations`. You can also add a special `{vendor}` placeholder to use
|
|
vendor-specific scripts. Assume the following:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
spring.flyway.locations=db/migration/{vendor}
|
|
----
|
|
|
|
Rather than using `db/migration`, the preceding configuration sets the folder to use
|
|
according to the type of the database (such as `db/migration/mysql` for MySQL). The list
|
|
of supported databases is available in
|
|
{sc-spring-boot}/jdbc/DatabaseDriver.{sc-ext}[`DatabaseDriver`].
|
|
|
|
See the Flyway class from flyway-core for details of available settings such as schemas
|
|
and others. In addition, Spring Boot provides a small set of properties (in
|
|
{sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`])
|
|
that can be used to disable the migrations or switch off the location checking. Spring
|
|
Boot calls `Flyway.migrate()` to perform the database migration. If you would like
|
|
more control, provide a `@Bean` that implements
|
|
{sc-spring-boot-autoconfigure}/flyway/FlywayMigrationStrategy.{sc-ext}[`FlywayMigrationStrategy`].
|
|
|
|
Flyway supports SQL and Java https://flywaydb.org/documentation/callbacks.html[callbacks].
|
|
To use SQL-based callbacks, place the callback scripts in the `classpath:db/migration`
|
|
folder. To use Java-based callbacks, create one or more beans that implement
|
|
`FlywayCallback` or, preferably, extend `BaseFlywayCallback`. Any such beans are
|
|
automatically registered with `Flyway`. They can be ordered by using `@Order` or by
|
|
implementing `Ordered`.
|
|
|
|
By default, Flyway autowires the (`@Primary`) `DataSource` in your context and
|
|
uses that for migrations. If you like to use a different `DataSource`, you can create
|
|
one and mark its `@Bean` as `@FlywayDataSource`. If you do so and want two data sources,
|
|
remember to create another one and mark it as `@Primary`. Alternatively, you can use
|
|
Flyway's native `DataSource` by setting `spring.flyway.[url,user,password]`
|
|
in external properties. Setting either `spring.flyway.url` or `spring.flyway.user`
|
|
is sufficient to cause Flyway to use its own `DataSource`. If any of the three
|
|
properties has not be set, the value of its equivalent `spring.datasource` property will
|
|
be used.
|
|
|
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so
|
|
that you can see how to set things up.
|
|
|
|
You can also use Flyway to provide data for specific scenarios. For example, you can
|
|
place test-specific migrations in `src/test/resources` and they are run only when your
|
|
application starts for testing. Also, you can use profile-specific configuration to
|
|
customize `spring.flyway.locations` so that certain migrations run only when a particular
|
|
profile is active. For example, in `application-dev.properties`, you might specify the
|
|
following setting:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
|
|
----
|
|
|
|
With that setup, migrations in `dev/db/migration` run only when the `dev` profile is
|
|
active.
|
|
|
|
|
|
|
|
[[howto-execute-liquibase-database-migrations-on-startup]]
|
|
==== Execute Liquibase Database Migrations on Startup
|
|
To automatically run Liquibase database migrations on startup, add the
|
|
`org.liquibase:liquibase-core` to your classpath.
|
|
|
|
By default, the master change log is read from `db/changelog/db.changelog-master.yaml`,
|
|
but you can change the location by setting `spring.liquibase.change-log`. In addition to
|
|
YAML, Liquibase also supports JSON, XML, and SQL change log formats.
|
|
|
|
By default, Liquibase autowires the (`@Primary`) `DataSource` in your context and uses
|
|
that for migrations. If you need to use a different `DataSource`, you can create one and
|
|
mark its `@Bean` as `@LiquibaseDataSource`. If you do so and you want two data sources,
|
|
remember to create another one and mark it as `@Primary`. Alternatively, you can use
|
|
Liquibase's native `DataSource` by setting `spring.liquibase.[url,user,password]` in
|
|
external properties. Setting either `spring.liquibase.url` or `spring.liquibase.user`
|
|
is sufficient to cause Liquibase to use its own `DataSource`. If any of the three
|
|
properties has not be set, the value of its equivalent `spring.datasource` property will
|
|
be used.
|
|
|
|
See
|
|
{sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[`LiquibaseProperties`]
|
|
for details about available settings such as contexts, the default schema, and others.
|
|
|
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-liquibase[Liquibase
|
|
sample] so that you can see how to set things up.
|
|
|
|
|
|
|
|
[[howto-messaging]]
|
|
== Messaging
|
|
|
|
Spring Boot offers a number of starters that include messaging. This section answers
|
|
questions that arise from using messaging with Spring Boot.
|
|
|
|
[[howto-jms-disable-transaction]]
|
|
=== Disable Transacted JMS Session
|
|
If your JMS broker does not support transacted sessions, you have to disable the
|
|
support of transactions altogether. If you create your own `JmsListenerContainerFactory`,
|
|
there is nothing to do, since, by default it cannot be transacted. If you want to use
|
|
the `DefaultJmsListenerContainerFactoryConfigurer` to reuse Spring Boot's default, you
|
|
can disable transacted sessions, as follows:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
@Bean
|
|
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
|
|
ConnectionFactory connectionFactory,
|
|
DefaultJmsListenerContainerFactoryConfigurer configurer) {
|
|
DefaultJmsListenerContainerFactory listenerFactory =
|
|
new DefaultJmsListenerContainerFactory();
|
|
configurer.configure(listenerFactory, connectionFactory);
|
|
listenerFactory.setTransactionManager(null);
|
|
listenerFactory.setSessionTransacted(false);
|
|
return listenerFactory;
|
|
}
|
|
----
|
|
|
|
The preceding example overrides the default factory, and it should be applied to any
|
|
other factory that your application defines, if any.
|
|
|
|
|
|
|
|
[[howto-batch-applications]]
|
|
== Batch Applications
|
|
|
|
This section answers questions that arise from using Spring Batch with Spring Boot.
|
|
|
|
NOTE: By default, batch applications require a `DataSource` to store job details. If you
|
|
want to deviate from that, you need to implement `BatchConfigurer`. See
|
|
{spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[The
|
|
Javadoc of `@EnableBatchProcessing`] for more details.
|
|
|
|
For more about Spring Batch, see the https://projects.spring.io/spring-batch/[Spring Batch
|
|
project page].
|
|
|
|
|
|
|
|
[[howto-execute-spring-batch-jobs-on-startup]]
|
|
=== Execute Spring Batch Jobs on Startup
|
|
Spring Batch auto-configuration is enabled by adding `@EnableBatchProcessing`
|
|
(from Spring Batch) somewhere in your context.
|
|
|
|
By default, it executes *all* `Jobs` in the application context on startup (see
|
|
{sc-spring-boot-autoconfigure}/batch/JobLauncherCommandLineRunner.{sc-ext}[JobLauncherCommandLineRunner]
|
|
for details). You can narrow down to a specific job or jobs by specifying
|
|
`spring.batch.job.names` (which takes a comma-separated list of job name patterns).
|
|
|
|
If the application context includes a `JobRegistry`, the jobs in
|
|
`spring.batch.job.names` are looked up in the registry instead of being autowired from the
|
|
context. This is a common pattern with more complex systems, where multiple jobs are
|
|
defined in child contexts and registered centrally.
|
|
|
|
See
|
|
{sc-spring-boot-autoconfigure}/batch/BatchAutoConfiguration.{sc-ext}[BatchAutoConfiguration]
|
|
and
|
|
https://github.com/spring-projects/spring-batch/blob/master/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java[@EnableBatchProcessing]
|
|
for more details.
|
|
|
|
|
|
|
|
[[howto-actuator]]
|
|
== Actuator
|
|
|
|
Spring Boot includes the Spring Boot Actuator. This section answers questions that often
|
|
arise from its use.
|
|
|
|
[[howto-change-the-http-port-or-address-of-the-actuator-endpoints]]
|
|
=== Change the HTTP Port or Address of the Actuator Endpoints
|
|
In a standalone application, the Actuator HTTP port defaults to the same as the main HTTP
|
|
port. To make the application listen on a different port, set the external property:
|
|
`management.server.port`. To listen on a completely different network address (such as
|
|
when you have an internal network for management and an external one for user
|
|
applications), you can also set `management.server.address` to a valid IP address to which
|
|
the server is able to bind.
|
|
|
|
For more detail, see the
|
|
{sc-spring-boot-actuator-autoconfigure}/web/server/ManagementServerProperties.{sc-ext}[`ManagementServerProperties`]
|
|
source code and
|
|
"`<<production-ready-features.adoc#production-ready-customizing-management-server-port>>`"
|
|
in the "`Production-ready features`" section.
|
|
|
|
|
|
|
|
[[howto-customize-the-whitelabel-error-page]]
|
|
=== Customize the '`whitelabel`' Error Page
|
|
Spring Boot installs a '`whitelabel`' error page that you see in a browser client if
|
|
you encounter a server error (machine clients consuming JSON and other media types should
|
|
see a sensible response with the right error code).
|
|
|
|
NOTE: Set `server.error.whitelabel.enabled=false` to switch the default error page off.
|
|
Doing so restores the default of the servlet container that you are using. Note that
|
|
Spring Boot still tries to resolve the error view, so you should probably add your own
|
|
error page rather than disabling it completely.
|
|
|
|
Overriding the error page with your own depends on the templating technology that you
|
|
use. For example, if you use Thymeleaf, you can add an `error.html` template.
|
|
If you use FreeMarker, you can add an `error.ftl` template. In general, you
|
|
need a `View` that resolves with a name of `error` or a `@Controller` that handles
|
|
the `/error` path. Unless you replaced some of the default configuration, you should find
|
|
a `BeanNameViewResolver` in your `ApplicationContext`, so a `@Bean` named `error` would
|
|
be a simple way of doing that. See
|
|
{sc-spring-boot-autoconfigure}/web/servlet/error/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`]
|
|
for more options.
|
|
|
|
See also the section on "`<<boot-features-error-handling, Error Handling>>`" for details
|
|
of how to register handlers in the servlet container.
|
|
|
|
|
|
|
|
[[howto-security]]
|
|
== Security
|
|
|
|
This section addresses questions about security when working with Spring Boot, including
|
|
questions that arise from using Spring Security with Spring Boot.
|
|
|
|
For more about Spring Security, see the {spring-security}[Spring Security project page].
|
|
|
|
|
|
|
|
[[howto-switch-off-spring-boot-security-configuration]]
|
|
=== Switch off the Spring Boot Security Configuration
|
|
If you define a `@Configuration` with a `WebSecurityConfigurerAdapter` in your application,
|
|
it switches off the default webapp security settings in Spring Boot.
|
|
|
|
|
|
[[howto-change-the-authenticationmanager-and-add-user-accounts]]
|
|
=== Change the AuthenticationManager and Add User Accounts
|
|
If you provide a `@Bean` of type `AuthenticationManager`, `AuthenticationProvider`,
|
|
or `UserDetailsService`, the default `@Bean` for `InMemoryUserDetailsManager` is not
|
|
created, so you have the full feature set of Spring Security available (such as
|
|
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication[various
|
|
authentication options]).
|
|
|
|
The easiest way to add user accounts is to provide your own `UserDetailsService` bean.
|
|
|
|
|
|
|
|
[[howto-enable-https]]
|
|
=== Enable HTTPS When Running behind a Proxy Server
|
|
Ensuring that all your main endpoints are only available over HTTPS is an important
|
|
chore for any application. If you use Tomcat as a servlet container, then
|
|
Spring Boot adds Tomcat's own `RemoteIpValve` automatically if it detects some
|
|
environment settings, and you should be able to rely on the `HttpServletRequest` to
|
|
report whether it is secure or not (even downstream of a proxy server that handles the
|
|
real SSL termination). The standard behavior is determined by the presence or absence of
|
|
certain request headers (`x-forwarded-for` and `x-forwarded-proto`), whose names are
|
|
conventional, so it should work with most front-end proxies. You can switch on the valve
|
|
by adding some entries to `application.properties`, as shown in the following example:
|
|
|
|
[source,properties,indent=0]
|
|
----
|
|
server.tomcat.remote-ip-header=x-forwarded-for
|
|
server.tomcat.protocol-header=x-forwarded-proto
|
|
----
|
|
|
|
(The presence of either of those properties switches on the valve. Alternatively, you can
|
|
add the `RemoteIpValve` by adding a `TomcatServletWebServerFactory` bean.)
|
|
|
|
To configure Spring Security to require a secure channel for all (or some)
|
|
requests, consider adding your own `WebSecurityConfigurerAdapter` that adds the following
|
|
`HttpSecurity` configuration:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@Configuration
|
|
public class SslWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
|
|
|
|
@Override
|
|
protected void configure(HttpSecurity http) throws Exception {
|
|
// Customize the application security
|
|
http.requiresChannel().anyRequest().requiresSecure();
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
|
|
[[howto-hotswapping]]
|
|
== Hot Swapping
|
|
|
|
Spring Boot supports hot swapping. This section answers questions about how it works.
|
|
|
|
|
|
|
|
[[howto-reload-static-content]]
|
|
=== Reload Static Content
|
|
There are several options for hot reloading. The recommended approach is to use
|
|
<<using-spring-boot.adoc#using-boot-devtools,`spring-boot-devtools`>>, as it provides
|
|
additional development-time features, such as support for fast application restarts
|
|
and LiveReload as well as sensible development-time configuration (such as template
|
|
caching). Devtools works by monitoring the classpath for changes. This means that static
|
|
resource changes must be "built" for the change to take affect. By default, this happens
|
|
automatically in Eclipse when you save your changes. In IntelliJ IDEA, the Make Project
|
|
command triggers the necessary build. Due to the
|
|
<<using-spring-boot.adoc#using-boot-devtools-restart-exclude, default restart
|
|
exclusions>>, changes to static resources do not trigger a restart of your application.
|
|
They do, however, trigger a live reload.
|
|
|
|
Alternatively, running in an IDE (especially with debugging on) is a good way to do
|
|
development (all modern IDEs allow reloading of static resources and usually also allow
|
|
hot-swapping of Java class changes).
|
|
|
|
Finally, the <<build-tool-plugins.adoc#build-tool-plugins, Maven and Gradle plugins>> can
|
|
be configured (see the `addResources` property) to support running from the command line
|
|
with reloading of static files directly from source. You can use that with an external
|
|
css/js compiler process if you are writing that code with higher-level tools.
|
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-template-content]]
|
|
=== Reload Templates without Restarting the Container
|
|
Most of the templating technologies supported by Spring Boot include a configuration
|
|
option to disable caching (described later in this document). If you use the
|
|
`spring-boot-devtools` module, these properties are
|
|
<<using-spring-boot.adoc#using-boot-devtools-property-defaults,automatically configured>>
|
|
for you at development time.
|
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-content]]
|
|
==== Thymeleaf Templates
|
|
If you use Thymeleaf, set `spring.thymeleaf.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`]
|
|
for other Thymeleaf customization options.
|
|
|
|
|
|
|
|
[[howto-reload-freemarker-content]]
|
|
==== FreeMarker Templates
|
|
If you use FreeMarker, set `spring.freemarker.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`]
|
|
for other FreeMarker customization options.
|
|
|
|
|
|
|
|
[[howto-reload-groovy-template-content]]
|
|
==== Groovy Templates
|
|
If you use Groovy templates, set `spring.groovy.template.cache` to `false`. See
|
|
{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`]
|
|
for other Groovy customization options.
|
|
|
|
|
|
|
|
[[howto-reload-fast-restart]]
|
|
=== Fast Application Restarts
|
|
The `spring-boot-devtools` module includes support for automatic application restarts.
|
|
While not as fast as technologies such as
|
|
http://zeroturnaround.com/software/jrebel/[JRebel] it is usually significantly faster than
|
|
a "`cold start`". You should probably give it a try before investigating some of the more
|
|
complex reload options discussed later in this document.
|
|
|
|
For more details, see the <<using-spring-boot.adoc#using-boot-devtools>> section.
|
|
|
|
|
|
|
|
[[howto-reload-java-classes-without-restarting]]
|
|
=== Reload Java Classes without Restarting the Container
|
|
Many modern IDEs (Eclipse, IDEA, and others) support hot swapping of bytecode.
|
|
Consequently, if you make a change that does not affect class or method signatures, it
|
|
should reload cleanly with no side effects.
|
|
|
|
|
|
|
|
[[howto-build]]
|
|
== Build
|
|
|
|
Spring Boot includes build plugins for Maven and Gradle. This section answers common
|
|
questions about these plugins.
|
|
|
|
|
|
|
|
[[howto-build-info]]
|
|
=== Generate Build Information
|
|
Both the Maven plugin and the Gradle plugin allow generating build information containing
|
|
the coordinates, name, and version of the project. The plugins can also be configured
|
|
to add additional properties through configuration. When such a file is present,
|
|
Spring Boot auto-configures a `BuildProperties` bean.
|
|
|
|
To generate build information with Maven, add an execution for the `build-info` goal, as
|
|
shown in the following example:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<version>{spring-boot-version}</version>
|
|
<executions>
|
|
<execution>
|
|
<goals>
|
|
<goal>build-info</goal>
|
|
</goals>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
TIP: See the {spring-boot-maven-plugin-site}[Spring Boot Maven Plugin documentation]
|
|
for more details.
|
|
|
|
The following example does the same with Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
springBoot {
|
|
buildInfo()
|
|
}
|
|
----
|
|
|
|
TIP: See the
|
|
{spring-boot-gradle-plugin-reference}/#integrating-with-actuator-build-info[Spring Boot
|
|
Gradle Plugin documentation] for more details.
|
|
|
|
|
|
|
|
[[howto-git-info]]
|
|
=== Generate Git Information
|
|
|
|
Both Maven and Gradle allow generating a `git.properties` file containing information
|
|
about the state of your `git` source code repository when the project was built.
|
|
|
|
For Maven users, the `spring-boot-starter-parent` POM includes a pre-configured plugin to
|
|
generate a `git.properties` file. To use it, add the following declaration to your POM:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>pl.project13.maven</groupId>
|
|
<artifactId>git-commit-id-plugin</artifactId>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
Gradle users can achieve the same result by using the
|
|
https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties[`gradle-git-properties`]
|
|
plugin, as shown in the following example:
|
|
|
|
[source,groovy,indent=0]
|
|
----
|
|
plugins {
|
|
id "com.gorylenko.gradle-git-properties" version "1.4.17"
|
|
}
|
|
----
|
|
|
|
TIP: The commit time in `git.properties` is expected to match the following format:
|
|
`yyyy-MM-dd'T'HH:mm:ssZ`. This is the default format for both plugins listed above. Using
|
|
this format lets the time be parsed into a `Date` and its format, when serialized to JSON,
|
|
to be controlled by Jackson's date serialization configuration settings.
|
|
|
|
|
|
|
|
[[howto-customize-dependency-versions-with-maven]]
|
|
[[howto-customize-dependency-versions]]
|
|
=== Customize Dependency Versions
|
|
If you use a Maven build that inherits directly or indirectly from
|
|
`spring-boot-dependencies` (for instance, `spring-boot-starter-parent`) but you want to
|
|
override a specific third-party dependency, you can add appropriate `<properties>`
|
|
elements. Browse the
|
|
{github-code}/spring-boot-project/spring-boot-dependencies/pom.xml[`spring-boot-dependencies`]
|
|
POM for a complete list of properties. For example, to pick a different `slf4j` version,
|
|
you would add the following property:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<properties>
|
|
<slf4j.version>1.7.5<slf4j.version>
|
|
</properties>
|
|
----
|
|
|
|
NOTE: Doing so only works if your Maven project inherits (directly or indirectly) from
|
|
`spring-boot-dependencies`. If you have added `spring-boot-dependencies` in your
|
|
own `dependencyManagement` section with `<scope>import</scope>`, you have to redefine
|
|
the artifact yourself instead of overriding the property.
|
|
|
|
WARNING: Each Spring Boot release is designed and tested against this specific set of
|
|
third-party dependencies. Overriding versions may cause compatibility issues.
|
|
|
|
|
|
|
|
[[howto-create-an-executable-jar-with-maven]]
|
|
=== Create an Executable JAR with Maven
|
|
The `spring-boot-maven-plugin` can be used to create an executable "`fat`" JAR. If you
|
|
use the `spring-boot-starter-parent` POM, you can declare the plugin and your jars are
|
|
repackaged as follows:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
If you do not use the parent POM, you can still use the plugin. However, you must
|
|
additionally add an `<executions>` section, as follows:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<version>{spring-boot-version}</version>
|
|
<executions>
|
|
<execution>
|
|
<goals>
|
|
<goal>repackage</goal>
|
|
</goals>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
See the {spring-boot-maven-plugin-site}/usage.html[plugin documentation] for full usage
|
|
details.
|
|
|
|
|
|
[[howto-create-an-additional-executable-jar]]
|
|
=== Use a Spring Boot Application as a Dependency
|
|
Like a war file, a Spring Boot application is not intended to be used as a dependency. If
|
|
your application contains classes that you want to share with other projects, the
|
|
recommended approach is to move that code into a separate module. The separate module can
|
|
then be depended upon by your application and other projects.
|
|
|
|
If you cannot rearrange your code as recommended above, Spring Boot's Maven and Gradle
|
|
plugins must be configured to produce a separate artifact that is suitable for use as a
|
|
dependency. The executable archive cannot be used as a dependency as the
|
|
<<appendix-executable-jar-format.adoc#executable-jar-jar-file-structure,executable jar
|
|
format>> packages application classes in `BOOT-INF/classes`. This means
|
|
that they cannot be found when the executable jar is used as a dependency.
|
|
|
|
To produce the two artifacts, one that can be used as a dependency and one that is
|
|
executable, a classifier must be specified. This classifier is applied to the name of the
|
|
executable archive, leaving the default archive for use as a dependency.
|
|
|
|
To configure a classifier of `exec` in Maven, you can use the following configuration:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<configuration>
|
|
<classifier>exec</classifier>
|
|
</configuration>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
|
|
|
|
[[howto-extract-specific-libraries-when-an-executable-jar-runs]]
|
|
=== Extract Specific Libraries When an Executable Jar Runs
|
|
Most nested libraries in an executable jar do not need to be unpacked in order to run.
|
|
However, certain libraries can have problems. For example, JRuby includes its own nested
|
|
jar support, which assumes that the `jruby-complete.jar` is always directly available as a
|
|
file in its own right.
|
|
|
|
To deal with any problematic libraries, you can flag that specific nested jars should be
|
|
automatically unpacked to the "`temp folder`" when the executable jar first runs.
|
|
|
|
For example, to indicate that JRuby should be flagged for unpacking by using the Maven
|
|
Plugin, you would add the following configuration:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<configuration>
|
|
<requiresUnpack>
|
|
<dependency>
|
|
<groupId>org.jruby</groupId>
|
|
<artifactId>jruby-complete</artifactId>
|
|
</dependency>
|
|
</requiresUnpack>
|
|
</configuration>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
|
|
|
|
[[howto-create-a-nonexecutable-jar]]
|
|
=== Create a Non-executable JAR with Exclusions
|
|
Often, if you have an executable and a non-executable jar as two separate build products,
|
|
the executable version has additional configuration files that are not needed in a library
|
|
jar. For example, the `application.yml` configuration file might by excluded from the
|
|
non-executable JAR.
|
|
|
|
In Maven, the executable jar must be the main artifact and you can add a classified jar
|
|
for the library, as follows:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
</plugin>
|
|
<plugin>
|
|
<artifactId>maven-jar-plugin</artifactId>
|
|
<executions>
|
|
<execution>
|
|
<id>lib</id>
|
|
<phase>package</phase>
|
|
<goals>
|
|
<goal>jar</goal>
|
|
</goals>
|
|
<configuration>
|
|
<classifier>lib</classifier>
|
|
<excludes>
|
|
<exclude>application.yml</exclude>
|
|
</excludes>
|
|
</configuration>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
----
|
|
|
|
|
|
|
|
[[howto-remote-debug-maven-run]]
|
|
=== Remote Debug a Spring Boot Application Started with Maven
|
|
To attach a remote debugger to a Spring Boot application that was started with Maven, you
|
|
can use the `jvmArguments` property of the {spring-boot-maven-plugin-site}[maven plugin].
|
|
|
|
See {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for more
|
|
details.
|
|
|
|
|
|
|
|
[[howto-build-an-executable-archive-with-ant]]
|
|
=== Build an Executable Archive from Ant without Using `spring-boot-antlib`
|
|
To build with Ant, you need to grab dependencies, compile, and then create a jar or war
|
|
archive. To make it executable, you can either use the `spring-boot-antlib`
|
|
module or you can follow these instructions:
|
|
|
|
. If you are building a jar, package the application's classes and resources in a nested
|
|
`BOOT-INF/classes` directory. If you are building a war, package the application's
|
|
classes in a nested `WEB-INF/classes` directory as usual.
|
|
. Add the runtime dependencies in a nested `BOOT-INF/lib` directory for a jar or
|
|
`WEB-INF/lib` for a war. Remember *not* to compress the entries in the archive.
|
|
. Add the `provided` (embedded container) dependencies in a nested `BOOT-INF/lib`
|
|
directory for a jar or `WEB-INF/lib-provided` for a war. Remember *not* to compress the
|
|
entries in the archive.
|
|
. Add the `spring-boot-loader` classes at the root of the archive (so that the `Main-Class`
|
|
is available).
|
|
. Use the appropriate launcher (such as `JarLauncher` for a jar file) as a `Main-Class`
|
|
attribute in the manifest and specify the other properties it needs as manifest entries --
|
|
principally, by setting a `Start-Class` property.
|
|
|
|
The following example shows how to build an executable archive with Ant:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<target name="build" depends="compile">
|
|
<jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false">
|
|
<mappedresources>
|
|
<fileset dir="target/classes" />
|
|
<globmapper from="*" to="BOOT-INF/classes/*"/>
|
|
</mappedresources>
|
|
<mappedresources>
|
|
<fileset dir="src/main/resources" erroronmissingdir="false"/>
|
|
<globmapper from="*" to="BOOT-INF/classes/*"/>
|
|
</mappedresources>
|
|
<mappedresources>
|
|
<fileset dir="${lib.dir}/runtime" />
|
|
<globmapper from="*" to="BOOT-INF/lib/*"/>
|
|
</mappedresources>
|
|
<zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" />
|
|
<manifest>
|
|
<attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" />
|
|
<attribute name="Start-Class" value="${start-class}" />
|
|
</manifest>
|
|
</jar>
|
|
</target>
|
|
----
|
|
|
|
The {github-code}/spring-boot-samples/spring-boot-sample-ant[Ant Sample] has a
|
|
`build.xml` file with a `manual` task that should work if you run it with the following
|
|
command:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
$ ant -lib <folder containing ivy-2.2.jar> clean manual
|
|
----
|
|
|
|
Then you can run the application with the following command:
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
$ java -jar target/*.jar
|
|
----
|
|
|
|
|
|
|
|
[[howto-traditional-deployment]]
|
|
== Traditional Deployment
|
|
|
|
Spring Boot supports traditional deployment as well as more modern forms of deployment.
|
|
This section answers common questions about traditional deployment.
|
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file]]
|
|
=== Create a Deployable War File
|
|
|
|
The first step in producing a deployable war file is to provide a
|
|
`SpringBootServletInitializer` subclass and override its `configure` method. Doing so
|
|
makes use of Spring Framework's Servlet 3.0 support and lets you configure your
|
|
application when it is launched by the servlet container. Typically, you should update
|
|
your application's main class to extend `SpringBootServletInitializer`, as shown in the
|
|
following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@SpringBootApplication
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
@Override
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
|
return application.sources(Application.class);
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
SpringApplication.run(Application.class, args);
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
The next step is to update your build configuration such that your project produces a war
|
|
file rather than a jar file. If you use Maven and `spring-boot-starter-parent` (which
|
|
configures Maven's war plugin for you), all you need to do is to modify `pom.xml` to
|
|
change the packaging to war, as follows:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<packaging>war</packaging>
|
|
----
|
|
|
|
If you use Gradle, you need to modify `build.gradle` to apply the war plugin to the
|
|
project, as follows:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
apply plugin: 'war'
|
|
----
|
|
|
|
The final step in the process is to ensure that the embedded servlet container does not
|
|
interfere with the servlet container to which the war file is deployed. To do so, you
|
|
need to mark the embedded servlet container dependency as being provided.
|
|
|
|
If you use Maven, the following example marks the servlet container (Tomcat, in this
|
|
case) as being provided:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependencies>
|
|
<!-- … -->
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
<scope>provided</scope>
|
|
</dependency>
|
|
<!-- … -->
|
|
</dependencies>
|
|
----
|
|
|
|
If you use Gradle, the following example marks the servlet container (Tomcat, in this
|
|
case) as being provided:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
dependencies {
|
|
// …
|
|
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
|
|
// …
|
|
}
|
|
----
|
|
|
|
TIP: `providedRuntime` is preferred to Gradle's `compileOnly` configuration. Among other
|
|
limitations, `compileOnly` dependencies are not on the test classpath, so any web-based
|
|
integration tests fail.
|
|
|
|
If you use the <<build-tool-plugins.adoc#build-tool-plugins, Spring Boot build tools>>,
|
|
marking the embedded servlet container dependency as provided produces an executable war
|
|
file with the provided dependencies packaged in a `lib-provided` directory. This means
|
|
that, in addition to being deployable to a servlet container, you can also run your
|
|
application by using `java -jar` on the command line.
|
|
|
|
TIP: Take a look at Spring Boot's sample applications for a
|
|
{github-code}/spring-boot-samples/spring-boot-sample-traditional/pom.xml[Maven-based
|
|
example] of the previously described configuration.
|
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file-for-older-containers]]
|
|
=== Create a Deployable War File for Older Servlet Containers
|
|
Older Servlet containers do not have support for the `ServletContextInitializer` bootstrap
|
|
process used in Servlet 3.0. You can still use Spring and Spring Boot in these containers,
|
|
but you are going to need to add a `web.xml` to your application and configure it to load
|
|
an `ApplicationContext` via a `DispatcherServlet`.
|
|
|
|
|
|
|
|
[[howto-convert-an-existing-application-to-spring-boot]]
|
|
=== Convert an Existing Application to Spring Boot
|
|
For a non-web application, it should be easy to convert an existing Spring application to
|
|
a Spring Boot application. To do so, throw away the code that creates your
|
|
`ApplicationContext` and replace it with calls to `SpringApplication` or
|
|
`SpringApplicationBuilder`. Spring MVC web applications are generally amenable to first
|
|
creating a deployable war application and then migrating it later to an executable war
|
|
or jar. See the https://spring.io/guides/gs/convert-jar-to-war/[Getting
|
|
Started Guide on Converting a jar to a war].
|
|
|
|
To create a deployable war by extending `SpringBootServletInitializer` (for example, in a
|
|
class called `Application`) and adding the Spring Boot `@SpringBootApplication`
|
|
annotation, use code similar to that shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@SpringBootApplication
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
@Override
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
|
// Customize the application or call application.sources(...) to add sources
|
|
// Since our example is itself a @Configuration class (via @SpringBootApplication)
|
|
// we actually don't need to override this method.
|
|
return application;
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
Remember that, whatever you put in the `sources` is merely a Spring `ApplicationContext`.
|
|
Normally, anything that already works should work here. There might be some beans you can
|
|
remove later and let Spring Boot provide its own defaults for them, but it should be
|
|
possible to get something working before you need to do that.
|
|
|
|
Static resources can be moved to `/public` (or `/static` or `/resources` or
|
|
`/META-INF/resources`) in the classpath root. The same applies to `messages.properties`
|
|
(which Spring Boot automatically detects in the root of the classpath).
|
|
|
|
Vanilla usage of Spring `DispatcherServlet` and Spring Security should require no further
|
|
changes. If you have other features in your application (for instance, using other
|
|
servlets or filters), you may need to add some configuration to your `Application`
|
|
context, by replacing those elements from the `web.xml`, as follows:
|
|
|
|
* A `@Bean` of type `Servlet` or `ServletRegistrationBean` installs that bean in the
|
|
container as if it were a `<servlet/>` and `<servlet-mapping/>` in `web.xml`.
|
|
* A `@Bean` of type `Filter` or `FilterRegistrationBean` behaves similarly (as a
|
|
`<filter/>` and `<filter-mapping/>`).
|
|
* An `ApplicationContext` in an XML file can be added through an `@ImportResource` in
|
|
your `Application`. Alternatively, simple cases where annotation configuration is
|
|
heavily used already can be recreated in a few lines as `@Bean` definitions.
|
|
|
|
Once the war file is working, you can make it executable by adding a `main` method to
|
|
your `Application`, as shown in the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(Application.class, args);
|
|
}
|
|
----
|
|
|
|
[NOTE]
|
|
====
|
|
If you intend to start your application as a war or as an executable application, you
|
|
need to share the customizations of the builder in a method that is both available to the
|
|
`SpringBootServletInitializer` callback and in the `main` method in a class similar to the
|
|
following:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
@SpringBootApplication
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
@Override
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
|
return configureApplication(builder);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
configureApplication(new SpringApplicationBuilder()).run(args);
|
|
}
|
|
|
|
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
|
|
return builder.sources(Application.class).bannerMode(Banner.Mode.OFF);
|
|
}
|
|
|
|
}
|
|
----
|
|
====
|
|
|
|
Applications can fall into more than one category:
|
|
|
|
* Servlet 3.0+ applications with no `web.xml`.
|
|
* Applications with a `web.xml`.
|
|
* Applications with a context hierarchy.
|
|
* Applications without a context hierarchy.
|
|
|
|
All of these should be amenable to translation, but each might require slightly different
|
|
techniques.
|
|
|
|
Servlet 3.0+ applications might translate pretty easily if they already use the Spring
|
|
Servlet 3.0+ initializer support classes. Normally, all the code from an existing
|
|
`WebApplicationInitializer` can be moved into a `SpringBootServletInitializer`. If your
|
|
existing application has more than one `ApplicationContext` (for example, if it uses
|
|
`AbstractDispatcherServletInitializer`) then you might be able to combine all your context
|
|
sources into a single `SpringApplication`. The main complication you might encounter is if
|
|
combining does not work and you need to maintain the context hierarchy. See the
|
|
<<howto-build-an-application-context-hierarchy, entry on building a hierarchy>> for
|
|
examples. An existing parent context that contains web-specific features usually
|
|
needs to be broken up so that all the `ServletContextAware` components are in the child
|
|
context.
|
|
|
|
Applications that are not already Spring applications might be convertible to Spring
|
|
Boot applications, and the previously mentioned guidance may help. However, you may yet
|
|
encounter problems. In that case, we suggest
|
|
https://stackoverflow.com/questions/tagged/spring-boot[asking questions on Stack Overflow
|
|
with a tag of `spring-boot`].
|
|
|
|
|
|
|
|
[[howto-weblogic]]
|
|
=== Deploying a WAR to WebLogic
|
|
To deploy a Spring Boot application to WebLogic, you must ensure that your servlet
|
|
initializer *directly* implements `WebApplicationInitializer` (even if you extend from a
|
|
base class that already implements it).
|
|
|
|
A typical initializer for WebLogic should resemble the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
|
import org.springframework.web.WebApplicationInitializer;
|
|
|
|
@SpringBootApplication
|
|
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
|
|
|
|
}
|
|
----
|
|
|
|
If you use Logback, you also need to tell WebLogic to prefer the packaged version
|
|
rather than the version that was pre-installed with the server. You can do so by adding a
|
|
`WEB-INF/weblogic.xml` file with the following contents:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<wls:weblogic-web-app
|
|
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
|
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
|
|
http://xmlns.oracle.com/weblogic/weblogic-web-app
|
|
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
|
|
<wls:container-descriptor>
|
|
<wls:prefer-application-packages>
|
|
<wls:package-name>org.slf4j</wls:package-name>
|
|
</wls:prefer-application-packages>
|
|
</wls:container-descriptor>
|
|
</wls:weblogic-web-app>
|
|
----
|
|
|
|
|
|
|
|
[[howto-servlet-2-5]]
|
|
=== Deploying a WAR in an Old (Servlet 2.5) Container
|
|
Spring Boot uses Servlet 3.0 APIs to initialize the `ServletContext` (register `Servlets`
|
|
and so on), so you cannot use the same application in a Servlet 2.5 container.
|
|
It *is*, however, possible to run a Spring Boot application on an older container with some
|
|
special tools. If you include `org.springframework.boot:spring-boot-legacy` as a
|
|
dependency (https://github.com/scratches/spring-boot-legacy[maintained separately] to the
|
|
core of Spring Boot and currently available at 1.1.0.RELEASE), all you need to do
|
|
is create a `web.xml` and declare a context listener to create the application context and
|
|
your filters and servlets. The context listener is a special purpose one for Spring Boot,
|
|
but the rest of it is normal for a Spring application in Servlet 2.5. The following Maven
|
|
example shows how to set up a Spring Boot project to run in a Servlet 2.5 container:
|
|
|
|
[source,xml,indent=0]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
|
|
|
<context-param>
|
|
<param-name>contextConfigLocation</param-name>
|
|
<param-value>demo.Application</param-value>
|
|
</context-param>
|
|
|
|
<listener>
|
|
<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
|
|
</listener>
|
|
|
|
<filter>
|
|
<filter-name>metricsFilter</filter-name>
|
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
|
</filter>
|
|
|
|
<filter-mapping>
|
|
<filter-name>metricsFilter</filter-name>
|
|
<url-pattern>/*</url-pattern>
|
|
</filter-mapping>
|
|
|
|
<servlet>
|
|
<servlet-name>appServlet</servlet-name>
|
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
|
<init-param>
|
|
<param-name>contextAttribute</param-name>
|
|
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
|
|
</init-param>
|
|
<load-on-startup>1</load-on-startup>
|
|
</servlet>
|
|
|
|
<servlet-mapping>
|
|
<servlet-name>appServlet</servlet-name>
|
|
<url-pattern>/</url-pattern>
|
|
</servlet-mapping>
|
|
|
|
</web-app>
|
|
----
|
|
|
|
In the preceding example, we use a single application context (the one created by the
|
|
context listener) and attach it to the `DispatcherServlet` by using an `init` parameter.
|
|
This is normal in a Spring Boot application (you normally only have one application
|
|
context).
|
|
|
|
|
|
|
|
[[howto-use-jedis-instead-of-lettuce]]
|
|
=== Use Jedis Instead of Lettuce
|
|
By default, the Spring Boot starter (`spring-boot-starter-data-redis`) uses
|
|
https://github.com/lettuce-io/lettuce-core/[Lettuce]. You need to exclude that
|
|
dependency and include the https://github.com/xetorthio/jedis/[Jedis] one instead. Spring
|
|
Boot manages these dependencies to help make this process as easy as possible.
|
|
|
|
The following example shows how to do so in Maven:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>io.lettuce</groupId>
|
|
<artifactId>lettuce-core</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>redis.clients</groupId>
|
|
<artifactId>jedis</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
The following example shows how to do so in Gradle:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
----
|
|
configurations {
|
|
compile.exclude module: "lettuce"
|
|
}
|
|
|
|
dependencies {
|
|
compile("redis.clients:jedis")
|
|
// ...
|
|
}
|
|
----
|