From a1a30c6c13034b7d7b7bddd73331151c6db363a7 Mon Sep 17 00:00:00 2001 From: Jay Bryant Date: Tue, 31 Oct 2017 16:51:10 -0500 Subject: [PATCH] Make editorial changes to howto.adoc Closes gh-10854 --- .../src/main/asciidoc/howto.adoc | 1765 +++++++++-------- 1 file changed, 909 insertions(+), 856 deletions(-) diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc index 3da3b438e22..22483d07175 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -3,41 +3,41 @@ [partintro] -- -This section provides answers to some common '`how do I do that...`' type of questions -that often arise when using Spring Boot. This is by no means an exhaustive list, but it +This section provides answers to some common '`how do I do that...`' questions +that often arise when using Spring Boot. Its coverage is not exhaustive, but it does cover quite a lot. -If you are having a specific problem that we don't cover here, you might want to check out +If you have a specific problem that we do not cover here, you might want to check out http://stackoverflow.com/tags/spring-boot[stackoverflow.com] to see if someone has -already provided an answer; this is also a great place to ask new questions (please use +already provided an answer. This is also a great place to ask new questions (please use the `spring-boot` tag). -We're also more than happy to extend this section; If you want to add a '`how-to`' you -can send us a {github-code}[pull request]. +We are also more than happy to extend this section. If you want to add a '`how-to`', +send us a {github-code}[pull request]. -- [[howto-spring-boot-application]] -== Spring Boot application +== Spring Boot Application [[howto-failure-analyzer]] -=== Create your own FailureAnalyzer +=== Create Your Own FailureAnalyzer {dc-spring-boot}/diagnostics/FailureAnalyzer.{dc-ext}[`FailureAnalyzer`] is a great way to intercept an exception on startup and turn it into a human-readable message, wrapped -into a {dc-spring-boot}/diagnostics/FailureAnalysis.{dc-ext}[`FailureAnalysis`]. Spring -Boot provides such analyzer for application context related exceptions, JSR-303 -validations and more. It is actually very easy to create your own. +in a {dc-spring-boot}/diagnostics/FailureAnalysis.{dc-ext}[`FailureAnalysis`]. Spring +Boot provides such an analyzer for application-context-related exceptions, JSR-303 +validations, and more. You can also create your own. `AbstractFailureAnalyzer` is a convenient extension of `FailureAnalyzer` that checks the presence of a specified exception type in the exception to handle. You can extend from that so that your implementation gets a chance to handle the exception only when it is -actually present. If for whatever reason you can't handle the exception, return `null` +actually present. If, for whatever reason, you cannot handle the exception, return `null` to give another implementation a chance to handle the exception. -`FailureAnalyzer` implementations are to be registered in a `META-INF/spring.factories`: -the following registers `ProjectConstraintViolationFailureAnalyzer`: +`FailureAnalyzer` implementations must be registered in `META-INF/spring.factories`. +The following example registers `ProjectConstraintViolationFailureAnalyzer`: [source,properties,indent=0] ---- @@ -48,31 +48,31 @@ the following registers `ProjectConstraintViolationFailureAnalyzer`: [[howto-troubleshoot-auto-configuration]] -=== Troubleshoot auto-configuration +=== Troubleshoot Auto-configuration The Spring Boot auto-configuration tries its best to '`do the right thing`', but -sometimes things fail and it can be hard to tell why. +sometimes things fail, and it can be hard to tell why. There is a really useful `ConditionEvaluationReport` available in any Spring Boot -`ApplicationContext`. You will 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 to debug the application and see what features have been added (and +`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 which not) by Spring Boot at runtime. -Many more questions can be answered by looking at the source code and the Javadoc. Some -rules of thumb: +Many more questions can be answered by looking at the source code and the Javadoc. When +reading the code, remember the following rules of thumb: -* Look for classes called `+*AutoConfiguration+` and read their sources, in particular the +* Look for classes called `+*AutoConfiguration+` and read their sources. Pay special attention to the `+@Conditional*+` annotations to find out what features they enable and when. Add `--debug` to the command line or a System property `-Ddebug` to get a log on the console of all the auto-configuration decisions that were made in your app. In a running - Actuator app look at the `autoconfig` endpoint (`/application/autoconfig` or the JMX + Actuator app, look at the `autoconfig` endpoint (`/application/autoconfig` or the JMX equivalent) for the same information. -* Look for classes that are `@ConfigurationProperties` (e.g. +* Look for classes that are `@ConfigurationProperties` (such as {sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`]) and read from there the available external configuration options. The - `@ConfigurationProperties` has a `name` attribute which acts as a prefix to external - properties, thus `ServerProperties` has `prefix="server"` and its configuration properties - are `server.port`, `server.address` etc. In a running Actuator app look at the + `@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 `configprops` endpoint. * Look for uses of the `bind` method on the `Binder` to pull configuration values explicitly out of the `Environment` in a relaxed manner. It is often used with a prefix. @@ -84,28 +84,28 @@ rules of thumb: [[howto-customize-the-environment-or-application-context]] -=== Customize the Environment or ApplicationContext before it starts +=== Customize the Environment or ApplicationContext Before It Starts A `SpringApplication` has `ApplicationListeners` and `ApplicationContextInitializers` that are used to apply customizations to the context or environment. Spring Boot loads a number of such customizations for use internally from `META-INF/spring.factories`. There is more than one way to register additional ones: -* Programmatically per application by calling the `addListeners` and `addInitializers` +* Programmatically, per application, by calling the `addListeners` and `addInitializers` methods on `SpringApplication` before you run it. -* Declaratively per application by setting `context.initializer.classes` or - `context.listener.classes`. -* Declaratively for all applications by adding a `META-INF/spring.factories` and packaging +* Declaratively, per application, by setting the `context.initializer.classes` or + `context.listener.classes` properties. +* Declaratively, for all applications, by adding a `META-INF/spring.factories` and packaging a jar file that the applications all use as a library. -The `SpringApplication` sends some special `ApplicationEvents` to the listeners (even -some before the context is created), and then registers the listeners for events published +The `SpringApplication` sends some special `ApplicationEvents` to the listeners (some +even before the context is created) and then registers the listeners for events published by the `ApplicationContext` as well. See -_<>_ in the +"`<>`" in the '`Spring Boot features`' section for a complete list. It is also possible to customize the `Environment` before the application context is -refreshed using `EnvironmentPostProcessor`. Each implementation should be registered in -`META-INF/spring.factories`: +refreshed by using `EnvironmentPostProcessor`. Each implementation should be registered in +`META-INF/spring.factories`, as shown in the following example: [source,properties,indent=0] ---- @@ -113,7 +113,7 @@ refreshed using `EnvironmentPostProcessor`. Each implementation should be regist ---- The implementation can load arbitrary files and add them to the `Environment`. For -instance, this example loads a YAML configuration file from the classpath: +instance, the following example loads a YAML configuration file from the classpath: [source,java,indent=0] @@ -121,38 +121,38 @@ instance, this example loads a YAML configuration file from the classpath: include::{code-examples}/context/EnvironmentPostProcessorExample.java[tag=example] ---- -TIP: The `Environment` will already have been prepared with all the usual property sources +TIP: The `Environment` has already been prepared with all the usual property sources that Spring Boot loads by default. It is therefore possible to get the location of the file from the environment. 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 -precedence. A custom implementation may obviously define another order. +precedence. A custom implementation may define another order. -NOTE: While using `@PropertySource` on your `@SpringBootApplication` seems convenient and +CAUTION: While using `@PropertySource` on your `@SpringBootApplication` may seem convenient and 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 -key defined via `@PropertySource` will be loaded too late to have any effect on +key defined via `@PropertySource` is loaded too late to have any effect on auto-configuration. [[howto-build-an-application-context-hierarchy]] -=== Build an ApplicationContext hierarchy (adding a parent or root context) +=== Build an ApplicationContext Hierarchy (Adding a Parent or Root Context) You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext` -hierarchies. See _<>_ +hierarchies. See "`<>`" in the '`Spring Boot features`' section for more information. [[howto-create-a-non-web-application]] -=== Create a non-web application +=== Create a Non-web Application Not all Spring applications have to be web applications (or web services). If you want to -execute some code in a `main` method, but also bootstrap a Spring application to set up -the infrastructure to use, then it's easy with 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 just -leave the servlet API dependencies off the classpath. If you can't do that (e.g. you are -running 2 applications from the same code base) then you can explicitly call -`setWebEnvironment(false)` on your `SpringApplication` instance, or set the +execute some code in a `main` method but also bootstrap a Spring application to set up +the infrastructure to use, you can use the `SpringApplication` features of Spring +Boot. A `SpringApplication` changes its `ApplicationContext` class, depending on whether it +thinks it needs a web application or not. The first thing you can do to help it is to +leave the servlet API dependencies off the classpath. If you cannot do that (for example, you +run two applications from the same code base) then you can explicitly call +`setWebEnvironment(false)` on your `SpringApplication` instance or set the `applicationContextClass` property (through the Java API or with external properties). Application code that you want to run as your business logic can be implemented as a `CommandLineRunner` and dropped into the context as a `@Bean` definition. @@ -160,23 +160,23 @@ Application code that you want to run as your business logic can be implemented [[howto-properties-and-configuration]] -== Properties & configuration +== Properties and Configuration [[howto-automatic-expansion]] -=== Automatically expand properties at build time +=== Automatically Expand Properties at Build Time Rather than hardcoding some properties that are also specified in your project's build -configuration, you can automatically expand them using the existing build configuration -instead. This is possible in both Maven and Gradle. +configuration, you can automatically expand them by instead using the existing build +configuration. This is possible in both Maven and Gradle. [[howto-automatic-expansion-maven]] -==== Automatic property expansion using Maven -You can automatically expand properties from the Maven project using resource -filtering. If you use the `spring-boot-starter-parent` you can then refer to your -Maven '`project properties`' via `@..@` placeholders, e.g. +==== Automatic Property Expansion Using Maven +You can automatically expand properties from the Maven project by using resource +filtering. If you use the `spring-boot-starter-parent`, you can then refer to your +Maven '`project properties`' with `@..@` placeholders, as shown in the following example: [source,properties,indent=0] ---- @@ -184,17 +184,17 @@ Maven '`project properties`' via `@..@` placeholders, e.g. app.java.version=@java.version@ ---- -NOTE: Only production configuration is filtered that way (i.e. no filtering is applied on -`src/test/resources`). +NOTE: Only production configuration is filtered that way (in other words, no filtering is +applied on `src/test/resources`). -TIP: The `spring-boot:run` can add `src/main/resources` directly to the classpath -(for hot reloading purposes) if you enable the `addResources` flag. This circumvents -the resource filtering and this feature. You can use the `exec:java` goal instead -or customize the plugin's configuration, see the +TIP: If you enable the `addResources` flag, the `spring-boot:run` goal can add +`src/main/resources` directly to the classpath (for hot reloading purposes). Doing so +circumvents the resource filtering and this feature. Instead, you can use the `exec:java` +goal or customize the plugin's configuration, see the {spring-boot-maven-plugin-site}/usage.html[plugin usage page] for more details. -If you don't use the starter parent, in your `pom.xml` you need (inside the `` -element): +If you do not use the starter parent, you need to include the following element inside +the `` element of your `pom.xml`: [source,xml,indent=0] ---- @@ -206,7 +206,7 @@ element): ---- -and (inside ``): +You also need to incude the following element inside ``: [source,xml,indent=0] ---- @@ -223,16 +223,16 @@ and (inside ``): ---- -NOTE: The `useDefaultDelimiters` property is important if you are using standard Spring -placeholders in your configuration (e.g. `${foo}`). These may be expanded by the build if -that property is not set to `false`. +NOTE: The `useDefaultDelimiters` property is important if you use standard Spring +placeholders (such as `${placeholder}`) in your configuration. If that property is not +set to `false`, these may be expanded by the build. [[howto-automatic-expansion-gradle]] -==== Automatic property expansion using Gradle +==== Automatic Property Expansion Using Gradle You can automatically expand properties from the Gradle project by configuring the -Java plugin's `processResources` task to do so: +Java plugin's `processResources` task to do so, as shown in the following example: [source,groovy,indent=0] ---- @@ -241,7 +241,8 @@ Java plugin's `processResources` task to do so: } ---- -You can then refer to your Gradle project's properties via placeholders, e.g. +You can then refer to your Gradle project's properties via placeholders, as shown in the +following example: [source,properties,indent=0] ---- @@ -249,20 +250,20 @@ You can then refer to your Gradle project's properties via placeholders, e.g. app.description=${description} ---- -NOTE: Gradle's `expand` method uses Groovy's `SimpleTemplateEngine` which transforms +NOTE: Gradle's `expand` method uses Groovy's `SimpleTemplateEngine`, which transforms `${..}` tokens. The `${..}` style conflicts with Spring's own property placeholder -mechanism. To use Spring property placeholders together with automatic expansion -the Spring property placeholders need to be escaped like `\${..}`. +mechanism. To use Spring property placeholders together with automatic expansion, escape +the Spring property placeholders as follows: `\${..}`. [[howto-externalize-configuration]] -=== Externalize the configuration of SpringApplication -A `SpringApplication` has bean properties (mainly setters) so you can use its Java API as -you create the application to modify its behavior. Or you can externalize the -configuration using properties in `+spring.main.*+`. E.g. in `application.properties` you -might have. +=== 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: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -270,15 +271,15 @@ might have. spring.main.banner-mode=off ---- -and then the Spring Boot banner will not be printed on startup, and the application will -not be a web application. +Then the Spring Boot banner is not printed on startup, and the application is +not a web application. -NOTE: The example above also demonstrates how flexible binding allows the use of +NOTE: The preceding example also demonstrates how flexible binding allows the use of underscores (`_`) as well as dashes (`-`) in property names. -Properties defined in external configuration overrides the values specified via the Java -API with the notable exception of the sources used to create the `ApplicationContext`. Let's -consider this application +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: [source,java,indent=0] ---- @@ -288,7 +289,7 @@ consider this application .run(args); ---- -used with the following configuration: +Now consider the following configuration: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -296,40 +297,41 @@ used with the following configuration: spring.main.banner-mode=console ---- -The actual application will _now_ show the banner (as overridden by configuration) and use -three sources for the `ApplicationContext` (in that order): `demo.MyApp`, `com.acme.Config`, -`com.acme.ExtraConfig`. +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`. [[howto-change-the-location-of-external-properties]] -=== Change the location of external properties of an application -By default properties from different sources are added to the Spring `Environment` in a -defined order (see _<>_ in +=== 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 "`<>`" in the '`Spring Boot features`' section for the exact order). -A nice way to augment and modify this is to add `@PropertySource` annotations to your +A nice way to augment and modify this ordering is to add `@PropertySource` annotations to your application sources. Classes passed to the `SpringApplication` static convenience -methods, and those added using `setSources()` are inspected to see if they have -`@PropertySources`, and if they do, those properties are added to the `Environment` early +methods and those added using `setSources()` are inspected to see if they have +`@PropertySources`. If they do, those properties are added to the `Environment` early enough to be used in all phases of the `ApplicationContext` lifecycle. Properties added -in this way have lower -priority than any added using the default locations (e.g. `application.properties`), system properties, environment variables or the command line. +in this way have lower priority than any added by using the default locations (such as +`application.properties`), system properties, environment variables, or the command line. -You can also provide System properties (or environment variables) to change the behavior: +You can also provide the following System properties (or environment variables) to change +the behavior: -* `spring.config.name` (`SPRING_CONFIG_NAME`), defaults to `application` as the root of +* `spring.config.name` (`SPRING_CONFIG_NAME`): Defaults to `application` as the root of the file name. -* `spring.config.location` (`SPRING_CONFIG_LOCATION`) is the file to load (e.g. a classpath +* `spring.config.location` (`SPRING_CONFIG_LOCATION`): The file to load (such as a classpath resource or a URL). A separate `Environment` property source is set up for this document - and it can be overridden by system properties, environment variables or the + and it can be overridden by system properties, environment variables, or the command line. -No matter what you set in the environment, Spring Boot will always load -`application.properties` as described above. If YAML is used then files with the '`.yml`' -extension are also added to the list by default. +No matter what you set in the environment, Spring Boot always loads +`application.properties` as described above. By default, if YAML is used, then files with +the '`.yml`' extension are also added to the list. -Spring Boot logs the configuration files that are loaded at `DEBUG` level and the +Spring Boot logs the configuration files that are loaded at the `DEBUG` level and the candidates it has not found at `TRACE` level. See {sc-spring-boot}/context/config/ConfigFileApplicationListener.{sc-ext}[`ConfigFileApplicationListener`] @@ -338,33 +340,33 @@ for more detail. [[howto-use-short-command-line-arguments]] -=== Use '`short`' command line arguments +=== Use '`Short`' Command Line Arguments Some people like to use (for example) `--port=9000` instead of `--server.port=9000` to -set configuration properties on the command line. You can easily enable this by using -placeholders in `application.properties`, e.g. +set configuration properties on the command line. You can enable this behavior by using +placeholders in `application.properties`, as shown in the following example: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- server.port=${port:8080} ---- -TIP: If you are inheriting from the `spring-boot-starter-parent` POM, the default filter -token of the `maven-resources-plugins` has been changed from `+${*}+` to `@` (i.e. +TIP: If you inherit from the `spring-boot-starter-parent` POM, the default filter +token of the `maven-resources-plugins` has been changed from `+${*}+` to `@` (that is, `@maven.token@` instead of `${maven.token}`) to prevent conflicts with Spring-style placeholders. If you have enabled maven filtering for the `application.properties` directly, you may want to also change the default filter token to use http://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#delimiters[other delimiters]. -NOTE: In this specific case the port binding will work in a PaaS environment like Heroku -and Cloud Foundry, since in those two platforms the `PORT` environment variable is set +NOTE: In this specific case, the port binding works in a PaaS environment such as Heroku +or Cloud Foundry In those two platforms, the `PORT` environment variable is set automatically and Spring can bind to capitalized synonyms for `Environment` properties. [[howto-use-yaml-for-external-properties]] -=== Use YAML for external properties -YAML is a superset of JSON and as such is a very convenient syntax for storing external -properties in a hierarchical format. E.g. +=== Use YAML for External Properties +YAML is a superset of JSON and, as such, is a convenient syntax for storing external +properties in a hierarchical format, as shown in the following example: [source,yaml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -378,14 +380,14 @@ properties in a hierarchical format. E.g. port: 9000 ---- -Create a file called `application.yml` and stick it in the root of your classpath, and -also add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already +Create a file called `application.yml` and put it in the root of your classpath. +Then add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already included if you use the `spring-boot-starter`). A YAML file is parsed to a Java `Map` (like a JSON object), and Spring Boot flattens the map so that it -is 1-level deep and has period-separated keys, a lot like people are used to with +is one level deep and has period-separated keys, as many people are used to with `Properties` files in Java. -The example YAML above corresponds to an `application.properties` file +The example YAML above corresponds to an `application.properties` file as follows: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -395,49 +397,48 @@ The example YAML above corresponds to an `application.properties` file server.port=9000 ---- -See _<>_ in +See "`<>`" in the '`Spring Boot features`' section for more information about YAML. [[howto-set-active-spring-profiles]] -=== Set the active Spring profiles -The Spring `Environment` has an API for this, but normally you would set a System property -(`spring.profiles.active`) or an OS environment variable (`SPRING_PROFILES_ACTIVE`). E.g. -launch your application with a `-D` argument (remember to put it before the main class -or jar archive): +=== Set the Active Spring Profiles +The Spring `Environment` has an API for this, but you would normally set a System property +(`spring.profiles.active`) or an OS environment variable (`SPRING_PROFILES_ACTIVE`). +Also, you can launch your application with a `-D` argument (remember to put it before the +main class or jar archive), as follows: [indent=0,subs="verbatim,quotes,attributes"] ---- $ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar ---- -In Spring Boot you can also set the active profile in `application.properties`, e.g. +In Spring Boot, you can also set the active profile in `application.properties`, as shown +in the following example: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- spring.profiles.active=production ---- -A value set this way is replaced by the System property or environment variable setting, -but not by the `SpringApplicationBuilder.profiles()` method. Thus the latter Java API can +A value set this way is replaced by the System property or environment variable setting +but not by the `SpringApplicationBuilder.profiles()` method. Thus, the latter Java API can be used to augment the profiles without changing the defaults. -See _<>_ in -the '`Spring Boot features`' section for more information. +See "`<>`" in +the "`Spring Boot features`" section for more information. [[howto-change-configuration-depending-on-the-environment]] -=== Change configuration depending on the environment +=== Change Configuration Depending on the Environment A YAML file is actually a sequence of documents separated by `---` lines, and each document is parsed separately to a flattened map. If a YAML document contains a `spring.profiles` key, then the profiles value -(comma-separated list of profiles) is fed into the Spring -`Environment.acceptsProfiles()` and if any of those profiles is active that document is -included in the final merge (otherwise not). - -Example: +(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: [source,yaml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -458,23 +459,24 @@ Example: port: 0 ---- -In this example the default port is 9000, but if the Spring profile '`development`' is -active then the port is 9001, and if '`production`' is active then it is 0. +In the preceding example, the default port is 9000. However, if the Spring profile called +'`development`' is active, then the port is 9001. If '`production`' is active, then the +port is 0. -The YAML documents are merged in the order they are encountered (so later values override -earlier ones). +The YAML documents are merged in the order in which they are encountered (so later values +override earlier ones). -To do the same thing with properties files you can use `application-${profile}.properties` -to specify profile-specific values. +To do the same thing with properties files, you can use +`application-${profile}.properties` to specify profile-specific values. [[howto-discover-build-in-options-for-external-properties]] -=== Discover built-in options for external properties +=== Discover Built-in Options for External Properties Spring Boot binds external properties from `application.properties` (or `.yml`) (and other places) into an application at runtime. There is not (and technically cannot be) -an exhaustive list of all supported properties in a single location because contributions -can come from additional jar files on your classpath. +an exhaustive list of all supported properties in a single location, because +contributions can come from additional jar files on your classpath. A running application with the Actuator features has a `configprops` endpoint that shows all the bound and bindable properties available through `@ConfigurationProperties`. @@ -482,34 +484,35 @@ all the bound and bindable properties available through `@ConfigurationPropertie The appendix includes an <> example with a list of the most common properties supported by Spring Boot. The definitive list comes from searching the source code for -`@ConfigurationProperties` and `@Value` annotations, as well as the occasional use of +`@ConfigurationProperties` and `@Value` annotations as well as the occasional use of `Binder`. [[howto-embedded-web-servers]] -== Embedded Web servers - +== Embedded Web Servers +Each Spring Boot web application includes an embedded web server. This feature leads to a +number of how-to questions, including how to change the embedded server and how to +configure the embedded server. This section answers those questions. [[howto-use-another-web-server]] -=== Use another Web server -The Spring Boot starters bring a default embedded container for you: - -* `spring-boot-starter-web` brings Tomcat with `spring-boot-starter-tomcat`, - but `spring-boot-starter-jetty` and `spring-boot-starter-undertow` can be used instead. -* `spring-boot-starter-webflux` brings Reactor Netty with - `spring-boot-starter-reactor-netty`, but `spring-boot-starter-tomcat`, - `spring-boot-starter-jetty` and `spring-boot-starter-undertow` can be used instead. - -NOTE: Many starters only support Spring MVC, so they transitively bring -`spring-boot-starter-web` into your application classpath - -If you choose to use a different HTTP server, you need to exclude those dependencies -and include the one you chose instead. Spring Boot provides separate starters for +=== 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 HTTP servers to help make this process as easy as possible. -Example in Maven, for Spring MVC: +The following Maven example shows how to exclude Tomcat and include Jetty for Spring MVC: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -531,7 +534,8 @@ Example in Maven, for Spring MVC: ---- -Example in Gradle, for Spring WebFlux: +The following Gradle example shows how to exclude Netty and include Undertow for Spring +WebFlux: [source,groovy,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -548,52 +552,54 @@ Example in Gradle, for Spring WebFlux: } ---- -NOTE: `spring-boot-starter-reactor-netty` is required to use the `WebClient`, so excluding -it is not required if you wish to use a different HTTP server. +NOTE: `spring-boot-starter-reactor-netty` is required to use the `WebClient` class, so +you may need to keep a dependency on Netty even when you need to include a different HTTP +server. [[howto-configure-jetty]] === Configure Jetty -Generally you can follow the advice from -_<>_ about -`@ConfigurationProperties` (`ServerProperties` is the main one here), but 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. Or the nuclear option is to add your own `JettyServletWebServerFactory`. +Generally, you can follow the advice from +"`<>`" 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`. [[howto-add-a-servlet-filter-or-listener]] -=== Add a Servlet, Filter or Listener to an application -There are two ways to add `Servlet`, `Filter`, `ServletContextListener` and the other +=== Add a Servlet, Filter, or Listener to an Application +There are two ways to add `Servlet`, `Filter`, `ServletContextListener`, and the other listeners supported by the Servlet spec to your application. You can either provide -Spring beans for them, or enable scanning for Servlet components. +Spring beans for them or enable scanning for Servlet components. [[howto-add-a-servlet-filter-or-listener-as-spring-bean]] -==== Add a Servlet, Filter or Listener using a Spring bean -To add a `Servlet`, `Filter`, or Servlet `*Listener` provide a `@Bean` definition for it. -This can be very useful when you want to inject configuration or dependencies. However, -you must be very careful that they don't cause eager initialization of too many other -beans because they have to be installed in the container very early in the application -lifecycle (e.g. it's not a good idea to have them depend on your `DataSource` or JPA -configuration). You can work around restrictions like that by initializing them 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 `ServletRegistrationBean` instead of or as well as -the underlying component. +==== 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. [NOTE] ==== -If no `dispatcherType` is specified on a filter registration, it will match -`FORWARD`,`INCLUDE` and `REQUEST`. If async has been enabled, it will match `ASYNC` as -well. +If no `dispatcherType` is specified on a filter registration, it matches +`FORWARD`,`INCLUDE`, and `REQUEST`. If async has been enabled, it also matches `ASYNC`. -If you are migrating a filter that has no `dispatcher` element in `web.xml` you will -need to specify a `dispatcherType` yourself: +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: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -610,11 +616,11 @@ need to specify a `dispatcherType` yourself: [[howto-disable-registration-of-a-servlet-or-filter]] -===== Disable registration of a Servlet or Filter -As <> any `Servlet` -or `Filter` beans will be 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. For example: +===== Disable Registration of a Servlet or Filter +As <>, any `Servlet` +or `Filter` beans are registered with the servlet container automatically. To disable +registration of a particular `Filter` or `Servlet` bean, create a registration bean for it +and mark it as disabled, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -629,26 +635,26 @@ and mark it as disabled. For example: [[howto-add-a-servlet-filter-or-listener-using-scanning]] -==== Add Servlets, Filters, and Listeners using classpath scanning +==== Add Servlets, Filters, and Listeners by Using Classpath Scanning `@WebServlet`, `@WebFilter`, and `@WebListener` annotated classes can be automatically registered with an embedded servlet container by annotating a `@Configuration` class with `@ServletComponentScan` and specifying the package(s) containing the components -that you want to register. By default, `@ServletComponentScan` will scan from the package +that you want to register. By default, `@ServletComponentScan` scans from the package of the annotated class. [[howto-change-the-http-port]] -=== Change the HTTP port -In a standalone application the main HTTP port defaults to `8080`, but can be set with -`server.port` (e.g. in `application.properties` or as a System property). Thanks to -relaxed binding of `Environment` values you can also use `SERVER_PORT` (e.g. as an OS +=== Change the HTTP Port +In a standalone application, the main HTTP port defaults to `8080` but can be set with +`server.port` (for example, in `application.properties` or as a System property). Thanks to +relaxed binding of `Environment` values, you can also use `SERVER_PORT` (for example, as an OS environment variable). -To switch off the HTTP endpoints completely, but still create a `WebApplicationContext`, -use `server.port=-1` (this is sometimes useful for testing). +To switch off the HTTP endpoints completely but still create a `WebApplicationContext`, +use `server.port=-1`. (Doing so is sometimes useful for testing.) -For more details look at _<>_ +For more details, see "`<>`" in the '`Spring Boot features`' section, or the {sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] source code. @@ -656,22 +662,22 @@ code. [[howto-user-a-random-unassigned-http-port]] -=== Use a random unassigned HTTP port +=== Use a Random Unassigned HTTP Port To scan for a free port (using OS natives to prevent clashes) use `server.port=0`. [[howto-discover-the-http-port-at-runtime]] -=== Discover the HTTP port at runtime +=== Discover the HTTP Port at Runtime You can access the port the server is running on from log output or from the -`ServletWebServerApplicationContext` via its `EmbeddedWebServer`. The best way to get -that and be sure that it has initialized is to add a `@Bean` of type +`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 `ApplicationListener` and pull the container out of the event when it is published. Tests that use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)` can -also inject the actual port into a field using the `@LocalServerPort` annotation. For -example: +also inject the actual port into a field by using the `@LocalServerPort` annotation, as +shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -692,10 +698,10 @@ example: [NOTE] ==== -`@LocalServerPort` is a meta-annotation for `@Value("${local.server.port}")`. Don't try -to inject the port in a regular application. As we just saw, the value is only set once -the container has initialized; contrary to a test, application code callbacks are -processed early (i.e. before the value is actually available). +`@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). ==== @@ -703,7 +709,8 @@ processed early (i.e. before the value is actually available). [[howto-configure-ssl]] === Configure SSL SSL can be configured declaratively by setting the various `+server.ssl.*+` properties, -typically in `application.properties` or `application.yml`. For example: +typically in `application.properties` or `application.yml`. The following example shows +setting SSL properties in `applicaiton.properties`: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -716,11 +723,11 @@ typically in `application.properties` or `application.yml`. For example: See {sc-spring-boot}/web/server/Ssl.{sc-ext}[`Ssl`] for details of all of the supported properties. -Using configuration like the example above means the application will no longer support -plain HTTP connector at port 8080. Spring Boot doesn't support the configuration of both -an HTTP connector and an HTTPS connector via `application.properties`. If you want to -have both then you'll need to configure one of them programmatically. It's recommended -to use `application.properties` to configure HTTPS as the HTTP connector is the easier of +Using configuration such as the preceding example means the application no longer supports +a plain HTTP connector at port 8080. Spring Boot does not support the configuration of both +an HTTP connector and an HTTPS connector through `application.properties`. If you want to +have both, you need to configure one of them programmatically. We recommend +using `application.properties` to configure HTTPS, as the HTTP connector is the easier of the two to configure programmatically. See the {github-code}/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors[`spring-boot-sample-tomcat-multi-connectors`] sample project for an example. @@ -729,10 +736,10 @@ sample project for an example. [[howto-configure-accesslogs]] === Configure Access Logging -Access logs can be configured for Tomcat, Undertow and Jetty via their respective +Access logs can be configured for Tomcat, Undertow, and Jetty through their respective namespaces. -For instance, the following logs access on Tomcat with a +For instance, the following settings log access on Tomcat with a {tomcat-documentation}/config/valve.html#Access_Logging[custom pattern]. [source,properties,indent=0,subs="verbatim,quotes,attributes"] @@ -742,12 +749,14 @@ For instance, the following logs access on Tomcat with a server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms) ---- -NOTE: The default location for logs is a `logs` directory relative to the tomcat base dir -and said directory is a temp directory by default so you may want to fix Tomcat's base -directory or use an absolute path for the logs. In the example above, the logs will -be available in `my-tomcat/logs` relative to the working directory of the application. +NOTE: The default location for logs is a `logs` directory relative to the Tomcat base +directory. By default, the `logs` directory is a temporary directory, so you may want to +fix Tomcat's base directory or use an absolute path for the logs. In the preceding +example, the logs are available in `my-tomcat/logs` relative to the working directory of +the application. -Access logging for undertow can be configured in a similar fashion +Access logging for undertow can be configured in a similar fashion, as shown in the +following example: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -756,9 +765,10 @@ Access logging for undertow can be configured in a similar fashion ---- Logs are stored in a `logs` directory relative to the working directory of the -application. This can be customized via `server.undertow.accesslog.directory`. +application. You can customize this location by setting the +`server.undertow.accesslog.directory` property. -Finally, access logging for jetty can also be configured that way: +Finally, access logging for Jetty can also be configured as follows: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -766,34 +776,34 @@ Finally, access logging for jetty can also be configured that way: server.jetty.accesslog.filename=/var/log/jetty-access.log ---- -By default, logs will be redirected to `System.err`. For more details, please refer to +By default, logs are redirected to `System.err`. For more details, see {jetty-documentation}/configuring-jetty-request-logs.html[the documentation]. [[howto-use-behind-a-proxy-server]] [[howto-use-tomcat-behind-a-proxy-server]] -=== Use behind a front-end proxy server +=== Running Behind a Front-end Proxy Server Your application might need to send `302` redirects or render content with absolute links -back to itself. When running behind a proxy, the caller wants a link to the proxy, and not -to the physical address of the machine hosting your app. Typically such situations are -handled via a contract with the proxy, which will add headers to tell the back end how to +back to itself. When running behind a proxy, the caller wants a link to the proxy and not +to the physical address of the machine hosting your app. Typically, such situations are +handled through a contract with the proxy, which adds headers to tell the back end how to construct links to itself. -If the proxy adds conventional `X-Forwarded-For` and `X-Forwarded-Proto` headers (most do -this out of the box) the absolute links should be rendered correctly as long as +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 `server.use-forward-headers` is set to `true` in your `application.properties`. -NOTE: If your application is running in Cloud Foundry or Heroku the -`server.use-forward-headers` property will default to `true` if not specified. In all -other instances it defaults to `false`. +NOTE: If your application runs in Cloud Foundry or Heroku, the +`server.use-forward-headers` property defaults to `true`. In all +other instances, it defaults to `false`. [[howto-customize-tomcat-behind-a-proxy-server]] -==== Customize Tomcat's proxy configuration -If you are using Tomcat you can additionally configure the names of the headers used to -carry "`forwarded`" information: +==== Customize Tomcat's Proxy Configuration +If you use Tomcat, you can additionally configure the names of the headers used to +carry "`forwarded`" information, as shown in the following example: [indent=0] ---- @@ -804,43 +814,44 @@ carry "`forwarded`" information: Tomcat is also configured with a default regular expression that matches internal proxies that are to be trusted. By default, IP addresses in `10/8`, `192.168/16`, `169.254/16` and `127/8` are trusted. You can customize the valve's configuration by -adding an entry to `application.properties`, e.g. +adding an entry to `application.properties`, as shown in the following example: [indent=0] ---- server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3} ---- -NOTE: The double backslashes are only required when you're using a properties file for -configuration. If you are using YAML, single backslashes are sufficient and a value -that's equivalent to the one shown above would be `192\.168\.\d{1,3}\.\d{1,3}`. +NOTE: The double backslashes are required only when you use a properties file for +configuration. If you use YAML, single backslashes are sufficient, and a value +equivalent to that shown in the preceding example would be `192\.168\.\d{1,3}\.\d{1,3}`. -NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but don't do -this in production). +NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but do not do +so in production). You can take complete control of the configuration of Tomcat's `RemoteIpValve` by -switching the automatic one off (i.e. set `server.use-forward-headers=false`) and adding -a new valve instance in a `TomcatServletWebServerFactory` bean. +switching the automatic one off (to do so, set `server.use-forward-headers=false`) and adding +a new valve instance in a `TomcatServletWebServerFactory` bean. [[howto-configure-tomcat]] === Configure Tomcat -Generally you can follow the advice from -_<>_ about -`@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at -`ServletWebServerFactoryCustomizer` and various Tomcat-specific `+*Customizers+` that you -can add in one of those. The Tomcat APIs are quite rich so once you have access to the -`TomcatServletWebServerFactory` you can modify it in a number of ways. Or the -nuclear option is to add your own `TomcatServletWebServerFactory`. +Generally, you can follow the advice from +"`<>`" 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`. [[howto-enable-multiple-connectors-in-tomcat]] === Enable Multiple Connectors with Tomcat -Add an `org.apache.catalina.connector.Connector` to the -`TomcatServletWebServerFactory` which can allow multiple connectors, e.g. HTTP and -HTTPS connector: +You can add an `org.apache.catalina.connector.Connector` to the +`TomcatServletWebServerFactory`, which can allow multiple connectors, including HTTP and +HTTPS connectors, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -879,8 +890,8 @@ HTTPS connector: [[howto-use-tomcat-legacycookieprocessor]] === Use Tomcat's LegacyCookieProcessor -The embedded Tomcat used by Spring Boot does not support "Version 0" of the Cookie -format out of the box, and you may see the following error: +By default, the embedded Tomcat used by Spring Boot does not support "Version 0" of the +Cookie format, so you may see the following error: [indent=0] ---- @@ -888,10 +899,11 @@ format out of the box, and you may see the following error: ---- If at all possible, you should consider updating your code to only store values -compliant with later Cookie specifications. If, however, you're unable to change the +compliant with later Cookie specifications. If, however, you cannot change the way that cookies are written, you can instead configure Tomcat to use a -`LegacyCookieProcessor`. To switch to the `LegacyCookieProcessor` use an -`ServletWebServerFactoryCustomizer` bean that adds a `TomcatContextCustomizer`: +`LegacyCookieProcessor`. To switch to the `LegacyCookieProcessor`, use an +`ServletWebServerFactoryCustomizer` bean that adds a `TomcatContextCustomizer`, as shown +in the following example: [source,java,indent=0] ---- @@ -903,20 +915,20 @@ include::{code-examples}/context/embedded/TomcatLegacyCookieProcessorExample.jav [[howto-configure-undertow]] === Configure Undertow Generally you can follow the advice from -_<>_ about +"`<>`" about `@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow` are the -main ones here), but 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. Or the nuclear option is to add your -own `UndertowServletWebServerFactory`. +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`. [[howto-enable-multiple-listeners-in-undertow]] === Enable Multiple Listeners with Undertow Add an `UndertowBuilderCustomizer` to the `UndertowServletWebServerFactory` and -add a listener to the `Builder`: +add a listener to the `Builder`, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -938,9 +950,10 @@ add a listener to the `Builder`: [[howto-create-websocket-endpoints-using-serverendpoint]] -=== Create WebSocket endpoints using @ServerEndpoint +=== Create WebSocket Endpoints Using @ServerEndpoint If you want to use `@ServerEndpoint` in a Spring Boot application that used an embedded -container, you must declare a single `ServerEndpointExporter` `@Bean`: +container, you must declare a single `ServerEndpointExporter` `@Bean`, as shown in the +following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -950,17 +963,17 @@ container, you must declare a single `ServerEndpointExporter` `@Bean`: } ---- -This bean will register 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. +The bean shown in the preceding example registers any `@ServerEndpoint` annotated beans +with the underlying WebSocket container. When deployed to a standalone servlet container, +this role is performed by a servlet container initializer, and the +`ServerEndpointExporter` bean is not required. [[how-to-enable-http-response-compression]] -=== Enable HTTP response compression +=== Enable HTTP Response Compression HTTP response compression is supported by Jetty, Tomcat, and Undertow. It can be enabled -via `application.properties`: +in `application.properties`, as follows: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -968,10 +981,10 @@ via `application.properties`: ---- By default, responses must be at least 2048 bytes in length for compression to be -performed. This can be configured using the `server.compression.min-response-size` -property. +performed. You can configure this behavior by setting the +`server.compression.min-response-size` property. -By default, responses will only be compressed if their content type is one of the +By default, responses are compressed only if their content type is one of the following: - `text/html` @@ -979,19 +992,21 @@ following: - `text/plain` - `text/css` -This can be configured using the `server.compression.mime-types` property. +You can configure this behavior by setting the `server.compression.mime-types` property. [[howto-spring-mvc]] == Spring MVC - +Spring Boot has a number of starters that include Spring MVC. Note that some starters +include a dependency on Spring MVC rather than include it directly. This section answers +common questions about Spring MVC and Spring Boot. [[howto-write-a-json-rest-service]] -=== Write a JSON REST service +=== Write a JSON REST Service Any Spring `@RestController` in a Spring Boot application should render JSON response by -default as long as Jackson2 is on the classpath. For example: +default as long as Jackson2 is on the classpath, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1006,18 +1021,18 @@ default as long as Jackson2 is on the classpath. For example: } ---- -As long as `MyThing` can be serialized by Jackson2 (e.g. a normal POJO or Groovy object) -then `http://localhost:8080/thing` will serve a JSON representation of it by default. -Sometimes in a browser you might see XML responses because browsers tend to send accept -headers that prefer XML. +As long as `MyThing` can be serialized by Jackson2 (true for a normal POJO or Groovy +object), then `http://localhost:8080/thing` serves a JSON representation of it by +default. Note that, in a browser, you might sometimes see XML responses, because browsers +tend to send accept headers that prefer XML. [[howto-write-an-xml-rest-service]] -=== Write an XML REST service -If you have the Jackson XML extension (`jackson-dataformat-xml`) on the classpath, it will -be used to render XML responses and the very same example as we used for JSON would work. -To use it, add the following dependency to your project: +=== Write an XML REST Service +If you have the Jackson XML extension (`jackson-dataformat-xml`) on the classpath, you +can use it to render XML responses. The previous example that we used for JSON would +work. To use the Jackson XML renderer, add the following dependency to your project: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1027,9 +1042,9 @@ To use it, add the following dependency to your project: ---- -You may also want to add a dependency on Woodstox. It's faster than the default StAX -implementation provided by the JDK and also adds pretty print support and improved -namespace handling: +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: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1039,9 +1054,9 @@ namespace handling: ---- -If Jackson's XML extension is not available, JAXB (provided by default in the JDK) will -be used, with the additional requirement to have `MyThing` annotated as -`@XmlRootElement`: +If Jackson's XML extension is not available, JAXB (provided by default in the JDK) is +used, with the additional requirement of having `MyThing` annotated as +`@XmlRootElement`, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1052,7 +1067,7 @@ be used, with the additional requirement to have `MyThing` annotated as } ---- -To get the server to render XML instead of JSON you might have to send an +To get the server to render XML instead of JSON, you might have to send an `Accept: text/xml` header (or use a browser). @@ -1060,11 +1075,11 @@ To get the server to render XML instead of JSON you might have to send an [[howto-customize-the-jackson-objectmapper]] === Customize the Jackson ObjectMapper Spring MVC (client and server side) uses `HttpMessageConverters` to negotiate content -conversion in an HTTP exchange. If Jackson is on the classpath you already get the +conversion in an HTTP exchange. If Jackson is on the classpath, you already get the default converter(s) provided by `Jackson2ObjectMapperBuilder`, an instance of which is auto-configured for you. -The `ObjectMapper` (or `XmlMapper` for Jackson XML converter) instance created by default +The `ObjectMapper` (or `XmlMapper` for Jackson XML converter) instance (created by default) has the following customized properties: * `MapperFeature.DEFAULT_VIEW_INCLUSION` is disabled @@ -1072,10 +1087,10 @@ has the following customized properties: Spring Boot has also some features to make it easier to customize this behavior. -You can configure the `ObjectMapper` and `XmlMapper` instances using the environment. +You can configure the `ObjectMapper` and `XmlMapper` instances by using the environment. Jackson provides an extensive suite of simple on/off features that can be used to -configure various aspects of its processing. These features are described in six enums in -Jackson which map onto properties in the environment: +configure various aspects of its processing. These features are described in six enums (in +Jackson) that map onto properties in the environment: |=== |Jackson enum|Environment property @@ -1101,57 +1116,57 @@ Jackson which map onto properties in the environment: For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`. Note that, thanks to the use of <>, the case of `indent_output` doesn't have to match the case of the -corresponding enum constant which is `INDENT_OUTPUT`. +relaxed binding>>, the case of `indent_output` does not have to match the case of the +corresponding enum constant, which is `INDENT_OUTPUT`. This environment-based configuration is applied to the auto-configured -`Jackson2ObjectMapperBuilder` bean, and will apply to any mappers created +`Jackson2ObjectMapperBuilder` bean and applies to any mappers created by using the builder, including the auto-configured `ObjectMapper` bean. The context's `Jackson2ObjectMapperBuilder` can be customized by one or more -`Jackson2ObjectMapperBuilderCustomizer` beans. Such customizer beans can be ordered and -Boot's own customizer has an order of 0, allowing additional customization to be applied +`Jackson2ObjectMapperBuilderCustomizer` beans. Such customizer beans can be ordered +(Boot's own customizer has an order of 0), letting additional customization be applied both before and after Boot's customization. -Any beans of type `com.fasterxml.jackson.databind.Module` will be automatically registered -with the auto-configured `Jackson2ObjectMapperBuilder` and applied to any `ObjectMapper` +Any beans of type `com.fasterxml.jackson.databind.Module` are automatically registered +with the auto-configured `Jackson2ObjectMapperBuilder` and are applied to any `ObjectMapper` instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application. If you want to replace the default `ObjectMapper` completely, either define a `@Bean` of -that type and mark it as `@Primary`, or, if you prefer the builder-based -approach, define a `Jackson2ObjectMapperBuilder` `@Bean`. Note that in either case this -will disable all auto-configuration of the `ObjectMapper`. - -If you provide any `@Beans` of type `MappingJackson2HttpMessageConverter` then -they will replace the default value in the MVC configuration. Also, a convenience bean is -provided of type `HttpMessageConverters` (always available if you use the default MVC -configuration) which has some useful methods to access the default and user-enhanced +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 message converters. -See also the _<>_ section and the +See the "`<>`" section and the {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] source code for more details. [[howto-customize-the-responsebody-rendering]] -=== Customize the @ResponseBody rendering +=== Customize the @ResponseBody Rendering Spring uses `HttpMessageConverters` to render `@ResponseBody` (or responses from -`@RestController`). You can contribute additional converters by simply adding beans of -that type in a Spring Boot context. If a bean you add is of a type that would have been -included by default anyway (like `MappingJackson2HttpMessageConverter` for JSON -conversions) then it will replace the default value. A convenience bean is provided of -type `HttpMessageConverters` (always available if you use the default MVC configuration) -which has some useful methods to access the default and user-enhanced message converters -(useful, for example if you want to manually inject them into a custom `RestTemplate`). +`@RestController`). You can contribute additional converters by adding beans of the +appropriate type in a Spring Boot context. If a bean you add is of a type that would have been +included by default anyway (such as `MappingJackson2HttpMessageConverter` for JSON +conversions), it replaces the default value. A convenience bean of +type `HttpMessageConverters` is provided and is always available if you use the default MVC configuration. +It has some useful methods to access the default and user-enhanced message converters +(For example, it can be useful if you want to manually inject them into a custom `RestTemplate`). As in normal MVC usage, any `WebMvcConfigurer` beans that you provide can also -contribute converters by overriding the `configureMessageConverters` method, but unlike +contribute converters by overriding the `configureMessageConverters` method. However, unlike with normal MVC, you can supply only additional converters that you need (because Spring -Boot uses the same mechanism to contribute its defaults). Finally, if you opt-out of the +Boot uses the same mechanism to contribute its defaults). Finally, if you opt out of the Spring Boot default MVC configuration by providing your own `@EnableWebMvc` configuration, -then you can take control completely and do everything manually using +you can take control completely and do everything manually by using `getMessageConverters` from `WebMvcConfigurationSupport`. See the {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] @@ -1162,12 +1177,12 @@ source code for more details. [[howto-multipart-file-upload-configuration]] === Handling Multipart File Uploads Spring Boot embraces the Servlet 3 `javax.servlet.http.Part` API to support uploading -files. By default Spring Boot configures Spring MVC with a maximum file of 1MB per +files. By default, Spring Boot configures Spring MVC with a maximum size of 1MB per file and a maximum of 10MB of file data in a single request. You may override these -values, as well as the location to which intermediate data is stored (e.g., to the `/tmp` -directory) and the threshold past which data is flushed to disk by using the properties -exposed in the `MultipartProperties` class. If you want to specify that files be -unlimited, for example, set the `spring.servlet.multipart.max-file-size` property to `-1`. +values, the location to which intermediate data is stored (for example, to the `/tmp` +directory), and the threshold past which data is flushed to disk by using the properties +exposed in the `MultipartProperties` class. For example, if you want to specify that +files be unlimited, set the `spring.servlet.multipart.max-file-size` property to `-1`. The multipart support is helpful when you want to receive multipart encoded file data as a `@RequestParam`-annotated parameter of type `MultipartFile` in a Spring MVC controller @@ -1179,20 +1194,20 @@ source for more details. [[howto-switch-off-the-spring-mvc-dispatcherservlet]] -=== Switch off the Spring MVC DispatcherServlet -Spring Boot wants to serve all content from the root of your application `/` down. If you -would rather map your own servlet to that URL you can do it, but of course you may lose +=== Switch Off the Spring MVC DispatcherServlet +Spring Boot wants to serve all content from the root of your application (`/`) down. If you +would rather map your own servlet to that URL, you can do it. However, you may lose some of the other Boot MVC features. To add your own servlet and map it to the root -resource just 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). +resource, declare a `@Bean` of type `Servlet` and give it the special bean name, +`dispatcherServlet`. (You can also create a bean of a different type with that name if +you want to switch it off and not replace it.) [[howto-switch-off-default-mvc-configuration]] -=== Switch off the Default MVC configuration +=== Switch off the Default MVC Configuration The easiest way to take complete control over MVC configuration is to provide your own -`@Configuration` with the `@EnableWebMvc` annotation. This will leave all MVC +`@Configuration` with the `@EnableWebMvc` annotation. Doing so leaves all MVC configuration in your hands. @@ -1204,73 +1219,80 @@ A `ViewResolver` is a core component of Spring MVC, translating view names in used in UI applications, rather than REST-style services (a `View` is not used to render a `@ResponseBody`). There are many implementations of `ViewResolver` to choose from, and Spring on its own is not opinionated about which ones you should use. Spring Boot, on the -other hand, installs one or two for you depending on what it finds on the classpath and +other hand, installs one or two for you, depending on what it finds on the classpath and in the application context. The `DispatcherServlet` uses all the resolvers it finds in -the application context, trying each one in turn until it gets a result, so if you are -adding your own you have to be aware of the order and in which position your resolver is +the application context, trying each one in turn until it gets a result, so, if you +add your own, you have to be aware of the order and in which position your resolver is added. `WebMvcAutoConfiguration` adds the following `ViewResolvers` to your context: -* An `InternalResourceViewResolver` with bean id '`defaultViewResolver`'. This one locates - physical resources that can be rendered using the `DefaultServlet` (e.g. static - resources and JSP pages if you are using those). It applies a prefix and a suffix to the +* An `InternalResourceViewResolver` named '`defaultViewResolver`'. This one locates + physical resources that can be rendered by using the `DefaultServlet` (including static + resources and JSP pages, if you use those). It applies a prefix and a suffix to the view name and then looks for a physical resource with that path in the servlet context - (defaults are both empty, but accessible for external configuration via - `spring.mvc.view.prefix` and `spring.mvc.view.suffix`). It can be overridden by providing a - bean of the same type. -* A `BeanNameViewResolver` with id '`beanNameViewResolver`'. This is a useful member of the - view resolver chain and will pick up any beans with the same name as the `View` being - resolved. It shouldn't be necessary to override or replace it. -* A `ContentNegotiatingViewResolver` with id '`viewResolver`' is only added if there *are* + (the defaults are both empty but are accessible for external configuration through + `spring.mvc.view.prefix` and `spring.mvc.view.suffix`). You can override it by + providing a bean of the same type. +* A `BeanNameViewResolver` named '`beanNameViewResolver`'. This is a useful member of the + view resolver chain and picks up any beans with the same name as the `View` being + resolved. It should not be necessary to override or replace it. +* A `ContentNegotiatingViewResolver` named '`viewResolver`' is added only if there *are* actually beans of type `View` present. This is a '`master`' resolver, delegating to all the others and attempting to find a match to the '`Accept`' HTTP header sent by the client. There is a useful https://spring.io/blog/2013/06/03/content-negotiation-using-views[blog about `ContentNegotiatingViewResolver`] - that you might like to study to learn more, and 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 will also have a `ThymeleafViewResolver` with id + that you might like to study to learn more, and you might also look at the source code + for detail. You can switch off the auto-configured `ContentNegotiatingViewResolver` by + defining a bean named '`viewResolver`'. +* If you use Thymeleaf, you also have a `ThymeleafViewResolver` named '`thymeleafViewResolver`'. It looks for resources by surrounding the view name with a - prefix and suffix (externalized to `spring.thymeleaf.prefix` and - `spring.thymeleaf.suffix`, defaults '`classpath:/templates/`' and '`.html`' - respectively). It can be overridden by providing a bean of the same name. -* If you use FreeMarker you will also have a `FreeMarkerViewResolver` with id - '`freeMarkerViewResolver`'. It looks for resources in a loader path (externalized to - `spring.freemarker.templateLoaderPath`, default '`classpath:/templates/`') by - surrounding the view name with a prefix and suffix (externalized to `spring.freemarker.prefix` - and `spring.freemarker.suffix`, with empty and '`.ftl`' defaults respectively). It can - be overridden by providing a bean of the same name. -* If you use Groovy templates (actually if groovy-templates is on your classpath) you will - also have a `GroovyMarkupViewResolver` with id '`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`, defaults '`classpath:/templates/`' and '`.tpl`' - respectively). It can be overridden by providing a bean of the same name. - -Check out {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`] and -{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`]. + 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`] [[howto-http-clients]] -== HTTP clients - +== HTTP Clients +Spring Boot offers a number of starters that work with HTTP clients. This section answers +questions related to doing so. [[howto-http-clients-proxy-configuration]] -=== Configure RestTemplate to use a proxy +=== Configure RestTemplate to Use a Proxy As described in <>, -a `RestTemplateCustomizer` can be used with `RestTemplateBuilder` to build a customized +you can use a `RestTemplateCustomizer` with `RestTemplateBuilder` to build a customized `RestTemplate`. This is the recommended approach for creating a `RestTemplate` configured to use a proxy. The exact details of the proxy configuration depend on the underlying client request -factory that is being used. Here's an example of configuring +factory that is being used. The following example configures `HttpComponentsClientRequestFactory` with an `HttpClient` that uses a proxy for all hosts -except `192.168.0.5`. +except `192.168.0.5`: [source,java,indent=0] ---- @@ -1283,12 +1305,12 @@ include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[t == Logging Spring Boot has no mandatory logging dependency, except for the Commons Logging API, of -which there are many implementations to choose from. To use http://logback.qos.ch[Logback] +which there are many implementations to choose from. To use http://logback.qos.ch[Logback], you need to include it and `jcl-over-slf4j` (which implements the Commons Logging API) on -the classpath. The simplest way to do that is through the starters which all depend on -`spring-boot-starter-logging`. For a web application you only need -`spring-boot-starter-web` since it depends transitively on the logging starter. For -example, using Maven: +the classpath. The simplest way to do that is through the starters, which all depend on +`spring-boot-starter-logging`. For a web application, you need only +`spring-boot-starter-web`, since it depends transitively on the logging starter. If you +use Maven, the following dependency adds logging for you: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1299,10 +1321,11 @@ example, using Maven: ---- Spring Boot has a `LoggingSystem` abstraction that attempts to configure logging based on -the content of the classpath. If Logback is available it is the first choice. +the content of the classpath. If Logback is available, it is the first choice. -If the only change you need to make to logging is to set the levels of various loggers -then you can do that in `application.properties` using the "logging.level" prefix, e.g. +If the only change you need to make to logging is to set the levels of various loggers, +you can do so in `application.properties` by using the "logging.level" prefix, as shown +in the following example: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1310,24 +1333,23 @@ then you can do that in `application.properties` using the "logging.level" prefi logging.level.org.hibernate=ERROR ---- -You can also set the location of a file to log to (in addition to the console) using -"logging.file". +You can also set the location of a file to which to write the log (in addition to the +console) by using "logging.file". -To configure the more fine-grained settings of a logging system you need to use the native -configuration format supported by the `LoggingSystem` in question. By default Spring Boot -picks up the native configuration from its default location for the system (e.g. -`classpath:logback.xml` for Logback), but you can set the location of the config file +To configure the more fine-grained settings of a logging system, you need to use the native +configuration format supported by the `LoggingSystem` in question. By default, Spring Boot +picks up the native configuration from its default location for the system (such as +`classpath:logback.xml` for Logback), but you can set the location of the config file by using the "logging.config" property. [[howto-configure-logback-for-logging]] -=== Configure Logback for logging -If you put a `logback.xml` in the root of your classpath it will be picked up from -there -(or `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 just -want to set levels, e.g. +=== Configure Logback for Logging +If you put a `logback.xml` in the root of your classpath, it is picked up from there (or +from `logback-spring.xml`, to take advantage of the templating features provided by +Boot). Spring Boot provides a default base configuration that you can include if you +want to set levels, as shown in the following example: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1338,30 +1360,30 @@ want to set levels, e.g. ---- -If you look at that `base.xml` in the spring-boot jar, you will see that it uses -some useful System properties which the `LoggingSystem` takes care of creating for you. -These are: +If you look at `base.xml` in the spring-boot jar, you can see that it uses +some useful System properties that the `LoggingSystem` takes care of creating for you: -* `${PID}` the current process ID. -* `${LOG_FILE}` if `logging.file` was set in Boot's external configuration. -* `${LOG_PATH}` if `logging.path` was set (representing a directory for - log files to live in). -* `${LOG_EXCEPTION_CONVERSION_WORD}` if `logging.exception-conversion-word` was set in - Boot's external configuration. +* `${PID}`: The current process ID. +* `${LOG_FILE}`: Whether `logging.file` was set in Boot's external configuration. +* `${LOG_PATH}`: Whether `logging.path` (representing a directory for + log files to live in) was set in Boot's external configuration. +* `${LOG_EXCEPTION_CONVERSION_WORD}`: Whether `logging.exception-conversion-word` was set + in Boot's external configuration. -Spring Boot also provides some nice ANSI colour terminal output on a console (but not in -a log file) using a custom Logback converter. See the default `base.xml` configuration +Spring Boot also provides some nice ANSI color terminal output on a console (but not in +a log file) by using a custom Logback converter. See the default `base.xml` configuration for details. -If Groovy is on the classpath you should be able to configure Logback with -`logback.groovy` as well (it will be given preference if present). +If Groovy is on the classpath, you should be able to configure Logback with +`logback.groovy` as well. If present, this setting is given preference. [[howto-configure-logback-for-logging-fileonly]] -==== Configure logback for file only output -If you want to disable console logging and write output only to a file you need a custom -`logback-spring.xml` that imports `file-appender.xml` but not `console-appender.xml`: +==== Configure Logback for File-only Output +If you want to disable console logging and write output only to a file, you need a custom +`logback-spring.xml` that imports `file-appender.xml` but not `console-appender.xml`, as +shown in the following example: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1376,7 +1398,8 @@ If you want to disable console logging and write output only to a file you need ---- -You also need to add `logging.file` to your `application.properties`: +You also need to add `logging.file` to your `application.properties`, as shown in the +following example: [source,properties,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1386,15 +1409,15 @@ You also need to add `logging.file` to your `application.properties`: [[howto-configure-log4j-for-logging]] -=== Configure Log4j for logging +=== Configure Log4j for Logging Spring Boot supports http://logging.apache.org/log4j/2.x[Log4j 2] for logging -configuration if it is on the classpath. If you are using the starters for -assembling dependencies that means you have to exclude Logback and then include log4j 2 -instead. If you aren't using the starters then you need to provide `jcl-over-slf4j` -(at least) in addition to Log4j 2. +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. The simplest path is probably through the starters, even though it requires some -jiggling with excludes, .e.g. in Maven: +jiggling with excludes. The following example shows how to set up the starters in Maven: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1418,19 +1441,20 @@ jiggling with excludes, .e.g. in Maven: ---- -NOTE: The use of the Log4j starters gathers together the dependencies for common logging -requirements (e.g. including having Tomcat use `java.util.logging` but configuring the -output using Log4j 2). See the Actuator Log4j 2 samples for more detail and to see it in -action. +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. [[howto-configure-log4j-for-logging-yaml-or-json-config]] -==== Use YAML or JSON to configure Log4j 2 +==== Use YAML or JSON to Configure Log4j 2 In addition to its default XML configuration format, Log4j 2 also supports YAML and JSON configuration files. To configure Log4j 2 to use an alternative configuration file format, add the appropriate dependencies to the classpath and name your -configuration files to match your chosen file format: +configuration files to match your chosen file format, as shown in the following example: [cols="10,75,15"] |=== @@ -1451,15 +1475,18 @@ a| `log4j2.json` + [[howto-data-access]] == Data Access - +Spring Boot includes a number of starters for working with data sources. This section +answers questions related to doing so. [[howto-configure-a-datasource]] -=== Configure a custom DataSource -To configure your own `DataSource` define a `@Bean` of that type in your configuration. -Spring Boot will reuse your `DataSource` anywhere one is required, including database -initialization. If you need to externalize some settings, you can easily bind your +=== Configure a Custom DataSource +To configure your own `DataSource`, define a `@Bean` of that type in your configuration. +Spring Boot reuses your `DataSource` anywhere one is required, including database +initialization. If you need to externalize some settings, you can bind your `DataSource` to the environment (see -<>). +"`<>`"). + +The following example shows how to define a data source in a bean: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1470,6 +1497,8 @@ initialization. If you need to externalize some settings, you can easily bind yo } ---- +The following example shows how to define a data source by setting properties: + [source,properties,indent=0] ---- app.datasource.url=jdbc:h2:mem:mydb @@ -1477,14 +1506,15 @@ initialization. If you need to externalize some settings, you can easily bind yo app.datasource.pool-size=30 ---- -Assuming that your `FancyDataSource` has regular JavaBean properties for the url, the -username and the pool size, these settings will be bound automatically before the +Assuming that your `FancyDataSource` has regular JavaBean properties for the URL, the +username, and the pool size, these settings are bound automatically before the `DataSource` is made available to other components. The regular -<> will also happen +<> also happens (so the relevant sub-set of `spring.datasource.*` can still be used with your custom configuration). -You can apply the same principle if you are configuring a custom JNDI `DataSource`: +You can apply the same principle if you configure a custom JNDI `DataSource`, as shown in +the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1496,20 +1526,24 @@ You can apply the same principle if you are configuring a custom JNDI `DataSourc } ---- -Spring Boot also provides a utility builder class `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. +Spring Boot also provides a utility builder class, called `DataSourceBuilder`, that can +be used to create one of the standard data sources (if it is on the classpath). The +builder can detect the one to use based on what's available on the classpath. It also +auto-detects the driver based on the JDBC URL. + +The following example shows how to create a data source by using a `DataSourceBuilder`: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- include::{code-examples}/jdbc/BasicDataSourceExample.java[tag=configuration] ---- -To run an app with that `DataSource`, all that is needed really is the connection -information; pool-specific settings can also be provided, check the implementation that +To run an app with that `DataSource`, all you need is the connection +information. Pool-specific settings can also be provided. Check the implementation that is going to be used at runtime for more details. +The following example shows how to deine a JDBC data source by setting properties: + [source,properties,indent=0] ---- app.datasource.url=jdbc:mysql://localhost/test @@ -1518,11 +1552,11 @@ is going to be used at runtime for more details. app.datasource.pool-size=30 ---- -There is a catch however. Because the actual type of the connection pool is not exposed, +However, there is a catch. Because the actual type of the connection pool is not exposed, no keys are generated in the metadata for your custom `DataSource` and no completion is -available in your IDE (The `DataSource` interface doesn't expose any property). Also, if -you happen to have Hikari on the classpath, this basic setup will not work because Hikari -has no `url` property (but a `jdbcUrl` property). You will have to rewrite your +available in your IDE (because the `DataSource` interface exposes no properties). Also, if +you happen to have Hikari on the classpath, this basic setup does not work, because Hikari +has no `url` property (but does have a `jdbcUrl` property). In that case, you must rewrite your configuration as follows: [source,properties,indent=0] @@ -1534,32 +1568,34 @@ configuration as follows: ---- You can fix that by forcing the connection pool to use and return a dedicated -implementation rather than `DataSource`. You won't be able to change the implementation -at runtime but the list of options will be explicit. +implementation rather than `DataSource`. You cannot change the implementation +at runtime, but the list of options will be explicit. + +The following example shows how create a `HikariDataSource` with `DataSourceBuilder`: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- include::{code-examples}/jdbc/SimpleDataSourceExample.java[tag=configuration] ---- -You can even go further by leveraging what `DataSourceProperties` does for you, that is -providing a default embedded database if no url is provided with a sensible username and -password for it. You can easily initialize a `DataSourceBuilder` from the state of any -`DataSourceProperties` so you could just as well inject the one Spring Boot creates -automatically. However, that would split your configuration in two namespaces: url, -username, password, type and driver on `spring.datasource` and the rest on your custom +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 namespace (`app.datasource`). To avoid that, you can redefine a custom -`DataSourceProperties` on your custom namespace: +`DataSourceProperties` on your custom namespace, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configuration] ---- -This setup puts you _in pair_ with what Spring Boot does for you by default, except that +This setup puts you _in sync_ with what Spring Boot does for you by default, except that a dedicated connection pool is chosen (in code) and its settings are exposed in the same namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl` -translation for you, you can configure it like this: +translation for you, you can configure it as follows: [source,properties,indent=0] ---- @@ -1570,10 +1606,10 @@ translation for you, you can configure it like this: ---- NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type` -will have no effect. In practice the builder will be initialized with whatever value you +has no effect. In practice, the builder is initialized with whatever value you might set there and then overridden by the call to `.type()`. -See _<>_ in the +See "`<>`" in the '`Spring Boot features`' section and the {sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`] class for more details. @@ -1583,12 +1619,12 @@ class for more details. [[howto-two-datasources]] === Configure Two DataSources If you need to configure multiple data sources, you can apply the same tricks that are -described in the previous section. You must, however, mark one of the `DataSource` -`@Primary` as various auto-configurations down the road expect to be able to get one by +described in the previous section. You must, however, mark one of the `DataSource` instances as +`@Primary`, because various auto-configurations down the road expect to be able to get one by type. -If you create your own `DataSource`, the auto-configuration will back off. In the example -below, we provide the _exact_ same features set as what the auto-configuration provides +If you create your own `DataSource`, the auto-configuration backs off. In the following +example, we provide the _exact_ same feature set as the auto-configuration provides on the primary data source: [source,java,indent=0,subs="verbatim,quotes,attributes"] @@ -1596,10 +1632,10 @@ on the primary data source: include::{code-examples}/jdbc/SimpleTwoDataSourcesExample.java[tag=configuration] ---- -TIP: `fooDataSourceProperties` has to be flagged `@Primary` so that the database -initializer feature uses your copy (should you use that). +TIP: `fooDataSourceProperties` has to be flagged as `@Primary` so that the database +initializer feature uses your copy (if you use the initializer). -Both data sources are also bound for advanced customizations. For instance you could +Both data sources are also bound for advanced customizations. For instance, you could configure them as follows: [source,properties,indent=0] @@ -1613,30 +1649,31 @@ configure them as follows: app.datasource.bar.max-total=30 ---- -Of course, you can apply the same concept to the secondary `DataSource` as well: +You can apply the same concept to the secondary `DataSource` as well, as shown in the +following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- include::{code-examples}/jdbc/CompleteTwoDataSourcesExample.java[tag=configuration] ---- -This final example configures two data sources on custom namespaces with the same logic -as what Spring Boot would do in auto-configuration. +The preceding example configures two data sources on custom namespaces with the same +logic as Spring Boot would use in auto-configuration. [[howto-use-spring-data-repositories]] -=== Use Spring Data repositories +=== Use Spring Data Repositories Spring Data can create implementations for you of `@Repository` interfaces of various -flavors. Spring Boot will handle all of that for you as long as those `@Repositories` +flavors. Spring Boot handles all of that for you, as long as those `@Repositories` are included in the same package (or a sub-package) of your `@EnableAutoConfiguration` class. -For many applications all you will need is to put the right Spring Data dependencies on +For many applications, all you need is to put the right Spring Data dependencies on your classpath (there is a `spring-boot-starter-data-jpa` for JPA and a -`spring-boot-starter-data-mongodb` for Mongodb), create some repository interfaces to handle your +`spring-boot-starter-data-mongodb` for Mongodb) and create some repository interfaces to handle your `@Entity` objects. Examples are in the {github-code}/spring-boot-samples/spring-boot-sample-data-jpa[JPA sample] -or the {github-code}/spring-boot-samples/spring-boot-sample-data-mongodb[Mongodb sample]. +and the {github-code}/spring-boot-samples/spring-boot-sample-data-mongodb[Mongodb sample]. Spring Boot tries to guess the location of your `@Repository` definitions, based on the `@EnableAutoConfiguration` it finds. To get more control, use the `@EnableJpaRepositories` @@ -1644,10 +1681,10 @@ annotation (from Spring Data JPA). [[howto-separate-entity-definitions-from-spring-configuration]] -=== Separate @Entity definitions from Spring configuration +=== Separate @Entity Definitions from Spring Configuration Spring Boot tries to guess the location of your `@Entity` definitions, based on the `@EnableAutoConfiguration` it finds. To get more control, you can use the `@EntityScan` -annotation, e.g. +annotation, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1664,27 +1701,27 @@ annotation, e.g. [[howto-configure-jpa-properties]] -=== Configure JPA properties -Spring Data JPA already provides some vendor-independent configuration options (e.g. -for SQL logging) and Spring Boot exposes those, and a few more for hibernate as external +=== Configure JPA Properties +Spring Data JPA already provides some vendor-independent configuration options (such as those +for SQL logging), and Spring Boot exposes those options and a few more for Hibernate as external configuration properties. Some of them are automatically detected according to the context -so you shouldn't have to set them. +so you should not have to set them. -The `spring.jpa.hibernate.ddl-auto` is a special case in that it has different defaults -depending on runtime conditions. If an embedded database is used and no schema manager, -such as Liquibase or Flyway, is handling the `DataSource` it then defaults to -`create-drop`. In all other cases it defaults to `none`. +The `spring.jpa.hibernate.ddl-auto` is a special case, because, depending on runtime +conditions, it has different defaults. If an embedded database is used and no schema manager +(such as Liquibase or Flyway) is handling the `DataSource`, it defaults to +`create-drop`. In all other cases, it defaults to `none`. -The dialect to use is also automatically detected based on the current `DataSource` but +The dialect to use is also automatically detected based on the current `DataSource`, but you can set `spring.jpa.database` yourself if you want to be explicit and bypass that check on startup. NOTE: Specifying a `database` leads to the configuration of a well-defined Hibernate -dialect. Several databases have more than one `Dialect` and this may not suit your need. +dialect. Several databases have more than one `Dialect`, and this may not suit your need. In that case, you can either set `spring.jpa.database` to `default` to let Hibernate figure -things out or set the dialect using the `spring.jpa.database-platform` property. +things out or set the dialect by setting the `spring.jpa.database-platform` property. -The most common options to set are: +The most common options to set are shown in the following example: [indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1692,7 +1729,7 @@ The most common options to set are: spring.jpa.show-sql=true ---- -In addition all properties in `+spring.jpa.properties.*+` are passed through as normal JPA +In addition, all properties in `+spring.jpa.properties.*+` are passed through as normal JPA properties (with the prefix stripped) when the local `EntityManagerFactory` is created. @@ -1700,20 +1737,20 @@ properties (with the prefix stripped) when the local `EntityManagerFactory` is c [[howto-configure-hibernate-naming-strategy]] === Configure Hibernate Naming Strategy Hibernate uses {hibernate-documentation}#naming[two different naming strategies] to map -names from the object model to the corresponding database names. The fully qualified class -name of the physical and implicit strategy implementations can be configured using the -`spring.jpa.hibernate.naming.physical-strategy` and -`spring.jpa.hibernate.naming.implicit-strategy` properties respectively. - -Spring Boot configures the physical naming strategy with `SpringPhysicalNamingStrategy` by -default. This implementation provides the same table structure as Hibernate 4: all dots -are replaced by underscores and camel cases are replaced by underscores as well. By -default, all table names are generated in lower case but it is possible to override that +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 flag if your schema requires it. -Concretely, a `TelephoneNumber` entity will be mapped to the `telephone_number` table. +For example, a `TelephoneNumber` entity is mapped to the `telephone_number` table. -If you'd rather use Hibernate 5's default instead, set the following property: +If you prefer to use Hibernate 5's default instead, set the following property: [indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1728,22 +1765,21 @@ for more details. [[howto-use-custom-entity-manager]] -=== Use a custom EntityManagerFactory +=== Use a Custom EntityManagerFactory To take full control of the configuration of the `EntityManagerFactory`, you need to add a `@Bean` named '`entityManagerFactory`'. Spring Boot auto-configuration switches off its -entity manager based on the presence of a bean of that type. +entity manager in the presence of a bean of that type. [[howto-use-two-entity-managers]] === Use Two EntityManagers -Even if the default `EntityManagerFactory` works fine, you will need to define a new one -because otherwise the presence of the second bean of that type will switch off the -default. To make it easy to do that you can use the convenient `EntityManagerBuilder` -provided by Spring Boot, or if you prefer you can just use the -`LocalContainerEntityManagerFactoryBean` directly from Spring ORM. - -Example: +Even if the default `EntityManagerFactory` works fine, you need to define a new one. +Otherwise, the presence of the second bean of that type switches off the +default. To make it easy to do, you can use the convenient `EntityManagerBuilder` +provided by Spring Boot. Alternatively, you can just the +`LocalContainerEntityManagerFactoryBean` directly from Spring ORM, as shown in the +following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1770,13 +1806,14 @@ Example: } ---- -The configuration above almost works on its own. To complete the picture you need to +The configuration above almost works on its own. To complete the picture, you need to 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 -`@Primary`. The other would have to be explicitly injected into a new instance. Or you -might be able to use a JTA transaction manager spanning both. +`@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. -If you are using Spring Data, you need to configure `@EnableJpaRepositories` accordingly: +If you are using Spring Data, you need to configure `@EnableJpaRepositories` accordingly, +as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -1798,11 +1835,11 @@ If you are using Spring Data, you need to configure `@EnableJpaRepositories` acc [[howto-use-traditional-persistence-xml]] -=== Use a traditional persistence.xml -Spring doesn't 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` -then you need to define your own `@Bean` of type `LocalEntityManagerFactoryBean` (with -id '`entityManagerFactory`', and set the persistence unit name there. +=== Use a Traditional `persistence.xml` File +Spring does not require the use of XML to configure the JPA provider, and Spring Boot +assumes you want to take advantage of that feature. If you prefer to use `persistence.xml`, +you need to define your own `@Bean` of type `LocalEntityManagerFactoryBean` (with +an ID of '`entityManagerFactory`') and set the persistence unit name there. See {sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBaseConfiguration`] @@ -1811,57 +1848,57 @@ for the default settings. [[howto-use-spring-data-jpa--and-mongo-repositories]] -=== Use Spring Data JPA and Mongo repositories - -Spring Data JPA and Spring Data Mongo can both create `Repository` implementations for you -automatically. 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 -`+@Enable*Repositories+` and tell it the location of your `Repository` interfaces -(where '`*`' is '`Jpa`' or '`Mongo`' or both). - -There are also flags `+spring.data.*.repositories.enabled+` that you can use to switch the -auto-configured repositories on and off in external configuration. This is useful for -instance in case you want to switch off the Mongo repositories and still use the +=== 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 auto-configured `MongoTemplate`. The same obstacle and the same features exist for other auto-configured Spring Data -repository types (Elasticsearch, Solr). Just change the names of the annotations and flags -respectively. +repository types (Elasticsearch, Solr, and others). To work with them, change the names of the annotations and flags +accordingly. [[howto-use-exposing-spring-data-repositories-rest-endpoint]] -=== Expose Spring Data repositories as REST endpoint -Spring Data REST can expose the `Repository` implementations as REST endpoints for you as -long as Spring MVC has been enabled for the application. +=== Expose Spring Data Repositories as REST Endpoint +Spring Data REST can expose the `Repository` implementations as REST endpoints for you, +provided Spring MVC has been enabled for the application. -Spring Boot exposes a set of useful properties from the `spring.data.rest` namespace that +Spring Boot exposes a set of useful properties (from the `spring.data.rest` namespace) that customize the {spring-data-rest-javadoc}/core/config/RepositoryRestConfiguration.{dc-ext}[`RepositoryRestConfiguration`]. If you need to provide additional customization, you should use a {spring-data-rest-javadoc}/webmvc/config/RepositoryRestConfigurer.{dc-ext}[`RepositoryRestConfigurer`] bean. -NOTE: If you don't specify any order on your custom `RepositoryRestConfigurer` it will run +NOTE: If you do not specify any order on your custom `RepositoryRestConfigurer`, it runs after the one Spring Boot uses internally. If you need to specify an order, make sure it is higher than 0. [[howto-configure-a-component-that-is-used-by-JPA]] -=== Configure a component that is used by JPA -If you want to configure a component that will be used by JPA then you need to ensure -that the component is initialized before JPA. Where the component is auto-configured -Spring Boot will take care of this for you. For example, when Flyway is auto-configured, -Hibernate is configured to depend upon Flyway so that the latter has a chance to +=== Configure a Component that is Used by JPA +If you want to configure a component that JPA uses, then you need to ensure +that the component is initialized before JPA. When the component is auto-configured, +Spring Boot takes care of this for you. For example, when Flyway is auto-configured, +Hibernate is configured to depend upon Flyway so that Flyway has a chance to initialize the database before Hibernate tries to use it. If you are configuring a component yourself, you can use an `EntityManagerFactoryDependsOnPostProcessor` subclass as a convenient way of setting up -the necessary dependencies. For example, if you are using Hibernate Search with -Elasticsearch as its index manager then any `EntityManagerFactory` beans must be -configured to depend on the `elasticsearchClient` bean: +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: [source,java,indent=0] ---- @@ -1871,100 +1908,102 @@ include::{code-examples}/elasticsearch/HibernateSearchElasticsearchExample.java[ [[howto-database-initialization]] -== Database initialization -An SQL database can be initialized in different ways depending on what your stack is. Or -of course you can do it manually as long as the database is a separate process. +== Database Initialization +An SQL database can be initialized in different ways depending on what your stack is. +Of course, you can also do it manually, provided the database is a separate process. [[howto-initialize-a-database-using-jpa]] -=== Initialize a database using JPA +=== Initialize a Database Using JPA JPA has features for DDL generation, and these can be set up to run on startup against the database. This is controlled through two external properties: * `spring.jpa.generate-ddl` (boolean) switches the feature on and off and is vendor independent. * `spring.jpa.hibernate.ddl-auto` (enum) is a Hibernate feature that controls the - behavior in a more fine-grained way. See below for more detail. + behavior in a more fine-grained way. This feature is described in more detail later in + the document. [[howto-initialize-a-database-using-hibernate]] -=== Initialize a database using Hibernate +=== Initialize a Database Using Hibernate You can set `spring.jpa.hibernate.ddl-auto` explicitly and the standard Hibernate property -values are `none`, `validate`, `update`, `create`, `create-drop`. Spring Boot chooses a -default value for you based on whether it thinks your database is embedded: default to -`create-drop` if no schema manager has been detected, `none` in all other cases. An -embedded database is detected by looking at the `Connection` type: `hsqldb`, `h2` and -`derby` are embedded, the rest are not. Be careful when switching from in-memory to a -'`real`' database that you don't 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 +values are `none`, `validate`, `update`, `create`, and `create-drop`. Spring Boot chooses a +default value for you based on whether it thinks your database is embedded. It defaults to +`create-drop` if no schema manager has been detected or `none` in all other cases. An +embedded database is detected by looking at the `Connection` type. `hsqldb`, `h2`, and +`derby` are embedded, and others are not. Be careful when switching from in-memory to a +'`real`' database that you do not make assumptions about the existence of the tables and +data in the new platform. You either have to set `ddl-auto` explicitly or use one of the other mechanisms to initialize the database. NOTE: You can output the schema creation by enabling the `org.hibernate.SQL` logger. This is done for you automatically if you enable the <>. -In addition, a file named `import.sql` in the root of the classpath will be executed on -startup if Hibernate creates the schema from scratch (that is if the `ddl-auto` property +In addition, a file named `import.sql` in the root of the classpath is executed on +startup if Hibernate creates the schema from scratch (that is, if the `ddl-auto` property is set to `create` or `create-drop`). This can be useful for demos and for testing if you -are careful, but probably not something you want to be on the classpath in production. It -is a Hibernate feature (nothing to do with Spring). +are careful but is probably not something you want to be on the classpath in production. It +is a Hibernate feature (and has nothing to do with Spring). [[howto-initialize-a-database-using-spring-jdbc]] -=== Initialize a database +=== Initialize a Database Spring Boot can automatically create the schema (DDL scripts) of your `DataSource` and -initialize it (DML scripts): it loads SQL from the standard root classpath locations -`schema.sql` and `data.sql`, respectively. In addition Spring Boot will process the +initialize it (DML scripts). It loads SQL from the standard root classpath locations: +`schema.sql` and `data.sql`, respectively. In addition, Spring Boot processes the `schema-${platform}.sql` and `data-${platform}.sql` files (if present), where `platform` -is the value of `spring.datasource.platform`. This allows you to switch to database -specific scripts if necessary, e.g. you might choose to set it to the vendor name of the -database (`hsqldb`, `h2`, `oracle`, `mysql`, `postgresql` etc.). +is the value of `spring.datasource.platform`. This allows you to switch to +database-specific scripts if necessary. For example, you might choose to set it to the +vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`, `postgresql`, and so on). Spring Boot automatically creates the schema of an embedded `DataSource`. This behavior -can be customized using the `spring.datasource.initialization-mode` property (can also be -`always` or `never`). +can be customized by using the `spring.datasource.initialization-mode` property (and it +can also be `always` or `never`). -Spring Boot enables the fail-fast feature of the Spring JDBC initializer by default, so if -the scripts cause exceptions the application will fail to start. You can tune that using -`spring.datasource.continue-on-error`. +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`. NOTE: In a JPA-based app, you can choose to let Hibernate create the schema or use -`schema.sql` but not both. Make sure to disable `spring.jpa.hibernate.ddl-auto` if you -chose the later. +`schema.sql`, but you cannot do both. Make sure to disable +`spring.jpa.hibernate.ddl-auto` if you use `schema.sql`. [[howto-initialize-a-spring-batch-database]] -=== Initialize a Spring Batch database -If you are using Spring Batch then it comes pre-packaged with SQL initialization scripts +=== Initialize a Spring Batch Database +If you use Spring Batch, it comes pre-packaged with SQL initialization scripts for most popular database platforms. Spring Boot can detect your database type and -execute those scripts on startup. If you are using an embedded database this happens -by default. You can also enable it for any database type: +execute those scripts on startup. If you use an embedded database, this happens +by default. You can also enable it for any database type, as shown in the following +example: [indent=0,subs="verbatim,quotes,attributes"] ---- spring.batch.initialize-schema=always ---- -You can also switch off the initialization explicitly using +You can also switch off the initialization explicitly by setting `spring.batch.initialize-schema=never`. [[howto-use-a-higher-level-database-migration-tool]] -=== Use a higher-level database migration tool +=== Use a Higher-level Database Migration Tool Spring Boot supports two higher-level migration tools: http://flywaydb.org/[Flyway] and http://www.liquibase.org/[Liquibase]. [[howto-execute-flyway-database-migrations-on-startup]] -==== Execute Flyway database migrations on startup +==== Execute Flyway Database Migrations on Startup To automatically run Flyway database migrations on startup, add the `org.flywaydb:flyway-core` to your classpath. The migrations are scripts in the form `V__.sql` (with `` an -underscore-separated version, e.g. '`1`' or '`2_1`'). By default they live in a folder -`classpath:db/migration` but you can modify that using `spring.flyway.locations`. You can +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 also add a special `{vendor}` placeholder to use vendor-specific scripts. Assume the following: @@ -1973,88 +2012,89 @@ following: spring.flyway.locations=db/migration/{vendor} ---- -Rather than using `db/migration`, this configuration will set the folder to use according -to the type of the database (i.e. `db/migration/mysql` for MySQL). The list of supported +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 database are available in {sc-spring-boot}/jdbc/DatabaseDriver.{sc-ext}[`DatabaseDriver`]. -See also the Flyway class from flyway-core for details of available settings like schemas -etc. 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 will call `Flyway.migrate()` to perform the database migration. If you would like +See the Flyway class from flyway-core for details of available settings such as schemas +and others. In addition, Spring Boot provides a small set of properties (in +{sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`]) +that can be used to disable the migrations or switch off the location checking. Spring +Boot calls `Flyway.migrate()` to perform the database migration. If you would like more control, provide a `@Bean` that implements {sc-spring-boot-autoconfigure}/flyway/FlywayMigrationStrategy.{sc-ext}[`FlywayMigrationStrategy`]. Flyway supports SQL and Java 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 -`FlywayCallback` or, preferably, extend `BaseFlywayCallback`. Any such beans will be -automatically registered with `Flyway`. They can be ordered using `@Order` or by +`FlywayCallback` or, preferably, extend `BaseFlywayCallback`. Any such beans are +automatically registered with `Flyway`. They can be ordered by using `@Order` or by implementing `Ordered`. -By default Flyway will autowire the (`@Primary`) `DataSource` in your context and -use that for migrations. If you like to use a different `DataSource` you can create -one and mark its `@Bean` as `@FlywayDataSource` - if you do that remember to create -another one and mark it as `@Primary` if you want two data sources. -Or you can use Flyway's native `DataSource` by setting `spring.flyway.[url,user,password]` +By default, Flyway autowires the (`@Primary`) `DataSource` in your context and +uses that for migrations. If you like to use a different `DataSource`, you can create +one and mark its `@Bean` as `@FlywayDataSource`. If you do so and want two data sources, +remember to create another one and mark it as `@Primary`. Alternatively, you can use +Flyway's native `DataSource` by setting `spring.flyway.[url,user,password]` in external properties. There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so -you can see how to set things up. +that you can see how to set things up. You can also use Flyway to provide data for specific scenarios. For example, you can -place test-specific migrations in `src/test/resources` and they will only be run when your -application starts for testing. If you want to be more sophisticated you can use +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 profile-specific configuration to customize `spring.flyway.locations` so that certain -migrations will only run when a particular profile is active. For example, in -`application-dev.properties`: +migrations run only when a particular profile is active. For example, in +`application-dev.properties`, you might specify the following setting: [source,properties,indent=0] ---- spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration ---- -With that setup, migrations in `dev/db/migration` will only run when the `dev` profile is +With that setup, migrations in `dev/db/migration` run only when the `dev` profile is active. [[howto-execute-liquibase-database-migrations-on-startup]] -==== Execute Liquibase database migrations on startup +==== Execute Liquibase Database Migrations on Startup To automatically run Liquibase database migrations on startup, add the `org.liquibase:liquibase-core` to your classpath. -The master change log is by default read from `db/changelog/db.changelog-master.yaml` but -can be set using `spring.liquibase.change-log`. In addition to YAML, Liquibase also +By default, the master change log is read from `db/changelog/db.changelog-master.yaml`, but +you can change the location by setting `spring.liquibase.change-log`. In addition to YAML, Liquibase also supports JSON, XML, and SQL change log formats. -By default Liquibase will autowire the (`@Primary`) `DataSource` in your context and use -that for migrations. If you like to use a different `DataSource` you can create one and -mark its `@Bean` as `@LiquibaseDataSource` - if you do that remember to create another one -and mark it as `@Primary` if you want two data sources. Or you can use Liquibase's native +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 `DataSource` by setting `spring.liquibase.[url,user,password]` in external properties. See {sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[`LiquibaseProperties`] -for details of available settings like contexts, default schema etc. +for details about available settings such as contexts, the default schema, and others. There is a {github-code}/spring-boot-samples/spring-boot-sample-liquibase[Liquibase sample] -so you can see how to set things up. +so that you can see how to set things up. [[howto-messaging]] == Messaging - +Spring Boot offers a number of starters that include messaging. This section answers +questions that arise from using messaging with Spring Boot. [[howto-jms-disable-transaction]] -=== Disable transacted JMS session -If your JMS broker does not support transacted session, you will have to disable the -support of transactions altogether. If you create your own `JmsListenerContainerFactory` -there is nothing to do since it won't be transacted by default. If you want to use +=== 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 the `DefaultJmsListenerContainerFactoryConfigurer` to reuse Spring Boot's default, you -can disable transacted session as follows: +can disable transacted session, as follows: [source,java,indent=0] ---- @@ -2071,34 +2111,34 @@ can disable transacted session as follows: } ---- -This overrides the default factory and this should be applied to any other factory that -your application defines, if any. +The preceding example overrides the default factory, and it should be applied to any +other factory that your application defines, if any. [[howto-batch-applications]] -== Batch applications +== Batch Applications NOTE: By default, batch applications require a `DataSource` to store job details. If you -want to deviate from that, you'll need to implement `BatchConfigurer`, see +want to deviate from that, you need to implement `BatchConfigurer`. See {spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[The Javadoc of `@EnableBatchProcessing`] for more details. [[howto-execute-spring-batch-jobs-on-startup]] -=== Execute Spring Batch jobs on startup +=== Execute Spring Batch Jobs on Startup Spring Batch auto-configuration is enabled by adding `@EnableBatchProcessing` (from Spring Batch) somewhere in your context. -By default it executes *all* `Jobs` in the application context on startup (see +By default, it executes *all* `Jobs` in the application context on startup (see {sc-spring-boot-autoconfigure}/batch/JobLauncherCommandLineRunner.{sc-ext}[JobLauncherCommandLineRunner] for details). You can narrow down to a specific job or jobs by specifying `spring.batch.job.names` (comma-separated job name patterns). -If the application context includes a `JobRegistry` then the jobs in +If the application context includes a `JobRegistry`, the jobs in `spring.batch.job.names` are looked up in the registry instead of being autowired from the -context. This is a common pattern with more complex systems where multiple jobs are +context. This is a common pattern with more complex systems, where multiple jobs are defined in child contexts and registered centrally. See @@ -2112,59 +2152,61 @@ for more details. [[howto-actuator]] == Actuator - +Spring Boot includes the Spring Boot Actuator. This section answers questions that often +arise from its use. [[howto-change-the-http-port-or-address-of-the-actuator-endpoints]] -=== Change the HTTP port or address of the actuator endpoints -In a standalone application the Actuator HTTP port defaults to the same as the main HTTP -port. To make the application listen on a different port set the external property -`management.server.port`. To listen on a completely different network address (e.g. if 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 that the server is able to bind to. - -For more detail look at the +=== Change the HTTP Port or Address of the Actuator Endpoints +In a standalone application, the Actuator HTTP port defaults to the same as the main HTTP +port. To make the application listen on a different port, set the external property, +`management.server.port`. To listen on a completely different network address (such as when you have +an internal network for management and an external one for user applications), you can +also set `management.server.address` to a valid IP address to which the server is able to bind. + +For more detail, see the {sc-spring-boot-actuator-autoconfigure}/web/server/ManagementServerProperties.{sc-ext}[`ManagementServerProperties`] source code and -_<>_ +"`<>`" in the '`Production-ready features`' section. [[howto-customize-the-whitelabel-error-page]] -=== Customize the '`whitelabel`' error page -Spring Boot installs a '`whitelabel`' error page that you will see in browser client if +=== Customize the '`whitelabel`' Error Page +Spring Boot installs a '`whitelabel`' error page that you see in a browser client if you encounter a server error (machine clients consuming JSON and other media types should see a sensible response with the right error code). -NOTE: Set `server.error.whitelabel.enabled=false` to switch the default error page off -which will restore the default of the servlet container that you are using. Note that -Spring Boot will still attempt to resolve the error view so you'd probably add you own +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 error page rather than disabling it completely. -Overriding the error page with your own depends on the templating technology that you are -using. For example, if you are using Thymeleaf you would add an `error.html` template and -if you are using FreeMarker you would add an `error.ftl` template. In general what you -need is a `View` that resolves with a name of `error`, and/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` with id `error` would -be a simple way of doing that. Look at -{sc-spring-boot-autoconfigure}/web/servlet/error/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`] for more options. +Overriding the error page with your own depends on the templating technology that you +use. For example, if you use Thymeleaf, you can add an `error.html` template. +If you use FreeMarker, you can add an `error.ftl` template. In general, you +need a `View` that resolves with a name of `error` or a `@Controller` that handles +the `/error` path. Unless you replaced some of the default configuration, you should find +a `BeanNameViewResolver` in your `ApplicationContext`, so a `@Bean` named `error` would +be a simple way of doing that. See +{sc-spring-boot-autoconfigure}/web/servlet/error/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`] +for more options. -See also the section on <> for details of -how to register handlers in the servlet container. +See also the section on "`<>`" for details +of how to register handlers in the servlet container. [[howto-use-actuator-with-jersey]] === Actuator and Jersey -Actuator HTTP endpoints are only available for Spring MVC-based applications. If you want -to use Jersey and still use the actuator you will need to enable Spring MVC (by depending +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 on `spring-boot-starter-web`, for example). By default, both Jersey and the Spring MVC -dispatcher servlet are mapped to the same path (`/`). You will need to change the path for +dispatcher servlet are mapped to the same path (`/`). You need to change the path for one of them (by configuring `server.servlet.path` for Spring MVC or `spring.jersey.application-path` for Jersey). For example, if you add `server.servlet.path=/system` into `application.properties`, the actuator HTTP endpoints -will be available under `/system`. +are available under `/system`. @@ -2173,27 +2215,27 @@ will be available under `/system`. [[howto-switch-off-spring-boot-security-configuration]] -=== Switch off the Spring Boot security configuration -If you define a `@Configuration` with `@EnableWebSecurity` anywhere in your application -it will switch off the default webapp security settings in Spring Boot (but leave the +=== 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 Actuator's security enabled). To tweak the defaults try setting properties in `+security.*+` (see {sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`] -for details of available settings) and `SECURITY` section of -<>. +for details of available settings) and the `SECURITY` section of +"`<>`". [[howto-change-the-authenticationmanager-and-add-user-accounts]] -=== Change the AuthenticationManager and add user accounts -If you provide a `@Bean` of type `AuthenticationManager` the default one will not be -created, so you have the full feature set of Spring Security available (e.g. +=== 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 http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication[various authentication options]). -Spring Security also provides a convenient `AuthenticationManagerBuilder` which can be +Spring Security also provides a convenient `AuthenticationManagerBuilder`, which can be 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 -`WebSecurityConfigurerAdapter`, e.g. +`WebSecurityConfigurerAdapter`, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2211,15 +2253,15 @@ use this in a webapp is to inject it into a void method in a } ---- -You will get the best results if you put this in a nested class, or a standalone class -(i.e. not mixed in with a lot of other `@Beans` that might be allowed to influence the +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 order of instantiation). The {github-code}/spring-boot-samples/spring-boot-sample-web-secure[secure web sample] is a useful template to follow. -If you experience instantiation issues (e.g. using JDBC or JPA for the user detail store) +If you experience instantiation issues (for example, when using JDBC or JPA for the user detail store), it might be worth extracting the `AuthenticationManagerBuilder` callback into a -`GlobalAuthenticationConfigurerAdapter` (in the `init()` method so it happens before the -authentication manager is needed elsewhere), e.g. +`GlobalAuthenticationConfigurerAdapter` (in the `init()` method so that it happens before the +authentication manager is needed elsewhere), as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2238,16 +2280,16 @@ authentication manager is needed elsewhere), e.g. [[howto-enable-https]] -=== Enable HTTPS when running behind a proxy server +=== Enable HTTPS When Running behind a Proxy Server Ensuring that all your main endpoints are only available over HTTPS is an important -chore for any application. If you are using Tomcat as a servlet container, then -Spring Boot will add Tomcat's own `RemoteIpValve` automatically if it detects some +chore for any application. If you use Tomcat as a servlet container, then +Spring Boot adds Tomcat's own `RemoteIpValve` automatically if it detects some environment settings, and you should be able to rely on the `HttpServletRequest` to report whether it is secure or not (even downstream of a proxy server that handles the real SSL termination). The standard behavior is determined by the presence or absence of certain request headers (`x-forwarded-for` and `x-forwarded-proto`), whose names are -conventional, so it should work with most front end proxies. You can switch on the valve -by adding some entries to `application.properties`, e.g. +conventional, so it should work with most front-end proxies. You can switch on the valve +by adding some entries to `application.properties`, as shown in the following example: [source,properties,indent=0] ---- @@ -2255,33 +2297,33 @@ by adding some entries to `application.properties`, e.g. server.tomcat.protocol-header=x-forwarded-proto ---- -(The presence of either of those properties will switch on the valve. Or you can add the -`RemoteIpValve` yourself by adding a `TomcatServletWebServerFactory` bean.) +(The presence of either of those properties switches on the valve. Alternatively, you can +add the `RemoteIpValve` yourself by adding a `TomcatServletWebServerFactory` bean.) -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 you just need to set +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 `security.require_ssl` to `true` in `application.properties`. [[howto-hotswapping]] -== Hot swapping - +== Hot Swapping +Spring Boot supports hot swapping. This section answers questions about how it works. [[howto-reload-static-content]] -=== Reload static content +=== Reload Static Content There are several options for hot reloading. The recommended approach is to use -<> as it provides -additional development-time features such as support for fast application restarts -and LiveReload as well as sensible development-time configuration (e.g. template caching). +<>, as it provides +additional development-time features, such as support for fast application restarts +and LiveReload as well as sensible development-time configuration (such as template caching). Devtools works by monitoring the classpath for changes. This means that static resource changes must be "built" for the change to take affect. By default, this happens -automatically in Eclipse when you save your changes. In IntelliJ IDEA, Make Project will -trigger the necessary build. Due to the +automatically in Eclipse when you save your changes. In IntelliJ IDEA, Make Project +triggers the necessary build. Due to the <>, changes to static resources will not trigger a restart of your application. -They will, however, trigger a live reload. +exclusions>>, changes to static resources do not trigger a restart of your application. +They do, however, trigger a live reload. Alternatively, running in an IDE (especially with debugging on) is a good way to do development (all modern IDEs allow reloading of static resources and usually also @@ -2290,58 +2332,58 @@ hot-swapping of Java class changes). Finally, the <> can be configured (see the `addResources` property) to support running from the command line with reloading of static files directly from source. You can use that with an external -css/js compiler process if you are writing that code with higher level tools. +css/js compiler process if you are writing that code with higher-level tools. [[howto-reload-thymeleaf-template-content]] -=== Reload templates without restarting the container +=== Reload Templates without Restarting the Container Most of the templating technologies supported by Spring Boot include a configuration -option to disable caching (see below for details). If you're using the -`spring-boot-devtools` module these properties will be +option to disable caching (described later in this document). If you use the +`spring-boot-devtools` module, these properties are <> for you at development time. [[howto-reload-thymeleaf-content]] -==== Thymeleaf templates -If you are using Thymeleaf, then set `spring.thymeleaf.cache` to `false`. See +==== Thymeleaf Templates +If you use Thymeleaf, set `spring.thymeleaf.cache` to `false`. See {sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`] for other Thymeleaf customization options. [[howto-reload-freemarker-content]] -==== FreeMarker templates -If you are using FreeMarker, then set `spring.freemarker.cache` to `false`. See +==== FreeMarker Templates +If you use FreeMarker, set `spring.freemarker.cache` to `false`. See {sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`] for other FreeMarker customization options. [[howto-reload-groovy-template-content]] -==== Groovy templates -If you are using Groovy templates, then set `spring.groovy.template.cache` to `false`. See +==== Groovy Templates +If you use Groovy templates, set `spring.groovy.template.cache` to `false`. See {sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`] for other Groovy customization options. [[howto-reload-fast-restart]] -=== Fast application restarts +=== Fast Application Restarts The `spring-boot-devtools` module includes support for automatic application restarts. -Whilst not as fast as technologies such as http://zeroturnaround.com/software/jrebel/[JRebel] -it's usually significantly faster than a "`cold start`". You should probably give it a try -before investigating some of the more complex reload options discussed below. +While not as fast as technologies such as http://zeroturnaround.com/software/jrebel/[JRebel] +it is usually significantly faster than a "`cold start`". You should probably give it a try +before investigating some of the more complex reload options discussed later in this document. -For more details see the <> section. +For more details, see the <> section. [[howto-reload-java-classes-without-restarting]] -=== Reload Java classes without restarting the container -Modern IDEs (Eclipse, IDEA, etc.) all support hot swapping of bytecode, so if you make a -change that doesn't affect class or method signatures it should reload cleanly with no +=== 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 side effects. @@ -2349,16 +2391,18 @@ side effects. [[howto-build]] == Build - +Spring Boot includes build plugins for Maven and Gradle. This section answers common +questions about these plugins. [[howto-build-info]] -=== Generate build information -Both the Maven and Gradle plugin allow to generate build information containing -the coordinates, name and version of the project. The plugin can also be configured -to add additional properties through configuration. When such file is present, +=== Generate Build Information +Both the Maven plugin and the Gradle plugin allow generating build information containing +the coordinates, name, and version of the project. The plugins can also be configured +to add additional properties through configuration. When such a file is present, Spring Boot auto-configures a `BuildProperties` bean. -To generate build information with Maven, add an execution for the `build-info` goal: +To generate build information with Maven, add an execution for the `build-info` goal, as +shown in the following example: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2380,10 +2424,10 @@ To generate build information with Maven, add an execution for the `build-info` ---- -TIP: Check the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin documentation] +TIP: See the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin documentation] for more details. -And to do the same with Gradle: +The following example does the same with Gradle: [source,groovy,indent=0,subs="verbatim,attributes"] ---- @@ -2392,7 +2436,7 @@ And to do the same with Gradle: } ---- -Additional properties can be added using the DSL: +Additional properties can be added by using the DSL, as shown in the following example: [source,groovy,indent=0,subs="verbatim,attributes"] ---- @@ -2408,13 +2452,13 @@ Additional properties can be added using the DSL: [[howto-git-info]] -=== Generate git information +=== Generate Git Information -Both Maven and Gradle allow to generate a `git.properties` file containing information +Both Maven and Gradle allow generating a `git.properties` file containing information about the state of your `git` source code repository when the project was built. -For Maven users the `spring-boot-starter-parent` POM includes a pre-configured plugin to -generate a `git.properties` file. Simply add the following declaration to your POM: +For Maven users, the `spring-boot-starter-parent` POM includes a pre-configured plugin to +generate a `git.properties` file. To use it, add the following declaration to your POM: [source,xml,indent=0] ---- @@ -2428,8 +2472,9 @@ generate a `git.properties` file. Simply add the following declaration to your P ---- -Gradle users can achieve the same result using the -https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties[`gradle-git-properties`] plugin +Gradle users can achieve the same result by using the +https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties[`gradle-git-properties`] +plugin, as shown in the following example: [source,groovy,indent=0] ---- @@ -2438,22 +2483,22 @@ https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties[`gradle-gi } ---- -TIP: The commit time in `git.properties` is expected to match the format +TIP: The commit time in `git.properties` is expected to match the following format: `yyyy-MM-dd'T'HH:mm:ssZ`. This is the default format for both plugins listed above. Using this format -allows the time to be parsed into a `Date` and its format when serialized to JSON to be controlled by +allows the time to be parsed into a `Date` and its format, when serialized to JSON, to be controlled by Jackson's date serialization configuration settings. [[howto-customize-dependency-versions-with-maven]] [[howto-customize-dependency-versions]] -=== Customize dependency versions +=== Customize Dependency Versions If you use a Maven build that inherits directly or indirectly from `spring-boot-dependencies` (for instance `spring-boot-starter-parent`) but you want to override a specific -third-party dependency you can add appropriate `` elements. Browse +third-party dependency, you can add appropriate `` elements. Browse the {github-code}/spring-boot-project/spring-boot-dependencies/pom.xml[`spring-boot-dependencies`] POM for a complete list of properties. For example, to pick a different `slf4j` version -you would add the following: +you would add the following property: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2462,9 +2507,9 @@ you would add the following: ---- -NOTE: This only works if your Maven project inherits (directly or indirectly) from +NOTE: Doing so only works if your Maven project inherits (directly or indirectly) from `spring-boot-dependencies`. If you have added `spring-boot-dependencies` in your -own `dependencyManagement` section with `import` you have to redefine +own `dependencyManagement` section with `import`, you have to redefine the artifact yourself instead of overriding the property. WARNING: Each Spring Boot release is designed and tested against a specific set of @@ -2473,10 +2518,10 @@ third-party dependencies. Overriding versions may cause compatibility issues. [[howto-create-an-executable-jar-with-maven]] -=== Create an executable JAR with Maven +=== Create an Executable JAR with Maven The `spring-boot-maven-plugin` can be used to create an executable '`fat`' JAR. If you -are using the `spring-boot-starter-parent` POM you can simply declare the plugin and -your jars will be repackaged: +are using the `spring-boot-starter-parent` POM, you can simply declare the plugin and +your jars are repackaged as follows: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2490,8 +2535,8 @@ your jars will be repackaged: ---- -If you are not using the parent POM you can still use the plugin, however, you must -additionally add an `` section: +If you do not use the parent POM, you can still use the plugin. However, you must +additionally add an `` section, as follows: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2518,7 +2563,7 @@ details. [[howto-create-an-additional-executable-jar]] -=== Use a Spring Boot application as a dependency +=== Use a Spring Boot Application as a Dependency Like a war file, a Spring Boot application is not intended to be used as a dependency. If your application contains classes that you want to share with other projects, the recommended approach is to move that code into a separate module. The separate module can @@ -2533,7 +2578,7 @@ that they cannot be found when the executable jar is used as a dependency. To produce the two artifacts, one that can be used as a dependency and one that is executable, a classifier must be specified. This classifier is applied to the name of the -executable archive, leaving the default archive for use as dependency. +executable archive, leaving the default archive for use as a dependency. To configure a classifier of `exec` in Maven, the following configuration can be used: @@ -2555,16 +2600,16 @@ To configure a classifier of `exec` in Maven, the following configuration can be [[howto-extract-specific-libraries-when-an-executable-jar-runs]] -=== Extract specific libraries when an executable jar runs -Most nested libraries in an executable jar do not need to be unpacked in order to run, -however, certain libraries can have problems. For example, JRuby includes its own nested -jar support which assumes that the `jruby-complete.jar` is always directly available as a +=== Extract Specific Libraries When an Executable Jar Runs +Most nested libraries in an executable jar do not need to be unpacked in order to run. +However, certain libraries can have problems. For example, JRuby includes its own nested +jar support, which assumes that the `jruby-complete.jar` is always directly available as a file in its own right. To deal with any problematic libraries, you can flag that specific nested jars should be automatically unpacked to the '`temp folder`' when the executable jar first runs. -For example, to indicate that JRuby should be flagged for unpack using the Maven Plugin +For example, to indicate that JRuby should be flagged for unpacking by using the Maven Plugin, you would add the following configuration: [source,xml,indent=0,subs="verbatim,quotes,attributes"] @@ -2590,15 +2635,13 @@ you would add the following configuration: [[howto-create-a-nonexecutable-jar]] -=== Create a non-executable JAR with exclusions -Often if you have an executable and a non-executable jar as build products, the executable -version will have additional configuration files that are not needed in a library jar. -E.g. the `application.yml` configuration file might excluded from the non-executable JAR. +=== 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. -The `maven-jar-plugin` used to expose a `forceCreation` attribute that allows you to -create the jar _again_ once the `repackage` goal has ran. Arguably, this was a bit fragile -anyway since it was relying on the order of plugin executions. In Maven, the executable -jar must be the main artifact and you can add a classified jar for the library: +In Maven, the executable jar must be the main artifact and you can add a classified jar +for the library, as follows: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2633,19 +2676,19 @@ jar must be the main artifact and you can add a classified jar for the library: [[howto-remote-debug-maven-run]] -=== Remote debug a Spring Boot application started with Maven -To attach a remote debugger to a Spring Boot application started with Maven you can use +=== Remote Debug a Spring Boot Application Started with Maven +To attach a remote debugger to a Spring Boot application that was started with Maven, you can use the `jvmArguments` property of the {spring-boot-maven-plugin-site}/[maven plugin]. -Check {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for more details. +See {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for more details. [[howto-build-an-executable-archive-with-ant]] -=== Build an executable archive from Ant without using spring-boot-antlib -To build with Ant you need to grab dependencies, compile and then create a jar or war -archive. To make it executable you can either use the `spring-boot-antlib` -module, or you can follow these instructions: +=== Build an Executable Archive from Ant without Using `spring-boot-antlib` +To build with Ant, you need to grab dependencies, compile, and then create a jar or war +archive. To make it executable, you can either use the `spring-boot-antlib` +module or you can follow these instructions: . If you are building a jar, package the application's classes and resources in a nested `BOOT-INF/classes` directory. If you are building a war, package the application's @@ -2653,15 +2696,15 @@ module, or you can follow these instructions: . Add the runtime dependencies in a nested `BOOT-INF/lib` directory for a jar or `WEB-INF/lib` for a war. Remember *not* to compress the entries in the archive. . Add the `provided` (embedded container) dependencies in a nested `BOOT-INF/lib` - directory for jar or `WEB-INF/lib-provided` for a war. Remember *not* to compress the + directory for a jar or `WEB-INF/lib-provided` for a war. Remember *not* to compress the entries in the archive. -. Add the `spring-boot-loader` classes at the root of the archive (so the `Main-Class` +. Add the `spring-boot-loader` classes at the root of the archive (so that the `Main-Class` is available). -. Use the appropriate launcher, e.g. `JarLauncher` for a jar file, as a `Main-Class` - attribute in the manifest and specify the other properties it needs as manifest entries, - principally a `Start-Class`. +. 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. -Example: +The following example shows how to build an executable archive with Ant: [source,xml,indent=0] ---- @@ -2689,14 +2732,14 @@ Example: ---- The {github-code}/spring-boot-samples/spring-boot-sample-ant[Ant Sample] has a -`build.xml` with a `manual` task that should work if you run it with +`build.xml` file with a `manual` task that should work if you run it with the following command: [indent=0,subs="verbatim,quotes,attributes"] ---- $ ant -lib clean manual ---- -after which you can run the application with +Then you can run the application with the following command: [indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2706,18 +2749,20 @@ after which you can run the application with [[howto-traditional-deployment]] -== Traditional deployment - +== Traditional Deployment +Spring Boot supports traditional deployment as well as more modern forms of deployment. +This section answers common questions about traditional deployment. [[howto-create-a-deployable-war-file]] -=== Create a deployable war file +=== Create a Deployable War File The first step in producing a deployable war file is to provide a -`SpringBootServletInitializer` subclass and override its `configure` method. This makes -use of Spring Framework's Servlet 3.0 support and allows you to configure your -application when it's launched by the servlet container. Typically, you update your -application's main class to extend `SpringBootServletInitializer`: +`SpringBootServletInitializer` subclass and override its `configure` method. Doing so makes +use of Spring Framework's Servlet 3.0 support and lets you configure your +application when it is launched by the servlet container. Typically, you should update your +application's main class to extend `SpringBootServletInitializer`, as shown in the +following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2736,29 +2781,30 @@ application's main class to extend `SpringBootServletInitializer`: } ---- -The next step is to update your build configuration so that your project produces a war file -rather than a jar file. If you're using Maven and using `spring-boot-starter-parent` (which +The next step is to update your build configuration such that your project produces a war file +rather than a jar file. If you use Maven and `spring-boot-starter-parent` (which configures Maven's war plugin for you) all you need to do is to modify `pom.xml` to change the -packaging to war: +packaging to war, as follows: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- war ---- -If you're using Gradle, you need to modify `build.gradle` to apply the war plugin to the -project: +If you use Gradle, you need to modify `build.gradle` to apply the war plugin to the +project, as follows: [source,groovy,indent=0,subs="verbatim,quotes,attributes"] ---- apply plugin: 'war' ---- -The final step in the process is to ensure that the embedded servlet container doesn't -interfere with the servlet container to which the war file will be deployed. To do so, you -need to mark the embedded servlet container dependency as provided. +The final step in the process is to ensure that the embedded servlet container does not +interfere with the servlet container to which the war file is deployed. To do so, you +need to mark the embedded servlet container dependency as being provided. -If you're using Maven: +If you use Maven, the following example marks the servlet container (Tomcat, in this +case) as being provided: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2773,7 +2819,8 @@ If you're using Maven: ---- -And if you're using Gradle: +If you use Gradle, the following example marks the servlet container (Tomcat, in this +case) as being provided: [source,groovy,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2784,25 +2831,25 @@ And if you're using Gradle: } ---- -NOTE: `providedRuntime` is preferred to Gradle's `compileOnly` configuration as, among other +NOTE: `providedRuntime` is preferred to Gradle's `compileOnly` configuration. Among other limitations, `compileOnly` dependencies are not on the test classpath so any web-based -integration tests will fail. +integration tests fail. -If you're using the <>, -marking the embedded servlet container dependency as provided will produce an executable war +If you use the <>, +marking the embedded servlet container dependency as provided produces an executable war file with the provided dependencies packaged in a `lib-provided` directory. This means that, in addition to being deployable to a servlet container, you can also run your -application using `java -jar` on the command line. +application by using `java -jar` on the command line. TIP: Take a look at Spring Boot's sample applications for a {github-code}/spring-boot-samples/spring-boot-sample-traditional/pom.xml[Maven-based example] -of the above-described configuration. +of the previously described configuration. [[howto-create-a-deployable-war-file-for-older-containers]] -=== Create a deployable war file for older servlet containers -Older Servlet containers don't have support for the `ServletContextInitializer` bootstrap +=== Create a Deployable War File for Older Servlet Containers +Older Servlet containers do not have support for the `ServletContextInitializer` bootstrap process used in Servlet 3.0. You can still use Spring and Spring Boot in these containers but you are going to need to add a `web.xml` to your application and configure it to load an `ApplicationContext` via a `DispatcherServlet`. @@ -2810,17 +2857,18 @@ an `ApplicationContext` via a `DispatcherServlet`. [[howto-convert-an-existing-application-to-spring-boot]] -=== Convert an existing application to Spring Boot -For a non-web application it should be easy (throw away the code that creates your +=== Convert an Existing Application to Spring Boot +For a non-web application, it should be easy to convert an existing Spring application to +a Spring Boot application. To do so, throw away the code that creates your `ApplicationContext` and replace it with calls to `SpringApplication` or -`SpringApplicationBuilder`). Spring MVC web applications are generally amenable to first -creating a deployable war application, and then migrating it later to an executable war -and/or jar. Useful reading is in the http://spring.io/guides/gs/convert-jar-to-war/[Getting +`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 Started Guide on Converting a jar to a war]. -Create a deployable war by extending `SpringBootServletInitializer` (e.g. in a class -called `Application`), and add the Spring Boot `@SpringBootApplication` annotation. -Example: +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: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2838,30 +2886,30 @@ Example: } ---- -Remember that whatever you put in the `sources` is just a Spring `ApplicationContext` and -normally anything that already works should work here. There might be some beans you can +Remember that, whatever you put in the `sources` is merely a Spring `ApplicationContext`. +Normally, anything that already works should work here. There might be some beans you can remove later and let Spring Boot provide its own defaults for them, but it should be -possible to get something working first. +possible to get something working before you need to do that. Static resources can be moved to `/public` (or `/static` or `/resources` or -`/META-INF/resources`) in the classpath root. Same for `messages.properties` (Spring Boot -detects this automatically in the root of the classpath). +`/META-INF/resources`) in the classpath root. The same applies to `messages.properties` +(which Spring Boot automatically detects in the root of the classpath). Vanilla usage of Spring `DispatcherServlet` and Spring Security should require no further -changes. If you have other features in your application, using other servlets or filters -for instance, then you may need to add some configuration to your `Application` context, -replacing those elements from the `web.xml` as follows: +changes. If you have other features in your application (for instance, using other +servlets or filters), you may need to add some configuration to your `Application` +context, by replacing those elements from the `web.xml` as follows: * A `@Bean` of type `Servlet` or `ServletRegistrationBean` installs that bean in the - container as if it was a `` and `` in `web.xml`. -* A `@Bean` of type `Filter` or `FilterRegistrationBean` behaves similarly (like a - `` and ``. + container as if it were a `` and `` in `web.xml`. +* A `@Bean` of type `Filter` or `FilterRegistrationBean` behaves similarly (as a + `` and ``). * An `ApplicationContext` in an XML file can be added through an `@ImportResource` in - your `Application`. Or simple cases where annotation configuration is heavily used - already can be recreated in a few lines as `@Bean` definitions. + your `Application`. Alternatively, simple cases where annotation configuration is + heavily used already can be recreated in a few lines as `@Bean` definitions. -Once the war is working we make it executable by adding a `main` method to our -`Application`, e.g. +Once the war file is working, you can make it executable by adding a `main` method to +your `Application`, as shown in the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2874,7 +2922,8 @@ Once the war is working we make it executable by adding a `main` method to our ==== If you intend to start your application as a war or as an executable application, you need to share the customizations of the builder in a method that is both available to the -`SpringBootServletInitializer` callback and the `main` method, something like: +`SpringBootServletInitializer` callback and the `main` method, in a class similar to the +following: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2906,32 +2955,35 @@ Applications can fall into more than one category: * Applications without a context hierarchy. All of these should be amenable to translation, but each might require slightly different -tricks. +techniques. Servlet 3.0+ applications might translate pretty easily if they already use the Spring -Servlet 3.0+ initializer support classes. Normally all the code from an existing +Servlet 3.0+ initializer support classes. Normally, all the code from an existing `WebApplicationInitializer` can be moved into a `SpringBootServletInitializer`. If your -existing application has more than one `ApplicationContext` (e.g. if it uses -`AbstractDispatcherServletInitializer`) then you might be able to squash all your context +existing application has more than one `ApplicationContext` (for example, if it uses +`AbstractDispatcherServletInitializer`) then you might be able to combine all your context sources into a single `SpringApplication`. The main complication you might encounter is if -that doesn't work and you need to maintain the context hierarchy. See the +combining does not work and you need to maintain the context hierarchy. See the <> for -examples. An existing parent context that contains web-specific features will usually -need to be broken up so that all the `ServletContextAware` components are in the child +examples. An existing parent context that contains web-specific features usually +needs to be broken up so that all the `ServletContextAware` components are in the child context. -Applications that are not already Spring applications might be convertible to a Spring -Boot application, and the guidance above might help, but your mileage may vary. +Applications that are not already Spring applications might be convertible to Spring +Boot applications, and the previously mentioned guidance may help. However, you may yet +encounter problems. In that case, we suggest +https://stackoverflow.com/questions/tagged/spring-boot[asking questions on Stack Overflow +with a tag of `spring-boot`]. [[howto-weblogic]] === Deploying a WAR to WebLogic -To deploy a Spring Boot application to WebLogic you must ensure that your servlet +To deploy a Spring Boot application to WebLogic, you must ensure that your servlet initializer *directly* implements `WebApplicationInitializer` (even if you extend from a base class that already implements it). -A typical initializer for WebLogic would be something like this: +A typical initializer for WebLogic should resemble the following example: [source,java,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -2945,8 +2997,8 @@ A typical initializer for WebLogic would be something like this: } ---- -If you use logback, you will also need to tell WebLogic to prefer the packaged version -rather than the version that pre-installed with the server. You can do this by adding a +If you use Logback, you also need to tell WebLogic to prefer the packaged version +rather than the version that was pre-installed with the server. You can do so by adding a `WEB-INF/weblogic.xml` file with the following contents: [source,xml,indent=0] @@ -2972,14 +3024,15 @@ rather than the version that pre-installed with the server. You can do this by a [[howto-servlet-2-5]] === Deploying a WAR in an Old (Servlet 2.5) Container Spring Boot uses Servlet 3.0 APIs to initialize the `ServletContext` (register `Servlets` -etc.) so you can't use the same application out of the box in a Servlet 2.5 container. -It *is* however possible to run a Spring Boot application on an older container with some +and so on), so you cannot use the same application in a Servlet 2.5 container. +It *is*, however, possible to run a Spring Boot application on an older container with some special tools. If you include `org.springframework.boot:spring-boot-legacy` as a dependency (https://github.com/scratches/spring-boot-legacy[maintained separately] to the core of Spring Boot and currently available at 1.0.2.RELEASE), all you should need to do is create a `web.xml` and declare a context listener to create the application context and your filters and servlets. The context listener is a special purpose one for Spring Boot, -but the rest of it is normal for a Spring application in Servlet 2.5. Example: +but the rest of it is normal for a Spring application in Servlet 2.5. The following Maven +example shows how to set up a Spring Boot project to run in a Servlet 2.5 container: [source,xml,indent=0] ---- @@ -3025,20 +3078,20 @@ but the rest of it is normal for a Spring application in Servlet 2.5. Example: ---- -In this example we are using a single application context (the one created by the context -listener) and attaching it to the `DispatcherServlet` using an init parameter. This is +In the preceding example, we use a single application context (the one created by the context +listener) and attach it to the `DispatcherServlet` by using an `init` parameter. This is normal in a Spring Boot application (you normally only have one application context). [[howto-use-jedis-instead-of-lettuce]] -=== Use Jedis instead of Lettuce -The Spring Boot starter (`spring-boot-starter-data-redis`) uses -https://github.com/lettuce-io/lettuce-core/[Lettuce] by default. You need to exclude that +=== Use Jedis Instead of Lettuce +By default, the Spring Boot starter (`spring-boot-starter-data-redis`) uses +https://github.com/lettuce-io/lettuce-core/[Lettuce]. You need to exclude that dependency and include the https://github.com/xetorthio/jedis/[Jedis] one instead. Spring Boot manages these dependencies to help make this process as easy as possible. -Example in Maven: +The following example shows how to do so in Maven: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -3058,7 +3111,7 @@ Example in Maven: ---- -Example in Gradle: +The following example shows how to do so in Gradle: [source,groovy,indent=0,subs="verbatim,quotes,attributes"] ----