2014-03-14 04:18:47 +08:00
|
|
|
[[howto]]
|
2014-10-10 02:06:46 +08:00
|
|
|
= '`How-to`' guides
|
2014-03-14 04:18:47 +08:00
|
|
|
|
|
|
|
[partintro]
|
|
|
|
--
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:18:47 +08:00
|
|
|
does cover quite a lot.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you have a specific problem that we do not cover here, you might want to check out
|
2014-03-14 04:18:47 +08:00
|
|
|
http://stackoverflow.com/tags/spring-boot[stackoverflow.com] to see if someone has
|
2017-11-01 05:51:10 +08:00
|
|
|
already provided an answer. This is also a great place to ask new questions (please use
|
2014-03-14 04:18:47 +08:00
|
|
|
the `spring-boot` tag).
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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].
|
2014-03-14 04:18:47 +08:00
|
|
|
--
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-spring-boot-application]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== Spring Boot Application
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2016-09-02 19:11:50 +08:00
|
|
|
[[howto-failure-analyzer]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create Your Own FailureAnalyzer
|
2016-10-02 13:00:47 +08:00
|
|
|
{dc-spring-boot}/diagnostics/FailureAnalyzer.{dc-ext}[`FailureAnalyzer`] is a great way
|
2016-09-02 19:11:50 +08:00
|
|
|
to intercept an exception on startup and turn it into a human-readable message, wrapped
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2016-09-02 19:11:50 +08:00
|
|
|
|
|
|
|
`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
|
2017-11-01 05:51:10 +08:00
|
|
|
actually present. If, for whatever reason, you cannot handle the exception, return `null`
|
2016-10-02 13:00:47 +08:00
|
|
|
to give another implementation a chance to handle the exception.
|
2016-09-02 19:11:50 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
`FailureAnalyzer` implementations must be registered in `META-INF/spring.factories`.
|
|
|
|
The following example registers `ProjectConstraintViolationFailureAnalyzer`:
|
2016-09-02 19:11:50 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
|
|
|
com.example.ProjectConstraintViolationFailureAnalyzer
|
|
|
|
----
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-troubleshoot-auto-configuration]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Troubleshoot Auto-configuration
|
2014-10-10 02:06:46 +08:00
|
|
|
The Spring Boot auto-configuration tries its best to '`do the right thing`', but
|
2017-11-01 05:51:10 +08:00
|
|
|
sometimes things fail, and it can be hard to tell why.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-02-18 21:47:20 +08:00
|
|
|
There is a really useful `ConditionEvaluationReport` available in any Spring Boot
|
2017-11-01 05:51:10 +08:00
|
|
|
`ApplicationContext`. You can see it if you enable `DEBUG` logging output. If you use
|
|
|
|
the `spring-boot-actuator`, there is also an `autoconfig` endpoint that renders the report
|
|
|
|
in JSON. Use that endpoint to debug the application and see what features have been added (and
|
2014-03-14 04:28:16 +08:00
|
|
|
which not) by Spring Boot at runtime.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
* Look for classes called `+*AutoConfiguration+` and read their sources. Pay special attention to the
|
2014-10-10 03:40:34 +08:00
|
|
|
`+@Conditional*+` annotations to find out what features they enable and when. Add
|
2014-03-14 04:28:16 +08:00
|
|
|
`--debug` to the command line or a System property `-Ddebug` to get a log on the
|
2015-10-27 12:21:26 +08:00
|
|
|
console of all the auto-configuration decisions that were made in your app. In a running
|
2017-11-01 05:51:10 +08:00
|
|
|
Actuator app, look at the `autoconfig` endpoint (`/application/autoconfig` or the JMX
|
2017-07-12 16:08:43 +08:00
|
|
|
equivalent) for the same information.
|
2017-11-01 05:51:10 +08:00
|
|
|
* Look for classes that are `@ConfigurationProperties` (such as
|
2014-04-16 17:48:36 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`])
|
2014-03-14 04:28:16 +08:00
|
|
|
and read from there the available external configuration options. The
|
2017-11-01 05:51:10 +08:00
|
|
|
`@ConfigurationProperties` 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
|
2014-03-14 04:28:16 +08:00
|
|
|
`configprops` endpoint.
|
2017-07-15 03:03:11 +08:00
|
|
|
* Look for uses of the `bind` method on the `Binder` to pull configuration values explicitly out of the
|
2017-08-22 17:28:14 +08:00
|
|
|
`Environment` in a relaxed manner. It is often used with a prefix.
|
2017-07-15 03:03:11 +08:00
|
|
|
* Look for `@Value` annotations that bind directly to the `Environment`.
|
2014-03-14 04:28:16 +08:00
|
|
|
* Look for `@ConditionalOnExpression` annotations that switch features on and off in
|
2015-11-11 20:45:43 +08:00
|
|
|
response to SpEL expressions, normally evaluated with placeholders resolved from the
|
2014-03-14 04:28:16 +08:00
|
|
|
`Environment`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-customize-the-environment-or-application-context]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Customize the Environment or ApplicationContext Before It Starts
|
2014-03-14 04:28:16 +08:00
|
|
|
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 ones:
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
* Programmatically, per application, by calling the `addListeners` and `addInitializers`
|
2014-03-14 04:28:16 +08:00
|
|
|
methods on `SpringApplication` before you run it.
|
2017-11-01 05:51:10 +08:00
|
|
|
* 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
|
2014-03-14 04:28:16 +08:00
|
|
|
a jar file that the applications all use as a library.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The `SpringApplication` sends some special `ApplicationEvents` to the listeners (some
|
|
|
|
even before the context is created) and then registers the listeners for events published
|
2014-03-14 04:28:16 +08:00
|
|
|
by the `ApplicationContext` as well. See
|
2017-11-01 05:51:10 +08:00
|
|
|
"`<<spring-boot-features.adoc#boot-features-application-events-and-listeners>>`" in the
|
2014-10-10 02:06:46 +08:00
|
|
|
'`Spring Boot features`' section for a complete list.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-06-20 21:29:38 +08:00
|
|
|
It is also possible to customize the `Environment` before the application context is
|
2017-11-01 05:51:10 +08:00
|
|
|
refreshed by using `EnvironmentPostProcessor`. Each implementation should be registered in
|
|
|
|
`META-INF/spring.factories`, as shown in the following example:
|
2016-06-20 21:29:38 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
|
|
|
|
----
|
|
|
|
|
2017-06-27 22:49:14 +08:00
|
|
|
The implementation can load arbitrary files and add them to the `Environment`. For
|
2017-11-01 05:51:10 +08:00
|
|
|
instance, the following example loads a YAML configuration file from the classpath:
|
2017-06-27 22:49:14 +08:00
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
----
|
|
|
|
include::{code-examples}/context/EnvironmentPostProcessorExample.java[tag=example]
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
TIP: The `Environment` has already been prepared with all the usual property sources
|
2017-06-27 22:49:14 +08:00
|
|
|
that Spring Boot loads by default. It is therefore possible to get the location of the
|
|
|
|
file from the environment. This 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
|
2017-11-01 05:51:10 +08:00
|
|
|
precedence. A custom implementation may define another order.
|
2017-06-27 22:49:14 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
CAUTION: While using `@PropertySource` on your `@SpringBootApplication` may seem convenient and
|
2017-06-27 22:49:14 +08:00
|
|
|
easy enough to load a custom resource in the `Environment`, we do not recommend it as
|
|
|
|
Spring Boot prepares the `Environment` before the `ApplicationContext` is refreshed. Any
|
2017-11-01 05:51:10 +08:00
|
|
|
key defined via `@PropertySource` is loaded too late to have any effect on
|
2017-06-27 22:49:14 +08:00
|
|
|
auto-configuration.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2017-07-07 07:52:53 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-build-an-application-context-hierarchy]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)
|
2014-03-14 04:28:16 +08:00
|
|
|
You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext`
|
2017-11-01 05:51:10 +08:00
|
|
|
hierarchies. See "`<<spring-boot-features.adoc#boot-features-fluent-builder-api>>`"
|
2014-10-10 02:06:46 +08:00
|
|
|
in the '`Spring Boot features`' section for more information.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-create-a-non-web-application]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create a Non-web Application
|
2014-03-14 04:28:16 +08:00
|
|
|
Not all Spring applications have to be web applications (or web services). If you want to
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2015-11-30 22:08:40 +08:00
|
|
|
`applicationContextClass` property (through the Java API or with external properties).
|
2014-03-14 04:28:16 +08:00
|
|
|
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]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== Properties and Configuration
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-03-24 19:55:56 +08:00
|
|
|
[[howto-automatic-expansion]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Automatically Expand Properties at Build Time
|
2016-03-24 19:55:56 +08:00
|
|
|
Rather than hardcoding some properties that are also specified in your project's build
|
2017-11-01 05:51:10 +08:00
|
|
|
configuration, you can automatically expand them by instead using the existing build
|
|
|
|
configuration. This is possible in both Maven and Gradle.
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-automatic-expansion-maven]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== 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:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
app.encoding=@project.build.sourceEncoding@
|
|
|
|
app.java.version=@java.version@
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: Only production configuration is filtered that way (in other words, no filtering is
|
|
|
|
applied on `src/test/resources`).
|
2017-08-29 16:14:13 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2016-03-24 19:55:56 +08:00
|
|
|
{spring-boot-maven-plugin-site}/usage.html[plugin usage page] for more details.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you do not use the starter parent, you need to include the following element inside
|
|
|
|
the `<build/>` element of your `pom.xml`:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0]
|
|
|
|
----
|
2017-01-04 08:59:53 +08:00
|
|
|
<resources>
|
|
|
|
<resource>
|
|
|
|
<directory>src/main/resources</directory>
|
|
|
|
<filtering>true</filtering>
|
|
|
|
</resource>
|
|
|
|
</resources>
|
2016-03-24 19:55:56 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You also need to incude the following element inside `<plugins/>`:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-automatic-expansion-gradle]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Automatic Property Expansion Using Gradle
|
2016-03-24 19:55:56 +08:00
|
|
|
You can automatically expand properties from the Gradle project by configuring the
|
2017-11-01 05:51:10 +08:00
|
|
|
Java plugin's `processResources` task to do so, as shown in the following example:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0]
|
|
|
|
----
|
|
|
|
processResources {
|
|
|
|
expand(project.properties)
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can then refer to your Gradle project's properties via placeholders, as shown in the
|
|
|
|
following example:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
app.name=${name}
|
|
|
|
app.description=${description}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: Gradle's `expand` method uses Groovy's `SimpleTemplateEngine`, which transforms
|
2016-03-24 19:55:56 +08:00
|
|
|
`${..}` tokens. The `${..}` style conflicts with Spring's own property placeholder
|
2017-11-01 05:51:10 +08:00
|
|
|
mechanism. To use Spring property placeholders together with automatic expansion, escape
|
|
|
|
the Spring property placeholders as follows: `\${..}`.
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-externalize-configuration]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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 using properties in `+spring.main.*+`. For example, in `application.properties`, you
|
|
|
|
might have the following settings:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-03-17 15:04:57 +08:00
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
2016-04-08 14:10:48 +08:00
|
|
|
spring.main.web-environment=false
|
|
|
|
spring.main.banner-mode=off
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Then the Spring Boot banner is not printed on startup, and the application is
|
|
|
|
not a web application.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: The preceding example also demonstrates how flexible binding allows the use of
|
2014-03-19 02:26:15 +08:00
|
|
|
underscores (`_`) as well as dashes (`-`) in property names.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Properties defined in external configuration overrides the values specified with the Java
|
|
|
|
API, with the notable exception of the sources used to create the `ApplicationContext`.
|
|
|
|
Consider the following application:
|
2015-05-27 17:11:19 +08:00
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
----
|
|
|
|
new SpringApplicationBuilder()
|
2015-10-08 17:44:16 +08:00
|
|
|
.bannerMode(Banner.Mode.OFF)
|
2015-05-27 17:11:19 +08:00
|
|
|
.sources(demo.MyApp.class)
|
|
|
|
.run(args);
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Now consider the following configuration:
|
2015-05-27 17:11:19 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
spring.main.sources=com.acme.Config,com.acme.ExtraConfig
|
2016-04-08 14:10:48 +08:00
|
|
|
spring.main.banner-mode=console
|
2015-05-27 17:11:19 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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`, `com.acme.ExtraConfig`.
|
2015-05-27 17:11:19 +08:00
|
|
|
|
2015-06-04 02:57:28 +08:00
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-change-the-location-of-external-properties]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2014-10-10 02:06:46 +08:00
|
|
|
the '`Spring Boot features`' section for the exact order).
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
A nice way to augment and modify this ordering is to add `@PropertySource` annotations to your
|
2014-03-14 04:28:16 +08:00
|
|
|
application sources. Classes passed to the `SpringApplication` static convenience
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
enough to be used in all phases of the `ApplicationContext` lifecycle. Properties added
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can also provide the following System properties (or environment variables) to change
|
|
|
|
the behavior:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
* `spring.config.name` (`SPRING_CONFIG_NAME`): Defaults to `application` as the root of
|
2014-03-14 04:28:16 +08:00
|
|
|
the file name.
|
2017-11-01 05:51:10 +08:00
|
|
|
* `spring.config.location` (`SPRING_CONFIG_LOCATION`): The file to load (such as a classpath
|
2014-03-14 04:28:16 +08:00
|
|
|
resource or a URL). A separate `Environment` property source is set up for this document
|
2017-11-01 05:51:10 +08:00
|
|
|
and it can be overridden by system properties, environment variables, or the
|
2014-03-14 04:28:16 +08:00
|
|
|
command line.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot logs the configuration files that are loaded at the `DEBUG` level and the
|
2015-07-07 00:05:36 +08:00
|
|
|
candidates it has not found at `TRACE` level.
|
|
|
|
|
2015-10-29 03:07:45 +08:00
|
|
|
See {sc-spring-boot}/context/config/ConfigFileApplicationListener.{sc-ext}[`ConfigFileApplicationListener`]
|
2014-03-14 04:28:16 +08:00
|
|
|
for more detail.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-use-short-command-line-arguments]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Use '`Short`' Command Line Arguments
|
2014-03-14 04:28:16 +08:00
|
|
|
Some people like to use (for example) `--port=9000` instead of `--server.port=9000` to
|
2017-11-01 05:51:10 +08:00
|
|
|
set configuration properties on the command line. You can enable this behavior by using
|
|
|
|
placeholders in `application.properties`, as shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-03-17 15:04:57 +08:00
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
2014-03-17 15:04:57 +08:00
|
|
|
server.port=${port:8080}
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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,
|
2014-11-04 18:29:55 +08:00
|
|
|
`@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
|
2014-03-19 02:35:11 +08:00
|
|
|
http://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#delimiters[other delimiters].
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
automatically and Spring can bind to capitalized synonyms for `Environment` properties.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-use-yaml-for-external-properties]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[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
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
included if you use the `spring-boot-starter`). A YAML file is parsed to a Java
|
2014-03-18 22:34:06 +08:00
|
|
|
`Map<String,Object>` (like a JSON object), and Spring Boot flattens the map so that it
|
2017-11-01 05:51:10 +08:00
|
|
|
is one level deep and has period-separated keys, as many people are used to with
|
2014-03-14 04:28:16 +08:00
|
|
|
`Properties` files in Java.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The example YAML above corresponds to an `application.properties` file as follows:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-03-17 15:04:57 +08:00
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
2014-03-17 15:04:57 +08:00
|
|
|
spring.application.name=cruncher
|
|
|
|
spring.datasource.driverClassName=com.mysql.jdbc.Driver
|
|
|
|
spring.datasource.url=jdbc:mysql://localhost/test
|
|
|
|
server.port=9000
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
See "`<<spring-boot-features.adoc#boot-features-external-config-yaml>>`" in
|
2014-10-10 02:06:46 +08:00
|
|
|
the '`Spring Boot features`' section for more information
|
2014-03-14 04:28:16 +08:00
|
|
|
about YAML.
|
|
|
|
|
|
|
|
[[howto-set-active-spring-profiles]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
In Spring Boot, you can also set the active profile in `application.properties`, as shown
|
|
|
|
in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-03-17 15:04:57 +08:00
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
spring.profiles.active=production
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
be used to augment the profiles without changing the defaults.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
See "`<<spring-boot-features.adoc#boot-features-profiles>>`" in
|
|
|
|
the "`Spring Boot features`" section for more information.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-change-configuration-depending-on-the-environment]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Change Configuration Depending on the Environment
|
2014-03-14 04:28:16 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
(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 not), as shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
server:
|
|
|
|
port: 9000
|
|
|
|
---
|
|
|
|
|
|
|
|
spring:
|
|
|
|
profiles: development
|
|
|
|
server:
|
|
|
|
port: 9001
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
spring:
|
|
|
|
profiles: production
|
|
|
|
server:
|
|
|
|
port: 0
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The YAML documents are merged in the order in which they are encountered (so later values
|
|
|
|
override earlier ones).
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
To do the same thing with properties files, you can use
|
|
|
|
`application-${profile}.properties` to specify profile-specific values.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-discover-build-in-options-for-external-properties]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Discover Built-in Options for External Properties
|
2014-03-14 04:28:16 +08:00
|
|
|
Spring Boot binds external properties from `application.properties` (or `.yml`) (and
|
2014-05-15 16:15:35 +08:00
|
|
|
other places) into an application at runtime. There is not (and technically cannot be)
|
2017-11-01 05:51:10 +08:00
|
|
|
an exhaustive list of all supported properties in a single location, because
|
|
|
|
contributions can come from additional jar files on your classpath.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
`@ConfigurationProperties` and `@Value` annotations as well as the occasional use of
|
2017-07-15 03:03:11 +08:00
|
|
|
`Binder`.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-07 22:55:25 +08:00
|
|
|
[[howto-embedded-web-servers]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== Embedded Web Servers
|
2017-07-07 22:55:25 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2017-07-07 22:55:25 +08:00
|
|
|
|
|
|
|
[[howto-use-another-web-server]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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` and `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`, and `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
|
2017-07-07 22:55:25 +08:00
|
|
|
HTTP servers to help make this process as easy as possible.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following Maven example shows how to exclude Tomcat and include Jetty for Spring MVC:
|
2017-07-07 22:55:25 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following Gradle example shows how to exclude Netty and include Undertow for Spring
|
|
|
|
WebFlux:
|
2017-07-07 22:55:25 +08:00
|
|
|
|
|
|
|
[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'
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2017-07-12 04:55:45 +08:00
|
|
|
|
|
|
|
|
2017-07-07 22:55:25 +08:00
|
|
|
|
|
|
|
[[howto-configure-jetty]]
|
|
|
|
=== Configure Jetty
|
2017-11-01 05:51:10 +08:00
|
|
|
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 `ServletWebServerFactoryCustomizer`. 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`.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-08-17 23:45:44 +08:00
|
|
|
[[howto-add-a-servlet-filter-or-listener]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Add a Servlet, Filter, or Listener to an Application
|
|
|
|
There are two ways to add `Servlet`, `Filter`, `ServletContextListener`, and the other
|
2015-08-17 23:45:44 +08:00
|
|
|
listeners supported by the Servlet spec to your application. You can either provide
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring beans for them or enable scanning for Servlet components.
|
2015-08-17 23:45:44 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-listener-as-spring-bean]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== 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
|
|
|
|
restrictions like that 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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-10-27 18:04:56 +08:00
|
|
|
[NOTE]
|
|
|
|
====
|
2017-11-01 05:51:10 +08:00
|
|
|
If no `dispatcherType` is specified on a filter registration, it matches
|
|
|
|
`FORWARD`,`INCLUDE`, and `REQUEST`. If async has been enabled, it also matches `ASYNC`.
|
2015-10-27 18:04:56 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you are migrating a filter that has no `dispatcher` element in `web.xml`, you
|
|
|
|
need to specify a `dispatcherType` yourself, as shown in the following example:
|
2015-10-27 18:04:56 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Bean
|
|
|
|
public FilterRegistrationBean myFilterRegistration() {
|
|
|
|
FilterRegistrationBean registration = new FilterRegistrationBean();
|
|
|
|
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
|
|
|
....
|
|
|
|
|
|
|
|
return registration;
|
|
|
|
}
|
|
|
|
----
|
|
|
|
====
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2015-02-11 21:15:52 +08:00
|
|
|
[[howto-disable-registration-of-a-servlet-or-filter]]
|
2017-11-01 05:51:10 +08:00
|
|
|
===== Disable Registration of a Servlet or Filter
|
|
|
|
As <<howto-add-a-servlet-filter-or-listener-as-spring-bean,described above>>, 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:
|
2015-02-11 21:15:52 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2015-02-26 00:23:18 +08:00
|
|
|
@Bean
|
2015-02-11 21:15:52 +08:00
|
|
|
public FilterRegistrationBean registration(MyFilter filter) {
|
|
|
|
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
|
|
|
|
registration.setEnabled(false);
|
|
|
|
return registration;
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
|
|
|
|
2015-11-04 12:36:20 +08:00
|
|
|
|
2015-08-17 23:45:44 +08:00
|
|
|
[[howto-add-a-servlet-filter-or-listener-using-scanning]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Add Servlets, Filters, and Listeners by Using Classpath Scanning
|
2015-08-17 23:45:44 +08:00
|
|
|
`@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
|
2017-11-01 05:51:10 +08:00
|
|
|
that you want to register. By default, `@ServletComponentScan` scans from the package
|
2015-08-17 23:45:44 +08:00
|
|
|
of the annotated class.
|
|
|
|
|
|
|
|
|
2015-02-11 21:15:52 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-change-the-http-port]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2014-03-14 04:28:16 +08:00
|
|
|
environment variable).
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
To switch off the HTTP endpoints completely but still create a `WebApplicationContext`,
|
|
|
|
use `server.port=-1`. (Doing so is sometimes useful for testing.)
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
For more details, see "`<<spring-boot-features.adoc#boot-features-customizing-embedded-containers>>`"
|
2014-10-09 17:24:30 +08:00
|
|
|
in the '`Spring Boot features`' section, or the
|
2014-03-14 04:28:16 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] source
|
|
|
|
code.
|
|
|
|
|
|
|
|
|
2016-03-09 03:20:41 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-user-a-random-unassigned-http-port]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Use a Random Unassigned HTTP Port
|
2014-03-14 04:28:16 +08:00
|
|
|
To scan for a free port (using OS natives to prevent clashes) use `server.port=0`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-discover-the-http-port-at-runtime]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Discover the HTTP Port at Runtime
|
2014-03-14 04:28:16 +08:00
|
|
|
You can access the port the server is running on from log output or from the
|
2017-11-01 05:51:10 +08:00
|
|
|
`ServletWebServerApplicationContext` through its `EmbeddedWebServer`. The best way to get
|
|
|
|
that and be sure that it has been initialized is to add a `@Bean` of type
|
2017-04-28 22:48:47 +08:00
|
|
|
`ApplicationListener<ServletWebServerInitializedEvent>` and pull the container
|
2014-03-18 22:34:06 +08:00
|
|
|
out of the event when it is published.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-04-05 12:25:01 +08:00
|
|
|
Tests that use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)` can
|
2017-11-01 05:51:10 +08:00
|
|
|
also inject the actual port into a field by using the `@LocalServerPort` annotation, as
|
|
|
|
shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-03-18 16:37:04 +08:00
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
2016-04-05 12:25:01 +08:00
|
|
|
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
|
2016-04-01 07:58:47 +08:00
|
|
|
public class MyWebIntegrationTests {
|
2014-03-18 16:37:04 +08:00
|
|
|
|
|
|
|
@Autowired
|
2017-04-28 22:48:47 +08:00
|
|
|
ServletWebServerApplicationContext server;
|
2014-04-23 16:42:10 +08:00
|
|
|
|
2016-03-14 21:19:55 +08:00
|
|
|
@LocalServerPort
|
2014-03-19 00:41:12 +08:00
|
|
|
int port;
|
2014-03-18 16:37:04 +08:00
|
|
|
|
|
|
|
// ...
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-09-08 20:04:39 +08:00
|
|
|
[NOTE]
|
|
|
|
====
|
2017-11-01 05:51:10 +08:00
|
|
|
`@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).
|
2015-09-08 20:04:39 +08:00
|
|
|
====
|
2014-07-30 04:06:47 +08:00
|
|
|
|
|
|
|
|
2015-09-09 04:37:28 +08:00
|
|
|
|
2014-07-23 00:51:51 +08:00
|
|
|
[[howto-configure-ssl]]
|
|
|
|
=== Configure SSL
|
2014-10-10 03:40:34 +08:00
|
|
|
SSL can be configured declaratively by setting the various `+server.ssl.*+` properties,
|
2017-11-01 05:51:10 +08:00
|
|
|
typically in `application.properties` or `application.yml`. The following example shows
|
|
|
|
setting SSL properties in `applicaiton.properties`:
|
2014-07-23 00:51:51 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2015-06-14 15:36:10 +08:00
|
|
|
server.port=8443
|
|
|
|
server.ssl.key-store=classpath:keystore.jks
|
|
|
|
server.ssl.key-store-password=secret
|
2015-07-02 20:51:43 +08:00
|
|
|
server.ssl.key-password=another-secret
|
2014-07-23 00:51:51 +08:00
|
|
|
----
|
|
|
|
|
2017-06-08 23:49:55 +08:00
|
|
|
See {sc-spring-boot}/web/server/Ssl.{sc-ext}[`Ssl`] for details of all of the
|
2014-07-23 00:51:51 +08:00
|
|
|
supported properties.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-12-16 20:48:43 +08:00
|
|
|
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.
|
2014-07-23 00:51:51 +08:00
|
|
|
|
2016-03-09 03:20:41 +08:00
|
|
|
|
|
|
|
|
2016-02-11 23:59:47 +08:00
|
|
|
[[howto-configure-accesslogs]]
|
|
|
|
=== Configure Access Logging
|
2017-11-01 05:51:10 +08:00
|
|
|
Access logs can be configured for Tomcat, Undertow, and Jetty through their respective
|
2017-04-27 16:41:39 +08:00
|
|
|
namespaces.
|
2016-02-11 23:59:47 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
For instance, the following settings log access on Tomcat with a
|
2017-04-28 03:03:44 +08:00
|
|
|
{tomcat-documentation}/config/valve.html#Access_Logging[custom pattern].
|
2016-02-11 23:59:47 +08:00
|
|
|
|
|
|
|
[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)
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2016-02-11 23:59:47 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Access logging for undertow can be configured in a similar fashion, as shown in the
|
|
|
|
following example:
|
2016-02-11 23:59:47 +08:00
|
|
|
|
|
|
|
[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
|
2017-11-01 05:51:10 +08:00
|
|
|
application. You can customize this location by setting the
|
|
|
|
`server.undertow.accesslog.directory` property.
|
2014-04-23 16:42:10 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Finally, access logging for Jetty can also be configured as follows:
|
2017-04-05 19:33:12 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
server.jetty.accesslog.enabled=true
|
2017-04-27 20:19:16 +08:00
|
|
|
server.jetty.accesslog.filename=/var/log/jetty-access.log
|
2017-04-05 19:33:12 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
By default, logs are redirected to `System.err`. For more details, see
|
2017-04-28 03:03:44 +08:00
|
|
|
{jetty-documentation}/configuring-jetty-request-logs.html[the documentation].
|
2017-04-27 16:41:39 +08:00
|
|
|
|
2014-04-23 16:42:10 +08:00
|
|
|
|
2016-03-09 03:20:41 +08:00
|
|
|
|
2015-10-02 14:57:14 +08:00
|
|
|
[[howto-use-behind-a-proxy-server]]
|
|
|
|
[[howto-use-tomcat-behind-a-proxy-server]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Running Behind a Front-end Proxy Server
|
2015-10-02 14:57:14 +08:00
|
|
|
Your application might need to send `302` redirects or render content with absolute links
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2015-10-02 14:57:14 +08:00
|
|
|
construct links to itself.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If the proxy adds conventional `X-Forwarded-For` and `X-Forwarded-Proto` headers (most
|
|
|
|
proxy server do so), the absolute links should be rendered correctly, provided
|
2015-10-02 14:57:14 +08:00
|
|
|
`server.use-forward-headers` is set to `true` in your `application.properties`.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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`.
|
2015-10-02 14:57:14 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-customize-tomcat-behind-a-proxy-server]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== 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:
|
2015-10-02 14:57:14 +08:00
|
|
|
|
|
|
|
[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
|
2017-11-01 05:51:10 +08:00
|
|
|
adding an entry to `application.properties`, as shown in the following example:
|
2015-10-02 14:57:14 +08:00
|
|
|
|
|
|
|
[indent=0]
|
|
|
|
----
|
|
|
|
server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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}`.
|
2015-10-02 14:57:14 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but do not do
|
|
|
|
so in production).
|
2015-10-02 14:57:14 +08:00
|
|
|
|
|
|
|
You can take complete control of the configuration of Tomcat's `RemoteIpValve` by
|
2017-11-01 05:51:10 +08:00
|
|
|
switching the automatic one off (to do so, set `server.use-forward-headers=false`) and adding
|
|
|
|
a new valve instance in a `TomcatServletWebServerFactory` bean.
|
2015-10-02 14:57:14 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-configure-tomcat]]
|
|
|
|
=== Configure Tomcat
|
2017-11-01 05:51:10 +08:00
|
|
|
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 `ServletWebServerFactoryCustomizer` and various Tomcat-specific
|
|
|
|
`+*Customizers+` that you can add. The Tomcat APIs are quite rich, so, 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`.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-20 11:11:46 +08:00
|
|
|
[[howto-enable-multiple-connectors-in-tomcat]]
|
2014-10-13 03:47:19 +08:00
|
|
|
=== Enable Multiple Connectors with Tomcat
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-20 11:11:46 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Bean
|
2017-04-28 22:48:47 +08:00
|
|
|
public ServletWebServerFactory servletContainer() {
|
|
|
|
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
|
2014-03-20 11:11:46 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
----
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2014-04-24 06:24:59 +08:00
|
|
|
|
2016-09-15 11:18:49 +08:00
|
|
|
[[howto-use-tomcat-legacycookieprocessor]]
|
|
|
|
=== Use Tomcat's LegacyCookieProcessor
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2016-09-15 11:18:49 +08:00
|
|
|
|
|
|
|
[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
|
2017-11-01 05:51:10 +08:00
|
|
|
compliant with later Cookie specifications. If, however, you cannot change the
|
2016-09-15 11:18:49 +08:00
|
|
|
way that cookies are written, you can instead configure Tomcat to use a
|
2017-11-01 05:51:10 +08:00
|
|
|
`LegacyCookieProcessor`. To switch to the `LegacyCookieProcessor`, use an
|
|
|
|
`ServletWebServerFactoryCustomizer` bean that adds a `TomcatContextCustomizer`, as shown
|
|
|
|
in the following example:
|
2016-09-15 11:18:49 +08:00
|
|
|
|
2016-09-15 21:53:14 +08:00
|
|
|
[source,java,indent=0]
|
|
|
|
----
|
|
|
|
include::{code-examples}/context/embedded/TomcatLegacyCookieProcessorExample.java[tag=customizer]
|
2016-09-15 11:18:49 +08:00
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-11-19 05:00:28 +08:00
|
|
|
[[howto-configure-undertow]]
|
|
|
|
=== Configure Undertow
|
|
|
|
Generally you can follow the advice from
|
2017-11-01 05:51:10 +08:00
|
|
|
"`<<howto-discover-build-in-options-for-external-properties>>`" about
|
2014-11-26 18:55:33 +08:00
|
|
|
`@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow` are the
|
2017-11-01 05:51:10 +08:00
|
|
|
main ones here). However, you should also look at `ServletWebServerFactoryCustomizer`.
|
|
|
|
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`.
|
2014-11-19 05:00:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-01-08 02:04:50 +08:00
|
|
|
[[howto-enable-multiple-listeners-in-undertow]]
|
|
|
|
=== Enable Multiple Listeners with Undertow
|
2017-04-28 22:48:47 +08:00
|
|
|
Add an `UndertowBuilderCustomizer` to the `UndertowServletWebServerFactory` and
|
2017-11-01 05:51:10 +08:00
|
|
|
add a listener to the `Builder`, as shown in the following example:
|
2015-01-08 02:04:50 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Bean
|
2017-04-28 22:48:47 +08:00
|
|
|
public UndertowServletWebServerFactory servletWebServerFactory() {
|
|
|
|
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
|
2015-01-08 02:04:50 +08:00
|
|
|
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void customize(Builder builder) {
|
|
|
|
builder.addHttpListener(8080, "0.0.0.0");
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
return factory;
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-21 23:02:48 +08:00
|
|
|
[[howto-create-websocket-endpoints-using-serverendpoint]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create WebSocket Endpoints Using @ServerEndpoint
|
2014-10-21 23:02:48 +08:00
|
|
|
If you want to use `@ServerEndpoint` in a Spring Boot application that used an embedded
|
2017-11-01 05:51:10 +08:00
|
|
|
container, you must declare a single `ServerEndpointExporter` `@Bean`, as shown in the
|
|
|
|
following example:
|
2014-10-21 23:02:48 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Bean
|
|
|
|
public ServerEndpointExporter serverEndpointExporter() {
|
|
|
|
return new ServerEndpointExporter();
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-10-21 23:02:48 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-01-16 19:09:52 +08:00
|
|
|
[[how-to-enable-http-response-compression]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Enable HTTP Response Compression
|
2015-06-29 21:50:48 +08:00
|
|
|
HTTP response compression is supported by Jetty, Tomcat, and Undertow. It can be enabled
|
2017-11-01 05:51:10 +08:00
|
|
|
in `application.properties`, as follows:
|
2015-01-16 19:09:52 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2015-06-29 21:50:48 +08:00
|
|
|
server.compression.enabled=true
|
2015-01-16 19:09:52 +08:00
|
|
|
----
|
|
|
|
|
2015-06-29 21:50:48 +08:00
|
|
|
By default, responses must be at least 2048 bytes in length for compression to be
|
2017-11-01 05:51:10 +08:00
|
|
|
performed. You can configure this behavior by setting the
|
|
|
|
`server.compression.min-response-size` property.
|
2015-01-16 19:09:52 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
By default, responses are compressed only if their content type is one of the
|
2015-06-29 21:50:48 +08:00
|
|
|
following:
|
2015-01-16 19:09:52 +08:00
|
|
|
|
2015-06-29 21:50:48 +08:00
|
|
|
- `text/html`
|
|
|
|
- `text/xml`
|
|
|
|
- `text/plain`
|
|
|
|
- `text/css`
|
2015-01-16 19:09:52 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can configure this behavior by setting the `server.compression.mime-types` property.
|
2015-01-16 19:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-spring-mvc]]
|
|
|
|
== Spring MVC
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-write-a-json-rest-service]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Write a JSON REST Service
|
2014-03-14 04:28:16 +08:00
|
|
|
Any Spring `@RestController` in a Spring Boot application should render JSON response by
|
2017-11-01 05:51:10 +08:00
|
|
|
default as long as Jackson2 is on the classpath, as shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@RestController
|
|
|
|
public class MyController {
|
|
|
|
|
|
|
|
@RequestMapping("/thing")
|
|
|
|
public MyThing thing() {
|
|
|
|
return new MyThing();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-04-23 16:42:10 +08:00
|
|
|
|
|
|
|
|
2014-04-11 17:13:56 +08:00
|
|
|
[[howto-write-an-xml-rest-service]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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:
|
2014-10-03 16:37:02 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<dependency>
|
|
|
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
|
|
|
<artifactId>jackson-dataformat-xml</artifactId>
|
|
|
|
</dependency>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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 Woodstox:
|
2014-10-03 16:37:02 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<dependency>
|
|
|
|
<groupId>org.codehaus.woodstox</groupId>
|
|
|
|
<artifactId>woodstox-core-asl</artifactId>
|
|
|
|
</dependency>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-04-11 14:07:34 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2014-04-23 16:42:10 +08:00
|
|
|
@XmlRootElement
|
2014-04-11 14:07:34 +08:00
|
|
|
public class MyThing {
|
2014-04-23 16:42:10 +08:00
|
|
|
private String name;
|
|
|
|
// .. getters and setters
|
2014-04-11 14:07:34 +08:00
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
To get the server to render XML instead of JSON, you might have to send an
|
2014-04-23 16:42:10 +08:00
|
|
|
`Accept: text/xml` header (or use a browser).
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-customize-the-jackson-objectmapper]]
|
|
|
|
=== Customize the Jackson ObjectMapper
|
|
|
|
Spring MVC (client and server side) uses `HttpMessageConverters` to negotiate content
|
2017-11-01 05:51:10 +08:00
|
|
|
conversion in an HTTP exchange. If Jackson is on the classpath, you already get the
|
2016-08-19 04:35:04 +08:00
|
|
|
default converter(s) provided by `Jackson2ObjectMapperBuilder`, an instance of which
|
|
|
|
is auto-configured for you.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The `ObjectMapper` (or `XmlMapper` for Jackson XML converter) instance (created by default)
|
2016-08-19 04:35:04 +08:00
|
|
|
has the following customized properties:
|
2014-10-03 16:37:02 +08:00
|
|
|
|
2014-10-11 08:27:26 +08:00
|
|
|
* `MapperFeature.DEFAULT_VIEW_INCLUSION` is disabled
|
|
|
|
* `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` is disabled
|
2014-10-03 16:37:02 +08:00
|
|
|
|
|
|
|
Spring Boot has also some features to make it easier to customize this behavior.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can configure the `ObjectMapper` and `XmlMapper` instances by using the environment.
|
2014-10-03 16:37:02 +08:00
|
|
|
Jackson provides an extensive suite of simple on/off features that can be used to
|
2017-11-01 05:51:10 +08:00
|
|
|
configure various aspects of its processing. These features are described in six enums (in
|
|
|
|
Jackson) that map onto properties in the environment:
|
2014-08-07 00:08:21 +08:00
|
|
|
|
|
|
|
|===
|
|
|
|
|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`
|
2015-06-15 03:51:28 +08:00
|
|
|
|
|
|
|
|`com.fasterxml.jackson.annotation.JsonInclude.Include`
|
2016-09-21 18:38:26 +08:00
|
|
|
|`spring.jackson.default-property-inclusion=always\|non_null\|non_absent\|non_default\|non_empty`
|
2014-08-07 00:08:21 +08:00
|
|
|
|===
|
|
|
|
|
2014-10-03 16:37:02 +08:00
|
|
|
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,
|
2017-11-01 05:51:10 +08:00
|
|
|
relaxed binding>>, the case of `indent_output` does not have to match the case of the
|
|
|
|
corresponding enum constant, which is `INDENT_OUTPUT`.
|
2014-10-03 16:37:02 +08:00
|
|
|
|
2016-08-19 04:35:04 +08:00
|
|
|
This environment-based configuration is applied to the auto-configured
|
2017-11-01 05:51:10 +08:00
|
|
|
`Jackson2ObjectMapperBuilder` bean and applies to any mappers created by
|
2016-08-19 04:35:04 +08:00
|
|
|
using the builder, including the auto-configured `ObjectMapper` bean.
|
2014-08-07 00:08:21 +08:00
|
|
|
|
2016-08-19 04:35:04 +08:00
|
|
|
The context's `Jackson2ObjectMapperBuilder` can be customized by one or more
|
2017-11-01 05:51:10 +08:00
|
|
|
`Jackson2ObjectMapperBuilderCustomizer` beans. Such customizer beans can be ordered
|
|
|
|
(Boot's own customizer has an order of 0), letting additional customization be applied
|
2016-08-19 04:35:04 +08:00
|
|
|
both before and after Boot's customization.
|
2014-08-07 00:08:21 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Any beans of type `com.fasterxml.jackson.databind.Module` are automatically registered
|
|
|
|
with the auto-configured `Jackson2ObjectMapperBuilder` and are applied to any `ObjectMapper`
|
2016-08-19 04:35:04 +08:00
|
|
|
instances that it creates. This provides a global mechanism for contributing custom
|
|
|
|
modules when you add new features to your application.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-08-19 04:35:04 +08:00
|
|
|
If you want to replace the default `ObjectMapper` completely, either define a `@Bean` of
|
2017-11-01 05:51:10 +08:00
|
|
|
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 (always available if you use the default MVC
|
|
|
|
configuration). It has some useful methods to access the default and user-enhanced
|
2014-03-14 04:28:16 +08:00
|
|
|
message converters.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
See the "`<<howto-customize-the-responsebody-rendering>>`" section and the
|
2017-04-29 14:30:06 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
2014-03-14 04:28:16 +08:00
|
|
|
source code for more details.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-customize-the-responsebody-rendering]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Customize the @ResponseBody Rendering
|
2014-03-14 04:28:16 +08:00
|
|
|
Spring uses `HttpMessageConverters` to render `@ResponseBody` (or responses from
|
2017-11-01 05:51:10 +08:00
|
|
|
`@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`).
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-07-25 05:55:13 +08:00
|
|
|
As in normal MVC usage, any `WebMvcConfigurer` beans that you provide can also
|
2017-11-01 05:51:10 +08:00
|
|
|
contribute converters by overriding the `configureMessageConverters` method. However, unlike
|
2014-03-14 04:28:16 +08:00
|
|
|
with normal MVC, you can supply only additional converters that you need (because Spring
|
2017-11-01 05:51:10 +08:00
|
|
|
Boot uses the same mechanism to contribute its defaults). Finally, if you opt out of the
|
2014-03-14 04:28:16 +08:00
|
|
|
Spring Boot default MVC configuration by providing your own `@EnableWebMvc` configuration,
|
2017-11-01 05:51:10 +08:00
|
|
|
you can take control completely and do everything manually by using
|
2014-03-14 04:28:16 +08:00
|
|
|
`getMessageConverters` from `WebMvcConfigurationSupport`.
|
|
|
|
|
2017-04-29 14:30:06 +08:00
|
|
|
See the {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`]
|
2014-03-14 04:28:16 +08:00
|
|
|
source code for more details.
|
|
|
|
|
2014-04-22 03:18:26 +08:00
|
|
|
|
|
|
|
|
2014-04-25 21:41:36 +08:00
|
|
|
[[howto-multipart-file-upload-configuration]]
|
|
|
|
=== Handling Multipart File Uploads
|
|
|
|
Spring Boot embraces the Servlet 3 `javax.servlet.http.Part` API to support uploading
|
2017-11-01 05:51:10 +08:00
|
|
|
files. By default, Spring Boot configures Spring MVC with a maximum size of 1MB per
|
2016-11-30 09:19:20 +08:00
|
|
|
file and a maximum of 10MB of file data in a single request. You may override these
|
2017-11-01 05:51:10 +08:00
|
|
|
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`.
|
2014-04-25 21:41:36 +08:00
|
|
|
|
|
|
|
The multipart support is helpful when you want to receive multipart encoded file data as
|
2014-05-15 16:15:35 +08:00
|
|
|
a `@RequestParam`-annotated parameter of type `MultipartFile` in a Spring MVC controller
|
2014-04-25 21:41:36 +08:00
|
|
|
handler method.
|
|
|
|
|
2017-04-29 14:30:06 +08:00
|
|
|
See the {sc-spring-boot-autoconfigure}/web/servlet/MultipartAutoConfiguration.{sc-ext}[`MultipartAutoConfiguration`]
|
2014-10-03 11:45:05 +08:00
|
|
|
source for more details.
|
2014-04-22 03:18:26 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-switch-off-the-spring-mvc-dispatcherservlet]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2014-03-14 04:28:16 +08:00
|
|
|
some of the other Boot MVC features. To add your own servlet and map it to the root
|
2017-11-01 05:51:10 +08:00
|
|
|
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.)
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-switch-off-default-mvc-configuration]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Switch off the Default MVC Configuration
|
2014-03-14 04:28:16 +08:00
|
|
|
The easiest way to take complete control over MVC configuration is to provide your own
|
2017-11-01 05:51:10 +08:00
|
|
|
`@Configuration` with the `@EnableWebMvc` annotation. Doing so leaves all MVC
|
2014-03-14 04:28:16 +08:00
|
|
|
configuration in your hands.
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-15 06:53:35 +08:00
|
|
|
[[howto-customize-view-resolvers]]
|
|
|
|
=== Customize ViewResolvers
|
2014-03-18 22:34:06 +08:00
|
|
|
A `ViewResolver` is a core component of Spring MVC, translating view names in
|
2014-05-15 16:15:35 +08:00
|
|
|
`@Controller` to actual `View` implementations. Note that `ViewResolvers` are mainly
|
2014-03-15 06:53:35 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
other hand, installs one or two for you, depending on what it finds on the classpath and
|
2014-03-15 06:53:35 +08:00
|
|
|
in the application context. The `DispatcherServlet` uses all the resolvers it finds in
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-15 06:53:35 +08:00
|
|
|
added.
|
|
|
|
|
|
|
|
`WebMvcAutoConfiguration` adds the following `ViewResolvers` to your context:
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
* 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
|
2014-03-15 06:53:35 +08:00
|
|
|
view name and then looks for a physical resource with that path in the servlet context
|
2017-11-01 05:51:10 +08:00
|
|
|
(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*
|
2014-10-10 02:06:46 +08:00
|
|
|
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
|
2014-03-15 06:53:35 +08:00
|
|
|
client. There is a useful
|
|
|
|
https://spring.io/blog/2013/06/03/content-negotiation-using-views[blog about `ContentNegotiatingViewResolver`]
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-10-10 02:06:46 +08:00
|
|
|
'`thymeleafViewResolver`'. It looks for resources by surrounding the view name with a
|
2017-11-01 05:51:10 +08:00
|
|
|
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 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`]
|
2015-08-19 20:32:31 +08:00
|
|
|
|
2014-03-15 06:53:35 +08:00
|
|
|
|
2015-09-03 11:17:28 +08:00
|
|
|
|
2016-07-07 17:56:33 +08:00
|
|
|
[[howto-http-clients]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== HTTP Clients
|
2016-07-07 17:56:33 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot offers a number of starters that work with HTTP clients. This section answers
|
|
|
|
questions related to doing so.
|
2016-07-07 17:56:33 +08:00
|
|
|
|
|
|
|
[[howto-http-clients-proxy-configuration]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Configure RestTemplate to Use a Proxy
|
2017-07-07 22:55:25 +08:00
|
|
|
As described in <<spring-boot-features.adoc#boot-features-resttemplate-customization>>,
|
2017-11-01 05:51:10 +08:00
|
|
|
you can use a `RestTemplateCustomizer` with `RestTemplateBuilder` to build a customized
|
2016-07-07 17:56:33 +08:00
|
|
|
`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
|
2017-11-01 05:51:10 +08:00
|
|
|
factory that is being used. The following example configures
|
2016-07-07 17:56:33 +08:00
|
|
|
`HttpComponentsClientRequestFactory` with an `HttpClient` that uses a proxy for all hosts
|
2017-11-01 05:51:10 +08:00
|
|
|
except `192.168.0.5`:
|
2016-07-07 17:56:33 +08:00
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
----
|
|
|
|
include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[tag=customizer]
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-logging]]
|
|
|
|
== Logging
|
|
|
|
|
2016-05-24 21:43:47 +08:00
|
|
|
Spring Boot has no mandatory logging dependency, except for the Commons Logging API, of
|
2017-11-01 05:51:10 +08:00
|
|
|
which there are many implementations to choose from. To use http://logback.qos.ch[Logback],
|
2016-05-24 21:43:47 +08:00
|
|
|
you need to include it and `jcl-over-slf4j` (which implements the Commons Logging API) on
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<dependency>
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
|
|
</dependency>
|
|
|
|
----
|
|
|
|
|
2014-03-19 02:26:15 +08:00
|
|
|
Spring Boot has a `LoggingSystem` abstraction that attempts to configure logging based on
|
2017-11-01 05:51:10 +08:00
|
|
|
the content of the classpath. If Logback is available, it is the first choice.
|
2014-06-27 21:56:39 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-06-27 21:56:39 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2015-06-14 15:36:10 +08:00
|
|
|
logging.level.org.springframework.web=DEBUG
|
|
|
|
logging.level.org.hibernate=ERROR
|
2014-06-27 21:56:39 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can also set the location of a file to which to write the log (in addition to the
|
|
|
|
console) by using "logging.file".
|
2014-07-03 06:52:46 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-07-03 06:52:46 +08:00
|
|
|
using the "logging.config" property.
|
2014-06-27 21:56:39 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-11-11 20:45:43 +08:00
|
|
|
[[howto-configure-logback-for-logging]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
* `${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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
for details.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-17 06:24:03 +08:00
|
|
|
[[howto-configure-logback-for-logging-fileonly]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== 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:
|
2015-12-17 06:24:03 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You also need to add `logging.file` to your `application.properties`, as shown in the
|
|
|
|
following example:
|
2015-12-17 06:24:03 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
logging.file=myapplication.log
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-configure-log4j-for-logging]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Configure Log4j for Logging
|
2016-01-25 20:43:36 +08:00
|
|
|
Spring Boot supports http://logging.apache.org/log4j/2.x[Log4j 2] for logging
|
2017-11-01 05:51:10 +08:00
|
|
|
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) `jcl-over-slf4j`
|
|
|
|
in addition to Log4j 2.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-05-18 14:55:42 +08:00
|
|
|
The simplest path is probably through the starters, even though it requires some
|
2017-11-01 05:51:10 +08:00
|
|
|
jiggling with excludes. The following example shows how to set up the starters in Maven:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<dependency>
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
2014-05-15 16:15:35 +08:00
|
|
|
</dependency>
|
2014-03-18 22:34:06 +08:00
|
|
|
<dependency>
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
<artifactId>spring-boot-starter</artifactId>
|
2014-03-14 04:28:16 +08:00
|
|
|
<exclusions>
|
2014-10-13 03:47:19 +08:00
|
|
|
<exclusion>
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
<artifactId>spring-boot-starter-logging</artifactId>
|
|
|
|
</exclusion>
|
2014-03-14 04:28:16 +08:00
|
|
|
</exclusions>
|
|
|
|
</dependency>
|
|
|
|
<dependency>
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
2016-01-25 20:43:36 +08:00
|
|
|
<artifactId>spring-boot-starter-log4j2</artifactId>
|
2014-03-14 04:28:16 +08:00
|
|
|
</dependency>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-01-22 23:06:20 +08:00
|
|
|
[[howto-configure-log4j-for-logging-yaml-or-json-config]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Use YAML or JSON to Configure Log4j 2
|
2015-01-22 23:06:20 +08:00
|
|
|
In addition to its default XML configuration format, Log4j 2 also supports YAML and JSON
|
2016-01-15 20:51:19 +08:00
|
|
|
configuration files. To configure Log4j 2 to use an alternative configuration file format,
|
|
|
|
add the appropriate dependencies to the classpath and name your
|
2017-11-01 05:51:10 +08:00
|
|
|
configuration files to match your chosen file format, as shown in the following example:
|
2015-01-22 23:06:20 +08:00
|
|
|
|
2016-01-15 20:51:19 +08:00
|
|
|
[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`
|
|
|
|
|===
|
2015-01-22 23:06:20 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-data-access]]
|
|
|
|
== Data Access
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot includes a number of starters for working with data sources. This section
|
|
|
|
answers questions related to doing so.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-configure-a-datasource]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2017-01-23 22:46:41 +08:00
|
|
|
`DataSource` to the environment (see
|
2017-11-01 05:51:10 +08:00
|
|
|
"`<<spring-boot-features.adoc#boot-features-external-config-3rd-party-configuration>>`").
|
|
|
|
|
|
|
|
The following example shows how to define a data source in a bean:
|
2014-05-15 16:15:05 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Bean
|
2017-01-23 22:46:41 +08:00
|
|
|
@ConfigurationProperties(prefix="app.datasource")
|
2014-05-15 16:15:35 +08:00
|
|
|
public DataSource dataSource() {
|
|
|
|
return new FancyDataSource();
|
|
|
|
}
|
2014-05-15 16:15:05 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following example shows how to define a data source by setting properties:
|
|
|
|
|
2014-05-15 16:15:05 +08:00
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
2017-01-23 22:46:41 +08:00
|
|
|
app.datasource.url=jdbc:h2:mem:mydb
|
|
|
|
app.datasource.username=sa
|
|
|
|
app.datasource.pool-size=30
|
2016-08-22 17:49:32 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Assuming that your `FancyDataSource` has regular JavaBean properties for the URL, the
|
|
|
|
username, and the pool size, these settings are bound automatically before the
|
2017-01-23 22:46:41 +08:00
|
|
|
`DataSource` is made available to other components. The regular
|
2017-11-01 05:51:10 +08:00
|
|
|
<<howto-initialize-a-database-using-spring-jdbc,database initialization>> also happens
|
2017-01-23 22:46:41 +08:00
|
|
|
(so the relevant sub-set of `spring.datasource.*` can still be used with your custom
|
|
|
|
configuration).
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can apply the same principle if you configure a custom JNDI `DataSource`, as shown in
|
|
|
|
the following example:
|
2016-08-22 17:49:32 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2017-01-23 22:46:41 +08:00
|
|
|
@Bean(destroyMethod="")
|
|
|
|
@ConfigurationProperties(prefix="app.datasource")
|
|
|
|
public DataSource dataSource() throws Exception {
|
|
|
|
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
|
|
|
|
return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
|
2016-08-22 17:49:32 +08:00
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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`:
|
2017-01-23 22:46:41 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
include::{code-examples}/jdbc/BasicDataSourceExample.java[tag=configuration]
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-01-23 22:46:41 +08:00
|
|
|
is going to be used at runtime for more details.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following example shows how to deine a JDBC data source by setting properties:
|
|
|
|
|
2017-01-23 22:46:41 +08:00
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
app.datasource.url=jdbc:mysql://localhost/test
|
|
|
|
app.datasource.username=dbuser
|
|
|
|
app.datasource.password=dbpass
|
|
|
|
app.datasource.pool-size=30
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
However, there is a catch. Because the actual type of the connection pool is not exposed,
|
2017-01-23 22:46:41 +08:00
|
|
|
no keys are generated in the metadata for your custom `DataSource` and no completion is
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-05-15 05:35:08 +08:00
|
|
|
configuration as follows:
|
2017-01-23 22:46:41 +08:00
|
|
|
|
2016-08-22 17:49:32 +08:00
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
2017-01-23 22:46:41 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
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`:
|
2017-01-23 22:46:41 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
include::{code-examples}/jdbc/SimpleDataSourceExample.java[tag=configuration]
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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 one 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
|
2017-01-23 22:46:41 +08:00
|
|
|
namespace (`app.datasource`). To avoid that, you can redefine a custom
|
2017-11-01 05:51:10 +08:00
|
|
|
`DataSourceProperties` on your custom namespace, as shown in the following example:
|
2017-01-23 22:46:41 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configuration]
|
2014-05-15 16:15:05 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
This setup puts you _in sync_ with what Spring Boot does for you by default, except that
|
2017-01-23 22:46:41 +08:00
|
|
|
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`
|
2017-11-01 05:51:10 +08:00
|
|
|
translation for you, you can configure it as follows:
|
2017-01-23 22:46:41 +08:00
|
|
|
|
|
|
|
[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`
|
2017-11-01 05:51:10 +08:00
|
|
|
has no effect. In practice, the builder is initialized with whatever value you
|
2017-03-28 16:05:33 +08:00
|
|
|
might set there and then overridden by the call to `.type()`.
|
2016-08-22 17:49:32 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
See "`<<spring-boot-features.adoc#boot-features-configure-datasource>>`" in the
|
2014-10-10 02:06:46 +08:00
|
|
|
'`Spring Boot features`' section and the
|
2014-03-14 04:28:16 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`]
|
|
|
|
class for more details.
|
|
|
|
|
2017-01-23 22:46:41 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-two-datasources]]
|
|
|
|
=== Configure Two DataSources
|
|
|
|
If you need to configure multiple data sources, you can apply the same tricks that are
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-01-23 22:46:41 +08:00
|
|
|
type.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-01-23 22:46:41 +08:00
|
|
|
on the primary data source:
|
2016-03-01 18:45:30 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2017-01-23 22:46:41 +08:00
|
|
|
include::{code-examples}/jdbc/SimpleTwoDataSourcesExample.java[tag=configuration]
|
2016-03-01 18:45:30 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
TIP: `fooDataSourceProperties` has to be flagged as `@Primary` so that the database
|
|
|
|
initializer feature uses your copy (if you use the initializer).
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Both data sources are also bound for advanced customizations. For instance, you could
|
2017-01-23 22:46:41 +08:00
|
|
|
configure them as follows:
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2017-01-23 22:46:41 +08:00
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
app.datasource.foo.type=com.zaxxer.hikari.HikariDataSource
|
|
|
|
app.datasource.foo.maximum-pool-size=30
|
2014-05-15 16:15:05 +08:00
|
|
|
|
2017-01-23 22:46:41 +08:00
|
|
|
app.datasource.bar.url=jdbc:mysql://localhost/test
|
|
|
|
app.datasource.bar.username=dbuser
|
|
|
|
app.datasource.bar.password=dbpass
|
|
|
|
app.datasource.bar.max-total=30
|
2014-05-15 16:15:05 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can apply the same concept to the secondary `DataSource` as well, as shown in the
|
|
|
|
following example:
|
2017-01-23 22:46:41 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
include::{code-examples}/jdbc/CompleteTwoDataSourcesExample.java[tag=configuration]
|
2014-05-15 16:15:05 +08:00
|
|
|
----
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The preceding example configures two data sources on custom namespaces with the same
|
|
|
|
logic as Spring Boot would use in auto-configuration.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2017-01-26 08:45:59 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-use-spring-data-repositories]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Use Spring Data Repositories
|
2014-03-14 04:28:16 +08:00
|
|
|
Spring Data can create implementations for you of `@Repository` interfaces of various
|
2017-11-01 05:51:10 +08:00
|
|
|
flavors. Spring Boot handles all of that for you, as long as those `@Repositories`
|
2014-03-14 04:28:16 +08:00
|
|
|
are included in the same package (or a sub-package) of your `@EnableAutoConfiguration`
|
|
|
|
class.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
For many applications, all you need is to put the right Spring Data dependencies on
|
2014-03-18 22:34:06 +08:00
|
|
|
your classpath (there is a `spring-boot-starter-data-jpa` for JPA and a
|
2017-11-01 05:51:10 +08:00
|
|
|
`spring-boot-starter-data-mongodb` for Mongodb) and create some repository interfaces to handle your
|
2014-03-14 04:28:16 +08:00
|
|
|
`@Entity` objects. Examples are in the {github-code}/spring-boot-samples/spring-boot-sample-data-jpa[JPA sample]
|
2017-11-01 05:51:10 +08:00
|
|
|
and the {github-code}/spring-boot-samples/spring-boot-sample-data-mongodb[Mongodb sample].
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
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).
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-separate-entity-definitions-from-spring-configuration]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Separate @Entity Definitions from Spring Configuration
|
2014-03-14 04:28:16 +08:00
|
|
|
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`
|
2017-11-01 05:51:10 +08:00
|
|
|
annotation, as shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Configuration
|
|
|
|
@EnableAutoConfiguration
|
|
|
|
@EntityScan(basePackageClasses=City.class)
|
|
|
|
public class Application {
|
|
|
|
|
|
|
|
//...
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-configure-jpa-properties]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2017-01-03 18:25:17 +08:00
|
|
|
configuration properties. Some of them are automatically detected according to the context
|
2017-11-01 05:51:10 +08:00
|
|
|
so you should not have to set them.
|
2017-01-03 18:25:17 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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`.
|
2017-08-21 23:48:42 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The dialect to use is also automatically detected based on the current `DataSource`, but
|
2017-01-03 18:25:17 +08:00
|
|
|
you can set `spring.jpa.database` yourself if you want to be explicit and bypass that
|
|
|
|
check on startup.
|
|
|
|
|
2017-02-14 22:16:17 +08:00
|
|
|
NOTE: Specifying a `database` leads to the configuration of a well-defined Hibernate
|
2017-11-01 05:51:10 +08:00
|
|
|
dialect. Several databases have more than one `Dialect`, and this may not suit your need.
|
2017-02-14 22:16:17 +08:00
|
|
|
In that case, you can either set `spring.jpa.database` to `default` to let Hibernate figure
|
2017-11-01 05:51:10 +08:00
|
|
|
things out or set the dialect by setting the `spring.jpa.database-platform` property.
|
2017-02-14 22:16:17 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The most common options to set are shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2016-04-08 20:13:23 +08:00
|
|
|
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
|
|
|
|
spring.jpa.show-sql=true
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
In addition, all properties in `+spring.jpa.properties.*+` are passed through as normal JPA
|
2017-01-03 18:25:17 +08:00
|
|
|
properties (with the prefix stripped) when the local `EntityManagerFactory` is created.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-06-07 23:43:20 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-configure-hibernate-naming-strategy]]
|
|
|
|
=== Configure Hibernate Naming Strategy
|
2017-07-26 20:49:42 +08:00
|
|
|
Hibernate uses {hibernate-documentation}#naming[two different naming strategies] to map
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
|
|
|
|
|
|
|
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
|
2017-07-26 20:49:42 +08:00
|
|
|
flag if your schema requires it.
|
2017-06-07 23:43:20 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
For example, a `TelephoneNumber` entity is mapped to the `telephone_number` table.
|
2017-06-07 23:43:20 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you prefer to use Hibernate 5's default instead, set the following property:
|
2016-04-15 14:54:35 +08:00
|
|
|
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
|
|
|
----
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
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.
|
|
|
|
|
|
|
|
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2014-04-03 00:13:40 +08:00
|
|
|
[[howto-use-custom-entity-manager]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Use a Custom EntityManagerFactory
|
2014-04-07 12:44:20 +08:00
|
|
|
To take full control of the configuration of the `EntityManagerFactory`, you need to add
|
2014-10-10 02:06:46 +08:00
|
|
|
a `@Bean` named '`entityManagerFactory`'. Spring Boot auto-configuration switches off its
|
2017-11-01 05:51:10 +08:00
|
|
|
entity manager in the presence of a bean of that type.
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2014-05-15 16:15:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-use-two-entity-managers]]
|
|
|
|
=== Use Two EntityManagers
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-05-15 16:15:05 +08:00
|
|
|
|
|
|
|
[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)
|
2014-05-15 16:15:35 +08:00
|
|
|
.persistenceUnit("customers")
|
|
|
|
.build();
|
2014-05-15 16:15:05 +08:00
|
|
|
}
|
2014-04-07 12:44:20 +08:00
|
|
|
|
2014-05-15 16:15:05 +08:00
|
|
|
@Bean
|
|
|
|
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
|
|
|
|
EntityManagerFactoryBuilder builder) {
|
|
|
|
return builder
|
|
|
|
.dataSource(orderDataSource())
|
|
|
|
.packages(Order.class)
|
2014-05-15 16:15:35 +08:00
|
|
|
.persistenceUnit("orders")
|
|
|
|
.build();
|
2014-05-15 16:15:05 +08:00
|
|
|
}
|
|
|
|
----
|
2014-04-03 00:13:40 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The configuration above almost works on its own. To complete the picture, you need to
|
2014-05-15 16:15:35 +08:00
|
|
|
configure `TransactionManagers` for the two `EntityManagers` as well. One of them could
|
|
|
|
be picked up by the default `JpaTransactionManager` in Spring Boot if you mark it as
|
2017-11-01 05:51:10 +08:00
|
|
|
`@Primary`. 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.
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you are using Spring Data, you need to configure `@EnableJpaRepositories` accordingly,
|
|
|
|
as shown in the following example:
|
2015-08-07 16:13:34 +08:00
|
|
|
|
|
|
|
[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 {
|
|
|
|
...
|
|
|
|
}
|
|
|
|
----
|
2014-05-15 16:15:35 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-09-03 11:17:28 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-use-traditional-persistence-xml]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
See
|
2017-10-12 21:33:54 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBaseConfiguration`]
|
2014-03-14 04:28:16 +08:00
|
|
|
for the default settings.
|
|
|
|
|
2014-06-10 02:28:25 +08:00
|
|
|
|
|
|
|
|
2014-06-09 16:36:00 +08:00
|
|
|
[[howto-use-spring-data-jpa--and-mongo-repositories]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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 one (or both) you want to create
|
|
|
|
repositories for you. 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+`) 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
|
2014-06-10 02:28:25 +08:00
|
|
|
auto-configured `MongoTemplate`.
|
|
|
|
|
|
|
|
The same obstacle and the same features exist for other auto-configured Spring Data
|
2017-11-01 05:51:10 +08:00
|
|
|
repository types (Elasticsearch, Solr, and others). To work with them, change the names of the annotations and flags
|
|
|
|
accordingly.
|
2014-06-10 02:28:25 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-02-24 11:21:37 +08:00
|
|
|
|
2015-02-10 23:00:11 +08:00
|
|
|
[[howto-use-exposing-spring-data-repositories-rest-endpoint]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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.
|
2015-02-10 23:00:11 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot exposes a set of useful properties (from the `spring.data.rest` namespace) that
|
2015-07-21 23:27:24 +08:00
|
|
|
customize the
|
|
|
|
{spring-data-rest-javadoc}/core/config/RepositoryRestConfiguration.{dc-ext}[`RepositoryRestConfiguration`].
|
|
|
|
If you need to provide additional customization, you should use a
|
2015-10-22 20:11:30 +08:00
|
|
|
{spring-data-rest-javadoc}/webmvc/config/RepositoryRestConfigurer.{dc-ext}[`RepositoryRestConfigurer`]
|
2015-07-21 23:27:24 +08:00
|
|
|
bean.
|
2015-02-10 23:00:11 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: If you do not specify any order on your custom `RepositoryRestConfigurer`, it runs
|
2017-01-16 17:41:44 +08:00
|
|
|
after the one Spring Boot uses internally. If you need to specify an order, make sure it
|
|
|
|
is higher than 0.
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-02-24 11:21:37 +08:00
|
|
|
|
2016-07-13 19:19:24 +08:00
|
|
|
[[howto-configure-a-component-that-is-used-by-JPA]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2016-07-13 19:19:24 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
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 follwing example:
|
2016-07-13 19:19:24 +08:00
|
|
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
----
|
|
|
|
include::{code-examples}/elasticsearch/HibernateSearchElasticsearchExample.java[tag=configuration]
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-database-initialization]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== 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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-jpa]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Initialize a Database Using JPA
|
2014-03-14 04:28:16 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
behavior in a more fine-grained way. This feature is described in more detail later in
|
|
|
|
the document.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-hibernate]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Initialize a Database Using Hibernate
|
2014-03-14 04:28:16 +08:00
|
|
|
You can set `spring.jpa.hibernate.ddl-auto` explicitly and the standard Hibernate property
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-08-21 23:48:42 +08:00
|
|
|
other mechanisms to initialize the database.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2015-05-28 15:45:06 +08:00
|
|
|
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>>.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2016-10-11 14:30:18 +08:00
|
|
|
is set to `create` or `create-drop`). This can be useful for demos and for testing if you
|
2017-11-01 05:51:10 +08:00
|
|
|
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).
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2015-11-12 21:33:29 +08:00
|
|
|
[[howto-initialize-a-database-using-spring-jdbc]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Initialize a Database
|
2017-10-03 21:23:58 +08:00
|
|
|
Spring Boot can automatically create the schema (DDL scripts) of your `DataSource` and
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-10-03 21:23:58 +08:00
|
|
|
`schema-${platform}.sql` and `data-${platform}.sql` files (if present), where `platform`
|
2017-11-01 05:51:10 +08:00
|
|
|
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).
|
2017-10-03 21:23:58 +08:00
|
|
|
|
2017-10-27 00:23:37 +08:00
|
|
|
Spring Boot automatically creates the schema of an embedded `DataSource`. This behavior
|
2017-11-01 05:51:10 +08:00
|
|
|
can be customized by using the `spring.datasource.initialization-mode` property (and it
|
|
|
|
can also be `always` or `never`).
|
2017-10-27 00:23:37 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
By default, Spring Boot enables the fail-fast feature of the Spring JDBC initializer, so,
|
|
|
|
if the scripts cause exceptions, the application fails to start. You can tune that
|
|
|
|
behavior by setting `spring.datasource.continue-on-error`.
|
2017-10-03 21:23:58 +08:00
|
|
|
|
|
|
|
NOTE: In a JPA-based app, you can choose to let Hibernate create the schema or use
|
2017-11-01 05:51:10 +08:00
|
|
|
`schema.sql`, but you cannot do both. Make sure to disable
|
|
|
|
`spring.jpa.hibernate.ddl-auto` if you use `schema.sql`.
|
2017-10-03 21:23:58 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-initialize-a-spring-batch-database]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Initialize a Spring Batch Database
|
|
|
|
If you use Spring Batch, it comes pre-packaged with SQL initialization scripts
|
2017-08-18 23:02:34 +08:00
|
|
|
for most popular database platforms. Spring Boot can detect your database type and
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2017-08-18 23:02:34 +08:00
|
|
|
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
spring.batch.initialize-schema=always
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You can also switch off the initialization explicitly by setting
|
2017-07-13 19:27:46 +08:00
|
|
|
`spring.batch.initialize-schema=never`.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-use-a-higher-level-database-migration-tool]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Use a Higher-level Database Migration Tool
|
2016-04-21 17:20:28 +08:00
|
|
|
Spring Boot supports two higher-level migration tools: http://flywaydb.org/[Flyway]
|
|
|
|
and http://www.liquibase.org/[Liquibase].
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-05-02 02:37:25 +08:00
|
|
|
[[howto-execute-flyway-database-migrations-on-startup]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Execute Flyway Database Migrations on Startup
|
2014-05-02 02:37:25 +08:00
|
|
|
To automatically run Flyway database migrations on startup, add the
|
2014-05-14 20:41:55 +08:00
|
|
|
`org.flywaydb:flyway-core` to your classpath.
|
2014-05-02 02:37:25 +08:00
|
|
|
|
2014-06-10 07:28:30 +08:00
|
|
|
The migrations are scripts in the form `V<VERSION>__<NAME>.sql` (with `<VERSION>` an
|
2017-11-01 05:51:10 +08:00
|
|
|
underscore-separated version, such as '`1`' or '`2_1`'). By default, they live in a folder called
|
|
|
|
`classpath:db/migration`, but you can modify that location by setting `spring.flyway.locations`. You can
|
2017-09-04 16:08:00 +08:00
|
|
|
also add a special `{vendor}` placeholder to use vendor-specific scripts. Assume the
|
|
|
|
following:
|
2016-12-22 22:39:31 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
2017-09-04 16:08:00 +08:00
|
|
|
spring.flyway.locations=db/migration/{vendor}
|
2016-12-22 22:39:31 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2016-12-22 22:39:31 +08:00
|
|
|
database are available in {sc-spring-boot}/jdbc/DatabaseDriver.{sc-ext}[`DatabaseDriver`].
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2016-04-12 00:30:24 +08:00
|
|
|
more control, provide a `@Bean` that implements
|
|
|
|
{sc-spring-boot-autoconfigure}/flyway/FlywayMigrationStrategy.{sc-ext}[`FlywayMigrationStrategy`].
|
2014-05-02 02:37:25 +08:00
|
|
|
|
2017-01-30 18:48:36 +08:00
|
|
|
Flyway supports SQL and Java http://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
|
2017-11-01 05:51:10 +08:00
|
|
|
`FlywayCallback` or, preferably, extend `BaseFlywayCallback`. Any such beans are
|
|
|
|
automatically registered with `Flyway`. They can be ordered by using `@Order` or by
|
2017-01-30 18:48:36 +08:00
|
|
|
implementing `Ordered`.
|
2016-01-15 02:33:11 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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]`
|
2014-05-26 15:55:28 +08:00
|
|
|
in external properties.
|
|
|
|
|
2014-05-02 02:37:25 +08:00
|
|
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so
|
2017-11-01 05:51:10 +08:00
|
|
|
that you can see how to set things up.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-01-20 23:44:42 +08:00
|
|
|
You can also use Flyway to provide data for specific scenarios. For example, you can
|
2017-11-01 05:51:10 +08:00
|
|
|
place test-specific migrations in `src/test/resources` and they are run only when your
|
|
|
|
application starts for testing. If you want to be more sophisticated, you can use
|
2017-09-04 16:08:00 +08:00
|
|
|
profile-specific configuration to customize `spring.flyway.locations` so that certain
|
2017-11-01 05:51:10 +08:00
|
|
|
migrations run only when a particular profile is active. For example, in
|
|
|
|
`application-dev.properties`, you might specify the following setting:
|
2017-09-04 16:08:00 +08:00
|
|
|
|
|
|
|
[source,properties,indent=0]
|
|
|
|
----
|
|
|
|
spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
With that setup, migrations in `dev/db/migration` run only when the `dev` profile is
|
2017-09-04 16:08:00 +08:00
|
|
|
active.
|
2017-01-20 23:44:42 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-05-02 20:06:52 +08:00
|
|
|
|
2014-04-18 05:59:36 +08:00
|
|
|
[[howto-execute-liquibase-database-migrations-on-startup]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Execute Liquibase Database Migrations on Startup
|
2014-04-18 05:59:36 +08:00
|
|
|
To automatically run Liquibase database migrations on startup, add the
|
2014-05-14 20:41:55 +08:00
|
|
|
`org.liquibase:liquibase-core` to your classpath.
|
2014-04-18 05:59:36 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-09-04 16:05:27 +08:00
|
|
|
supports JSON, XML, and SQL change log formats.
|
2016-04-21 17:20:28 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
By default, Liquibase 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 `@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
|
2017-09-04 16:05:27 +08:00
|
|
|
`DataSource` by setting `spring.liquibase.[url,user,password]` in external properties.
|
2017-02-07 23:16:19 +08:00
|
|
|
|
2016-04-21 17:20:28 +08:00
|
|
|
See
|
2014-04-18 05:59:36 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[`LiquibaseProperties`]
|
2017-11-01 05:51:10 +08:00
|
|
|
for details about available settings such as contexts, the default schema, and others.
|
2014-04-18 05:59:36 +08:00
|
|
|
|
2016-04-21 17:20:28 +08:00
|
|
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-liquibase[Liquibase sample]
|
2017-11-01 05:51:10 +08:00
|
|
|
so that you can see how to set things up.
|
2014-04-18 05:59:36 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-11-24 17:39:40 +08:00
|
|
|
[[howto-messaging]]
|
|
|
|
== Messaging
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot offers a number of starters that include messaging. This section answers
|
|
|
|
questions that arise from using messaging with Spring Boot.
|
2016-11-24 17:39:40 +08:00
|
|
|
|
|
|
|
[[howto-jms-disable-transaction]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Disable Transacted JMS Session
|
|
|
|
If your JMS broker does not support transacted session, 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
|
2016-11-24 17:39:40 +08:00
|
|
|
the `DefaultJmsListenerContainerFactoryConfigurer` to reuse Spring Boot's default, you
|
2017-11-01 05:51:10 +08:00
|
|
|
can disable transacted session, as follows:
|
2016-11-24 17:39:40 +08:00
|
|
|
|
|
|
|
[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;
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The preceding example overrides the default factory, and it should be applied to any
|
|
|
|
other factory that your application defines, if any.
|
2016-11-24 17:39:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-batch-applications]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== Batch Applications
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-02-13 17:08:40 +08:00
|
|
|
NOTE: By default, batch applications require a `DataSource` to store job details. If you
|
2017-11-01 05:51:10 +08:00
|
|
|
want to deviate from that, you need to implement `BatchConfigurer`. See
|
2017-02-13 17:08:40 +08:00
|
|
|
{spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[The
|
2017-02-28 05:56:17 +08:00
|
|
|
Javadoc of `@EnableBatchProcessing`] for more details.
|
2017-02-13 17:08:40 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-execute-spring-batch-jobs-on-startup]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Execute Spring Batch Jobs on Startup
|
2015-11-30 17:47:25 +08:00
|
|
|
Spring Batch auto-configuration is enabled by adding `@EnableBatchProcessing`
|
2014-03-14 04:28:16 +08:00
|
|
|
(from Spring Batch) somewhere in your context.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
By default, it executes *all* `Jobs` in the application context on startup (see
|
2014-03-14 04:28:16 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/batch/JobLauncherCommandLineRunner.{sc-ext}[JobLauncherCommandLineRunner]
|
|
|
|
for details). You can narrow down to a specific job or jobs by specifying
|
2014-10-13 03:47:19 +08:00
|
|
|
`spring.batch.job.names` (comma-separated job name patterns).
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If the application context includes a `JobRegistry`, the jobs in
|
2014-03-14 04:28:16 +08:00
|
|
|
`spring.batch.job.names` are looked up in the registry instead of being autowired from the
|
2017-11-01 05:51:10 +08:00
|
|
|
context. This is a common pattern with more complex systems, where multiple jobs are
|
2014-03-14 04:28:16 +08:00
|
|
|
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
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot includes the Spring Boot Actuator. This section answers questions that often
|
|
|
|
arise from its use.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-change-the-http-port-or-address-of-the-actuator-endpoints]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2017-10-12 21:33:54 +08:00
|
|
|
{sc-spring-boot-actuator-autoconfigure}/web/server/ManagementServerProperties.{sc-ext}[`ManagementServerProperties`]
|
2014-03-14 04:28:16 +08:00
|
|
|
source code and
|
2017-11-01 05:51:10 +08:00
|
|
|
"`<<production-ready-features.adoc#production-ready-customizing-management-server-port>>`"
|
2014-10-10 02:06:46 +08:00
|
|
|
in the '`Production-ready features`' section.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-customize-the-whitelabel-error-page]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Customize the '`whitelabel`' Error Page
|
|
|
|
Spring Boot installs a '`whitelabel`' error page that you see in a browser client if
|
2014-03-14 04:28:16 +08:00
|
|
|
you encounter a server error (machine clients consuming JSON and other media types should
|
2016-04-19 19:17:23 +08:00
|
|
|
see a sensible response with the right error code).
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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 you own
|
2016-04-19 19:17:23 +08:00
|
|
|
error page rather than disabling it completely.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
See also the section on "`<<boot-features-error-handling, Error Handling>>`" for details
|
|
|
|
of how to register handlers in the servlet container.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2015-11-23 00:38:38 +08:00
|
|
|
|
|
|
|
[[howto-use-actuator-with-jersey]]
|
|
|
|
=== Actuator and Jersey
|
2017-11-01 05:51:10 +08:00
|
|
|
Actuator HTTP endpoints are available only for Spring MVC-based applications. If you want
|
|
|
|
to use Jersey and still use the actuator, you need to enable Spring MVC (by depending
|
2015-11-23 00:38:38 +08:00
|
|
|
on `spring-boot-starter-web`, for example). By default, both Jersey and the Spring MVC
|
2017-11-01 05:51:10 +08:00
|
|
|
dispatcher servlet are mapped to the same path (`/`). You need to change the path for
|
2017-01-27 04:43:04 +08:00
|
|
|
one of them (by configuring `server.servlet.path` for Spring MVC or
|
2015-11-23 00:38:38 +08:00
|
|
|
`spring.jersey.application-path` for Jersey). For example, if you add
|
2017-01-27 04:43:04 +08:00
|
|
|
`server.servlet.path=/system` into `application.properties`, the actuator HTTP endpoints
|
2017-11-01 05:51:10 +08:00
|
|
|
are available under `/system`.
|
2015-11-23 00:38:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-security]]
|
|
|
|
== Security
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-switch-off-spring-boot-security-configuration]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Switch off the Spring Boot Security Configuration
|
|
|
|
If you define a `@Configuration` with `@EnableWebSecurity` anywhere in your application,
|
|
|
|
it switches off the default webapp security settings in Spring Boot (but leaves the
|
2016-07-27 23:16:19 +08:00
|
|
|
Actuator's security enabled). To tweak the defaults try setting properties in
|
|
|
|
`+security.*+` (see
|
2014-03-14 04:28:16 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
|
2017-11-01 05:51:10 +08:00
|
|
|
for details of available settings) and the `SECURITY` section of
|
|
|
|
"`<<common-application-properties-security,Common Application Properties>>`".
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-change-the-authenticationmanager-and-add-user-accounts]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Change the AuthenticationManager and Add User Accounts
|
|
|
|
If you provide a `@Bean` of type `AuthenticationManager`, the default one is not
|
|
|
|
created, so you have the full feature set of Spring Security available (such as
|
2014-03-14 04:28:16 +08:00
|
|
|
http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication[various authentication options]).
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Security also provides a convenient `AuthenticationManagerBuilder`, which can be
|
2014-03-14 04:28:16 +08:00
|
|
|
used to build an `AuthenticationManager` with common options. The recommended way to
|
|
|
|
use this in a webapp is to inject it into a void method in a
|
2017-11-01 05:51:10 +08:00
|
|
|
`WebSecurityConfigurerAdapter`, as shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
@Configuration
|
|
|
|
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|
|
|
|
|
|
|
@Autowired
|
2014-03-25 06:01:28 +08:00
|
|
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
|
|
|
auth.inMemoryAuthentication()
|
2014-05-15 16:15:35 +08:00
|
|
|
.withUser("barry").password("password").roles("USER"); // ... etc.
|
2014-03-14 04:28:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// ... other stuff for application security
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
You get the best results if you put this in a nested class or a standalone class
|
|
|
|
(that is, not mixed in with a lot of other `@Beans` that might be allowed to influence the
|
2014-04-07 12:44:20 +08:00
|
|
|
order of instantiation). The {github-code}/spring-boot-samples/spring-boot-sample-web-secure[secure web sample]
|
|
|
|
is a useful template to follow.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you experience instantiation issues (for example, when using JDBC or JPA for the user detail store),
|
2014-09-16 02:35:16 +08:00
|
|
|
it might be worth extracting the `AuthenticationManagerBuilder` callback into a
|
2017-11-01 05:51:10 +08:00
|
|
|
`GlobalAuthenticationConfigurerAdapter` (in the `init()` method so that it happens before the
|
|
|
|
authentication manager is needed elsewhere), as shown in the following example:
|
2014-09-05 23:30:27 +08:00
|
|
|
|
2014-09-05 23:33:32 +08:00
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2014-09-16 02:35:16 +08:00
|
|
|
@Configuration
|
2015-10-27 15:58:00 +08:00
|
|
|
public class AuthenticationManagerConfiguration extends
|
2015-10-27 16:20:16 +08:00
|
|
|
GlobalAuthenticationConfigurerAdapter {
|
2014-09-16 02:35:16 +08:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void init(AuthenticationManagerBuilder auth) {
|
|
|
|
auth.inMemoryAuthentication() // ... etc.
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2014-09-05 23:33:32 +08:00
|
|
|
----
|
2014-04-07 12:44:20 +08:00
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-enable-https]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Enable HTTPS When Running behind a Proxy Server
|
2014-03-14 04:28:16 +08:00
|
|
|
Ensuring that all your main endpoints are only available over HTTPS is an important
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
environment settings, and you should be able to rely on the `HttpServletRequest` to
|
2014-04-24 06:24:59 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-03-17 15:04:57 +08:00
|
|
|
[source,properties,indent=0]
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
2017-09-12 00:05:42 +08:00
|
|
|
server.tomcat.remote-ip-header=x-forwarded-for
|
|
|
|
server.tomcat.protocol-header=x-forwarded-proto
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
(The presence of either of those properties switches on the valve. Alternatively, you can
|
|
|
|
add the `RemoteIpValve` yourself by adding a `TomcatServletWebServerFactory` bean.)
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Security can also be configured to require a secure channel for all (or some)
|
|
|
|
requests. To switch that on in a Spring Boot application, set
|
2014-11-20 18:49:26 +08:00
|
|
|
`security.require_ssl` to `true` in `application.properties`.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-hotswapping]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== Hot Swapping
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot supports hot swapping. This section answers questions about how it works.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-reload-static-content]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Reload Static Content
|
2016-02-12 00:52:38 +08:00
|
|
|
There are several options for hot reloading. The recommended approach is to use
|
2017-11-01 05:51:10 +08:00
|
|
|
<<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).
|
2017-02-08 17:37:29 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
automatically in Eclipse when you save your changes. In IntelliJ IDEA, Make Project
|
|
|
|
triggers the necessary build. Due to the
|
2017-02-08 17:37:29 +08:00
|
|
|
<<using-spring-boot.adoc#using-boot-devtools-restart-exclude, default restart
|
2017-11-01 05:51:10 +08:00
|
|
|
exclusions>>, changes to static resources do not trigger a restart of your application.
|
|
|
|
They do, however, trigger a live reload.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-02-12 00:52:38 +08:00
|
|
|
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
|
|
|
|
hot-swapping of Java class changes).
|
2015-06-11 13:06:19 +08:00
|
|
|
|
2015-10-20 20:29:16 +08:00
|
|
|
Finally, the <<build-tool-plugins.adoc#build-tool-plugins, Maven and Gradle plugins>> can
|
2016-02-12 00:52:38 +08:00
|
|
|
be configured (see the `addResources` property) to support running from the command line
|
2017-02-08 17:37:29 +08:00
|
|
|
with reloading of static files directly from source. You can use that with an external
|
2017-11-01 05:51:10 +08:00
|
|
|
css/js compiler process if you are writing that code with higher-level tools.
|
2015-10-20 20:29:16 +08:00
|
|
|
|
2015-06-11 13:06:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-template-content]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Reload Templates without Restarting the Container
|
2015-06-11 13:06:19 +08:00
|
|
|
Most of the templating technologies supported by Spring Boot include a configuration
|
2017-11-01 05:51:10 +08:00
|
|
|
option to disable caching (described later in this document). If you use the
|
|
|
|
`spring-boot-devtools` module, these properties are
|
2015-06-11 13:06:19 +08:00
|
|
|
<<using-spring-boot.adoc#using-boot-devtools-property-defaults,automatically configured>>
|
2015-11-11 20:45:43 +08:00
|
|
|
for you at development time.
|
2015-06-11 13:06:19 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-content]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Thymeleaf Templates
|
|
|
|
If you use Thymeleaf, set `spring.thymeleaf.cache` to `false`. See
|
2014-03-14 04:28:16 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`]
|
2014-04-30 00:46:55 +08:00
|
|
|
for other Thymeleaf customization options.
|
|
|
|
|
|
|
|
|
2014-05-20 20:13:39 +08:00
|
|
|
|
2014-04-30 00:46:55 +08:00
|
|
|
[[howto-reload-freemarker-content]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== FreeMarker Templates
|
|
|
|
If you use FreeMarker, set `spring.freemarker.cache` to `false`. See
|
2014-04-30 00:46:55 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`]
|
|
|
|
for other FreeMarker customization options.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
2014-05-20 20:13:39 +08:00
|
|
|
|
2014-05-16 22:28:27 +08:00
|
|
|
[[howto-reload-groovy-template-content]]
|
2017-11-01 05:51:10 +08:00
|
|
|
==== Groovy Templates
|
|
|
|
If you use Groovy templates, set `spring.groovy.template.cache` to `false`. See
|
2014-05-16 22:28:27 +08:00
|
|
|
{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`]
|
|
|
|
for other Groovy customization options.
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-05-20 20:13:39 +08:00
|
|
|
|
2015-06-11 13:06:19 +08:00
|
|
|
[[howto-reload-fast-restart]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Fast Application Restarts
|
2015-06-11 13:06:19 +08:00
|
|
|
The `spring-boot-devtools` module includes support for automatic application restarts.
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2015-06-11 13:06:19 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
For more details, see the <<using-spring-boot.adoc#using-boot-devtools>> section.
|
2015-06-11 13:06:19 +08:00
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-reload-java-classes-without-restarting]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Reload Java Classes without Restarting the Container
|
|
|
|
Many modern IDEs (Eclipse, IDEA, and others) support hot swapping of bytecode, so, if you make a
|
|
|
|
change that does not affect class or method signatures, it should reload cleanly with no
|
2014-03-14 04:28:16 +08:00
|
|
|
side effects.
|
|
|
|
|
2014-06-10 08:27:33 +08:00
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-build]]
|
|
|
|
== Build
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot includes build plugins for Maven and Gradle. This section answers common
|
|
|
|
questions about these plugins.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-03-24 19:55:56 +08:00
|
|
|
[[howto-build-info]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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,
|
2016-03-24 19:55:56 +08:00
|
|
|
Spring Boot auto-configures a `BuildProperties` bean.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
To generate build information with Maven, add an execution for the `build-info` goal, as
|
|
|
|
shown in the following example:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
TIP: See the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin documentation]
|
2016-03-24 19:55:56 +08:00
|
|
|
for more details.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following example does the same with Gradle:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
|
|
----
|
2017-03-15 04:51:23 +08:00
|
|
|
springBoot {
|
2016-03-24 19:55:56 +08:00
|
|
|
buildInfo()
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Additional properties can be added by using the DSL, as shown in the following example:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
|
|
----
|
|
|
|
springBoot {
|
|
|
|
buildInfo {
|
|
|
|
additionalProperties = [
|
|
|
|
'foo': 'bar'
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-git-info]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Generate Git Information
|
2016-03-24 19:55:56 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Both Maven and Gradle allow generating a `git.properties` file containing information
|
2016-03-24 19:55:56 +08:00
|
|
|
about the state of your `git` source code repository when the project was built.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0]
|
|
|
|
----
|
|
|
|
<build>
|
|
|
|
<plugins>
|
|
|
|
<plugin>
|
|
|
|
<groupId>pl.project13.maven</groupId>
|
|
|
|
<artifactId>git-commit-id-plugin</artifactId>
|
|
|
|
</plugin>
|
|
|
|
</plugins>
|
|
|
|
</build>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0]
|
|
|
|
----
|
|
|
|
plugins {
|
2017-02-13 17:17:45 +08:00
|
|
|
id "com.gorylenko.gradle-git-properties" version "1.4.17"
|
2016-03-24 19:55:56 +08:00
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
TIP: The commit time in `git.properties` is expected to match the following format:
|
2017-09-25 23:53:07 +08:00
|
|
|
`yyyy-MM-dd'T'HH:mm:ssZ`. This is the default format for both plugins listed above. Using this format
|
2017-11-01 05:51:10 +08:00
|
|
|
allows the time to be parsed into a `Date` and its format, when serialized to JSON, to be controlled by
|
2017-09-25 23:53:07 +08:00
|
|
|
Jackson's date serialization configuration settings.
|
|
|
|
|
2016-03-24 19:55:56 +08:00
|
|
|
|
|
|
|
|
2014-04-24 06:01:21 +08:00
|
|
|
[[howto-customize-dependency-versions-with-maven]]
|
2015-08-03 23:37:25 +08:00
|
|
|
[[howto-customize-dependency-versions]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Customize Dependency Versions
|
2014-06-05 22:37:35 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
third-party dependency, you can add appropriate `<properties>` elements. Browse
|
2017-10-12 00:51:04 +08:00
|
|
|
the {github-code}/spring-boot-project/spring-boot-dependencies/pom.xml[`spring-boot-dependencies`]
|
2014-04-24 06:01:21 +08:00
|
|
|
POM for a complete list of properties. For example, to pick a different `slf4j` version
|
2017-11-01 05:51:10 +08:00
|
|
|
you would add the following property:
|
2014-04-24 06:01:21 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<properties>
|
|
|
|
<slf4j.version>1.7.5<slf4j.version>
|
|
|
|
</properties>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: Doing so only works if your Maven project inherits (directly or indirectly) from
|
2014-06-05 22:37:35 +08:00
|
|
|
`spring-boot-dependencies`. If you have added `spring-boot-dependencies` in your
|
2017-11-01 05:51:10 +08:00
|
|
|
own `dependencyManagement` section with `<scope>import</scope>`, you have to redefine
|
2015-08-03 23:37:25 +08:00
|
|
|
the artifact yourself instead of overriding the property.
|
2014-06-05 22:37:35 +08:00
|
|
|
|
2014-04-24 06:01:21 +08:00
|
|
|
WARNING: Each Spring Boot release is designed and tested against a specific set of
|
2014-05-23 10:18:08 +08:00
|
|
|
third-party dependencies. Overriding versions may cause compatibility issues.
|
2014-04-24 06:01:21 +08:00
|
|
|
|
2015-08-03 23:37:25 +08:00
|
|
|
|
2014-04-24 06:01:21 +08:00
|
|
|
|
2014-05-08 23:10:06 +08:00
|
|
|
[[howto-create-an-executable-jar-with-maven]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create an Executable JAR with Maven
|
2014-10-10 02:06:46 +08:00
|
|
|
The `spring-boot-maven-plugin` can be used to create an executable '`fat`' JAR. If you
|
2017-11-01 05:51:10 +08:00
|
|
|
are using the `spring-boot-starter-parent` POM, you can simply declare the plugin and
|
|
|
|
your jars are repackaged as follows:
|
2014-05-08 23:10:06 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you do not use the parent POM, you can still use the plugin. However, you must
|
|
|
|
additionally add an `<executions>` section, as follows:
|
2014-05-08 23:10:06 +08:00
|
|
|
|
|
|
|
[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.
|
|
|
|
|
|
|
|
|
2014-06-23 18:00:03 +08:00
|
|
|
[[howto-create-an-additional-executable-jar]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Use a Spring Boot Application as a Dependency
|
2016-09-19 20:58:39 +08:00
|
|
|
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.
|
2014-06-23 18:00:03 +08:00
|
|
|
|
2016-09-19 20:58:39 +08:00
|
|
|
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
|
2016-10-02 13:00:47 +08:00
|
|
|
<<appendix-executable-jar-format.adoc#executable-jar-jar-file-structure,executable jar
|
2016-09-19 20:58:39 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
executable archive, leaving the default archive for use as a dependency.
|
2016-09-19 20:58:39 +08:00
|
|
|
|
|
|
|
To configure a classifier of `exec` in Maven, the following configuration can be used:
|
2014-06-23 18:00:03 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2014-06-24 10:41:22 +08:00
|
|
|
|
|
|
|
|
2014-06-24 15:35:01 +08:00
|
|
|
[[howto-extract-specific-libraries-when-an-executable-jar-runs]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2014-06-24 15:35:01 +08:00
|
|
|
file in its own right.
|
|
|
|
|
|
|
|
To deal with any problematic libraries, you can flag that specific nested jars should be
|
2014-10-10 02:06:46 +08:00
|
|
|
automatically unpacked to the '`temp folder`' when the executable jar first runs.
|
2014-06-24 15:35:01 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
For example, to indicate that JRuby should be flagged for unpacking by using the Maven Plugin,
|
2014-06-24 15:35:01 +08:00
|
|
|
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>
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-23 18:00:03 +08:00
|
|
|
[[howto-create-a-nonexecutable-jar]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create a Non-executable JAR with Exclusions
|
|
|
|
Often, if you have an executable and a non-executable jar as 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.
|
2014-06-23 18:00:03 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
In Maven, the executable jar must be the main artifact and you can add a classified jar
|
|
|
|
for the library, as follows:
|
2014-06-23 18:00:03 +08:00
|
|
|
|
|
|
|
[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>
|
2016-11-29 18:28:14 +08:00
|
|
|
<id>lib</id>
|
2014-06-23 18:00:03 +08:00
|
|
|
<phase>package</phase>
|
|
|
|
<goals>
|
|
|
|
<goal>jar</goal>
|
|
|
|
</goals>
|
|
|
|
<configuration>
|
2016-11-29 18:28:14 +08:00
|
|
|
<classifier>lib</classifier>
|
2014-06-23 18:00:03 +08:00
|
|
|
<excludes>
|
|
|
|
<exclude>application.yml</exclude>
|
|
|
|
</excludes>
|
|
|
|
</configuration>
|
|
|
|
</execution>
|
|
|
|
</executions>
|
|
|
|
</plugin>
|
|
|
|
</plugins>
|
|
|
|
</build>
|
|
|
|
----
|
|
|
|
|
2014-06-24 10:41:22 +08:00
|
|
|
|
|
|
|
|
2014-04-24 06:09:53 +08:00
|
|
|
[[howto-remote-debug-maven-run]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2014-06-03 19:52:49 +08:00
|
|
|
the `jvmArguments` property of the {spring-boot-maven-plugin-site}/[maven plugin].
|
2014-04-24 06:09:53 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
See {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for more details.
|
2014-04-24 06:09:53 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
[[howto-build-an-executable-archive-with-ant]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-04-06 17:56:25 +08:00
|
|
|
. 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`
|
2017-11-01 05:51:10 +08:00
|
|
|
directory for a jar or `WEB-INF/lib-provided` for a war. Remember *not* to compress the
|
2016-04-06 17:56:25 +08:00
|
|
|
entries in the archive.
|
2017-11-01 05:51:10 +08:00
|
|
|
. Add the `spring-boot-loader` classes at the root of the archive (so that the `Main-Class`
|
2014-03-14 04:28:16 +08:00
|
|
|
is available).
|
2017-11-01 05:51:10 +08:00
|
|
|
. 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.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following example shows how to build an executable archive with Ant:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2016-04-06 17:56:25 +08:00
|
|
|
[source,xml,indent=0]
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
<target name="build" depends="compile">
|
2016-04-06 17:56:25 +08:00
|
|
|
<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" />
|
2014-03-14 04:28:16 +08:00
|
|
|
<manifest>
|
|
|
|
<attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" />
|
|
|
|
<attribute name="Start-Class" value="${start-class}" />
|
|
|
|
</manifest>
|
|
|
|
</jar>
|
|
|
|
</target>
|
|
|
|
----
|
|
|
|
|
2016-04-06 17:56:25 +08:00
|
|
|
The {github-code}/spring-boot-samples/spring-boot-sample-ant[Ant Sample] has a
|
2017-11-01 05:51:10 +08:00
|
|
|
`build.xml` file with a `manual` task that should work if you run it with the following command:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2016-04-06 17:56:25 +08:00
|
|
|
$ ant -lib <folder containing ivy-2.2.jar> clean manual
|
2014-03-14 04:28:16 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Then you can run the application with the following command:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
$ java -jar target/*.jar
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-traditional-deployment]]
|
2017-11-01 05:51:10 +08:00
|
|
|
== Traditional Deployment
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
Spring Boot supports traditional deployment as well as more modern forms of deployment.
|
|
|
|
This section answers common questions about traditional deployment.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create a Deployable War File
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
The first step in producing a deployable war file is to provide a
|
2017-11-01 05:51:10 +08:00
|
|
|
`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:
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2015-01-29 20:42:49 +08:00
|
|
|
@SpringBootApplication
|
2015-01-29 20:35:48 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2017-01-31 20:39:58 +08:00
|
|
|
configures Maven's war plugin for you) all you need to do is to modify `pom.xml` to change the
|
2017-11-01 05:51:10 +08:00
|
|
|
packaging to war, as follows:
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<packaging>war</packaging>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you use Gradle, you need to modify `build.gradle` to apply the war plugin to the
|
|
|
|
project, as follows:
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
apply plugin: 'war'
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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.
|
2015-01-29 20:35:48 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you use Maven, the following example marks the servlet container (Tomcat, in this
|
|
|
|
case) as being provided:
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
[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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
If you use Gradle, the following example marks the servlet container (Tomcat, in this
|
|
|
|
case) as being provided:
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
dependencies {
|
|
|
|
// …
|
|
|
|
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
|
|
|
|
// …
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
NOTE: `providedRuntime` is preferred to Gradle's `compileOnly` configuration. Among other
|
2017-03-15 04:51:23 +08:00
|
|
|
limitations, `compileOnly` dependencies are not on the test classpath so any web-based
|
2017-11-01 05:51:10 +08:00
|
|
|
integration tests fail.
|
2016-07-19 22:40:57 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2015-01-29 20:35:48 +08:00
|
|
|
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
|
2017-11-01 05:51:10 +08:00
|
|
|
application by using `java -jar` on the command line.
|
2015-01-29 20:35:48 +08:00
|
|
|
|
|
|
|
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]
|
2017-11-01 05:51:10 +08:00
|
|
|
of the previously described configuration.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file-for-older-containers]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== Create a Deployable War File for Older Servlet Containers
|
|
|
|
Older Servlet containers do not have support for the `ServletContextInitializer` bootstrap
|
2014-03-14 04:28:16 +08:00
|
|
|
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]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2014-03-14 04:28:16 +08:00
|
|
|
`ApplicationContext` and replace it with calls to `SpringApplication` or
|
2017-11-01 05:51:10 +08:00
|
|
|
`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 http://spring.io/guides/gs/convert-jar-to-war/[Getting
|
2014-03-14 04:28:16 +08:00
|
|
|
Started Guide on Converting a jar to a war].
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
To create a deployable war by extending `SpringBootServletInitializer` (for example, in a class
|
|
|
|
called `Application`) and add the Spring Boot `@SpringBootApplication` annotation, use
|
|
|
|
code similar to that shown in the following example:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
2016-10-03 18:28:25 +08:00
|
|
|
@SpringBootApplication
|
2014-03-14 04:28:16 +08:00
|
|
|
public class Application extends SpringBootServletInitializer {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
2014-12-10 16:29:12 +08:00
|
|
|
// Customize the application or call application.sources(...) to add sources
|
2016-10-03 18:28:25 +08:00
|
|
|
// Since our example is itself a @Configuration class (via @SpringBootApplication)
|
|
|
|
// we actually don't need to override this method.
|
2014-12-10 16:29:12 +08:00
|
|
|
return application;
|
2014-03-14 04:28:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
remove later and let Spring Boot provide its own defaults for them, but it should be
|
2017-11-01 05:51:10 +08:00
|
|
|
possible to get something working before you need to do that.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
Static resources can be moved to `/public` (or `/static` or `/resources` or
|
2017-11-01 05:51:10 +08:00
|
|
|
`/META-INF/resources`) in the classpath root. The same applies to `messages.properties`
|
|
|
|
(which Spring Boot automatically detects in the root of the classpath).
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
Vanilla usage of Spring `DispatcherServlet` and Spring Security should require no further
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
* A `@Bean` of type `Servlet` or `ServletRegistrationBean` installs that bean in the
|
2017-11-01 05:51:10 +08:00
|
|
|
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/>`).
|
2017-03-02 16:54:34 +08:00
|
|
|
* An `ApplicationContext` in an XML file can be added through an `@ImportResource` in
|
2017-11-01 05:51:10 +08:00
|
|
|
your `Application`. Alternatively, simple cases where annotation configuration is
|
|
|
|
heavily used already can be recreated in a few lines as `@Bean` definitions.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-03-14 04:28:16 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
public static void main(String[] args) {
|
|
|
|
SpringApplication.run(Application.class, args);
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2016-10-03 18:28:25 +08:00
|
|
|
[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
|
2017-11-01 05:51:10 +08:00
|
|
|
`SpringBootServletInitializer` callback and the `main` method, in a class similar to the
|
|
|
|
following:
|
2016-10-03 18:28:25 +08:00
|
|
|
|
|
|
|
[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);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
====
|
|
|
|
|
2014-03-14 04:28:16 +08:00
|
|
|
Applications can fall into more than one category:
|
|
|
|
|
2014-12-10 11:52:56 +08:00
|
|
|
* Servlet 3.0+ applications with no `web.xml`.
|
2014-03-14 04:28:16 +08:00
|
|
|
* 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
|
2017-11-01 05:51:10 +08:00
|
|
|
techniques.
|
2014-03-14 04:28:16 +08:00
|
|
|
|
2014-12-10 11:52:56 +08:00
|
|
|
Servlet 3.0+ applications might translate pretty easily if they already use the Spring
|
2017-11-01 05:51:10 +08:00
|
|
|
Servlet 3.0+ initializer support classes. Normally, all the code from an existing
|
2014-03-14 04:28:16 +08:00
|
|
|
`WebApplicationInitializer` can be moved into a `SpringBootServletInitializer`. If your
|
2017-11-01 05:51:10 +08:00
|
|
|
existing application has more than one `ApplicationContext` (for example, if it uses
|
|
|
|
`AbstractDispatcherServletInitializer`) then you might be able to combine all your context
|
2014-03-14 04:28:16 +08:00
|
|
|
sources into a single `SpringApplication`. The main complication you might encounter is if
|
2017-11-01 05:51:10 +08:00
|
|
|
combining does not work and you need to maintain the context hierarchy. See the
|
2014-03-14 04:28:16 +08:00
|
|
|
<<howto-build-an-application-context-hierarchy, entry on building a hierarchy>> for
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-03-14 04:28:16 +08:00
|
|
|
context.
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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`].
|
2014-11-04 01:04:57 +08:00
|
|
|
|
2014-11-04 09:20:40 +08:00
|
|
|
|
|
|
|
|
2014-12-08 12:10:51 +08:00
|
|
|
[[howto-weblogic]]
|
2015-11-11 20:45:43 +08:00
|
|
|
=== Deploying a WAR to WebLogic
|
2017-11-01 05:51:10 +08:00
|
|
|
To deploy a Spring Boot application to WebLogic, you must ensure that your servlet
|
2014-12-08 12:10:51 +08:00
|
|
|
initializer *directly* implements `WebApplicationInitializer` (even if you extend from a
|
|
|
|
base class that already implements it).
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
A typical initializer for WebLogic should resemble the following example:
|
2014-12-08 12:10:51 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
|
|
import org.springframework.boot.context.web.SpringBootServletInitializer;
|
|
|
|
import org.springframework.web.WebApplicationInitializer;
|
|
|
|
|
|
|
|
@SpringBootApplication
|
|
|
|
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-12-08 12:10:51 +08:00
|
|
|
`WEB-INF/weblogic.xml` file with the following contents:
|
|
|
|
|
|
|
|
[source,xml,indent=0]
|
|
|
|
----
|
2015-05-26 17:07:24 +08:00
|
|
|
<?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>
|
2014-12-08 12:10:51 +08:00
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-11-04 01:04:57 +08:00
|
|
|
[[howto-servlet-2-5]]
|
|
|
|
=== Deploying a WAR in an Old (Servlet 2.5) Container
|
2015-02-22 16:48:29 +08:00
|
|
|
Spring Boot uses Servlet 3.0 APIs to initialize the `ServletContext` (register `Servlets`
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2014-11-04 09:20:40 +08:00
|
|
|
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
|
2016-07-28 13:51:31 +08:00
|
|
|
core of Spring Boot and currently available at 1.0.2.RELEASE), all you should need to do
|
2014-11-04 09:20:40 +08:00
|
|
|
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,
|
2017-11-01 05:51:10 +08:00
|
|
|
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:
|
2014-11-04 09:20:40 +08:00
|
|
|
|
|
|
|
[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>
|
2016-10-12 16:03:23 +08:00
|
|
|
<filter-name>metricsFilter</filter-name>
|
2014-11-04 09:20:40 +08:00
|
|
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
2014-12-19 16:13:30 +08:00
|
|
|
</filter>
|
2014-11-04 09:20:40 +08:00
|
|
|
|
|
|
|
<filter-mapping>
|
2016-10-12 16:03:23 +08:00
|
|
|
<filter-name>metricsFilter</filter-name>
|
2014-11-04 09:20:40 +08:00
|
|
|
<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>
|
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
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
|
2015-02-02 13:37:17 +08:00
|
|
|
normal in a Spring Boot application (you normally only have one application context).
|
2016-03-02 23:04:44 +08:00
|
|
|
|
2017-05-02 21:16:11 +08:00
|
|
|
|
|
|
|
|
2017-10-04 22:08:27 +08:00
|
|
|
[[howto-use-jedis-instead-of-lettuce]]
|
2017-11-01 05:51:10 +08:00
|
|
|
=== 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
|
2017-10-04 22:08:27 +08:00
|
|
|
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.
|
2016-03-02 23:04:44 +08:00
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following example shows how to do so in Maven:
|
2016-03-02 23:04:44 +08:00
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
<dependency>
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
|
|
<exclusions>
|
|
|
|
<exclusion>
|
2017-10-04 22:08:27 +08:00
|
|
|
<groupId>io.lettuce</groupId>
|
|
|
|
<artifactId>lettuce-core</artifactId>
|
2016-03-02 23:04:44 +08:00
|
|
|
</exclusion>
|
|
|
|
</exclusions>
|
|
|
|
</dependency>
|
|
|
|
<dependency>
|
2017-10-04 22:08:27 +08:00
|
|
|
<groupId>redis.clients</groupId>
|
|
|
|
<artifactId>jedis</artifactId>
|
2017-05-04 20:03:50 +08:00
|
|
|
</dependency>
|
2016-03-02 23:04:44 +08:00
|
|
|
----
|
|
|
|
|
2017-11-01 05:51:10 +08:00
|
|
|
The following example shows how to do so in Gradle:
|
2016-03-02 23:04:44 +08:00
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
|
|
|
----
|
|
|
|
configurations {
|
2017-10-04 22:08:27 +08:00
|
|
|
compile.exclude module: "lettuce"
|
2016-03-02 23:04:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
dependencies {
|
2017-10-04 22:08:27 +08:00
|
|
|
compile("redis.clients:jedis")
|
2016-03-02 23:04:44 +08:00
|
|
|
// ...
|
|
|
|
}
|
2017-05-02 21:16:11 +08:00
|
|
|
----
|