diff --git a/docs/src/main/asciidoc/getting-started.adoc b/docs/src/main/asciidoc/getting-started.adoc index 4dc56a7fc6..5585967c82 100644 --- a/docs/src/main/asciidoc/getting-started.adoc +++ b/docs/src/main/asciidoc/getting-started.adoc @@ -2,820 +2,1046 @@ = Getting Started include::_attributes.adoc[] -If you are getting started with Spring Boot, or "`Spring`" in general, start by reading +If you are getting started with {project-full-name}, or "`Spring`" in general, start by reading this section. It answers the basic "`what?`", "`how?`" and "`why?`" questions. It -includes an introduction to Spring Boot, along with installation instructions. We then -walk you through building your first Spring Boot application, discussing some core +includes an introduction to {project-full-name}, along with installation instructions. We then +walk you through building your first {project-full-name} application, discussing some core principles as we go. +[[getting-started-introducing-spring-cloud-contract]] +== Introducing Spring Cloud Contract +Spring Cloud Contract moves TDD to the level of software architecture. It allows to perform consumer, consumer-driven and producer-driven contract testing. -[[getting-started-introducing-spring-boot]] -== Introducing Spring Boot -Spring Boot makes it easy to create stand-alone, production-grade Spring-based -Applications that you can run. We take an opinionated view of the Spring platform and -third-party libraries, so that you can get started with minimum fuss. Most Spring Boot -applications need very little Spring configuration. +[[getting-started-introducing-spring-cloud-contract-history]] +=== History -You can use Spring Boot to create Java applications that can be started by using -`java -jar` or more traditional war deployments. We also provide a command line tool that -runs "`spring scripts`". +Before becoming Spring Cloud Contract, this project was called https://github.com/Codearte/accurest[Accurest]. +It was created by https://twitter.com/mgrzejszczak[Marcin Grzejszczak] and https://twitter.com/jkubrynski[Jakub Kubrynski] +from (https://github.com/Codearte[Codearte]. -Our primary goals are: +The `0.1.0` release took place on 26 Jan 2015 and it became stable with `1.0.0` release on 29 Feb 2016. -* Provide a radically faster and widely accessible getting-started experience for all -Spring development. -* Be opinionated out of the box but get out of the way quickly as requirements start to -diverge from the defaults. -* Provide a range of non-functional features that are common to large classes of projects -(such as embedded servers, security, metrics, health checks, and externalized -configuration). -* Absolutely no code generation and no requirement for XML configuration. +[[getting-started-introducing-spring-cloud-contract-why]] +==== Why would you need it? +Assume that we have a system consisting of multiple microservices: +image::images/Deps.png[Microservices Architecture] -[[getting-started-system-requirements]] -== System Requirements -Spring Boot {spring-boot-version} requires https://www.java.com[Java 8] and is compatible -up to Java 12 (included). {spring-reference}[Spring Framework {spring-framework-version}] -or above is also required. +[[getting-started-introducing-spring-cloud-contract-testing-issues]] +==== Testing issues -Explicit build support is provided for the following build tools: +If we wanted to test the application in top left corner to determine whether it can +communicate with other services, we could do one of two things: -|=== -|Build Tool |Version +- Deploy all microservices and perform end-to-end tests. +- Mock other microservices in unit/integration tests. -|Maven -|3.3+ +Both have their advantages but also a lot of disadvantages. -|Gradle -|5.x (4.10 is also supported but in a deprecated form) -|=== +*Deploy all microservices and perform end to end tests* +Advantages: +- Simulates production. +- Tests real communication between services. -[[getting-started-system-requirements-servlet-containers]] -=== Servlet Containers -Spring Boot supports the following embedded servlet containers: +Disadvantages: -|=== -|Name |Servlet Version +- To test one microservice, we have to deploy 6 microservices, a couple of databases, +etc. +- The environment where the tests run is locked for a single suite of tests (nobody else +would be able to run the tests in the meantime). +- They take a long time to run. +- The feedback comes very late in the process. +- They are extremely hard to debug. -|Tomcat 9.0 -|4.0 +*Mock other microservices in unit/integration tests* -|Jetty 9.4 -|3.1 +Advantages: -|Undertow 2.0 -|4.0 -|=== +- They provide very fast feedback. +- They have no infrastructure requirements. -You can also deploy Spring Boot applications to any Servlet 3.1+ compatible container. +Disadvantages: +- The implementor of the service creates stubs that might have nothing to do with +reality. +- You can go to production with passing tests and failing production. +To solve the aforementioned issues, Spring Cloud Contract was created. The main idea is to give you very fast feedback, without the need to set up the +whole world of microservices. If you work on stubs, then the only applications you need +are those that your application directly uses. -[[getting-started-installing-spring-boot]] -== Installing Spring Boot -Spring Boot can be used with "`classic`" Java development tools or installed as a command -line tool. Either way, you need https://www.java.com[Java SDK v1.8] or higher. Before you -begin, you should check your current Java installation by using the following command: +image::images/Stubs2.png[Stubbed Services] -[indent=0] +Spring Cloud Contract gives you the certainty that the stubs that you use were +created by the service that you're calling. Also, if you can use them, it means that they +were tested against the producer's side. In short, you can trust those stubs. + +[[getting-started-introducing-spring-cloud-contract-purposes]] +=== Purposes + +The main purposes of Spring Cloud Contract are: + +- To ensure that HTTP / Messaging stubs (used when developing the client) do exactly +what the actual server-side implementation does. +- To promote ATDD (acceptance test driven developement) method and Microservices architectural style. +- To provide a way to publish changes in contracts that are immediately visible on both sides. +- To generate boilerplate test code to be used on the server side. + +By default Spring Cloud Contract integrates with http://wiremock.org[Wiremock] as the HTTP server stub. + +IMPORTANT: Spring Cloud Contract's purpose is NOT to start writing business +features in the contracts. Assume that we have a business use case of fraud check. If a +user can be a fraud for 100 different reasons, we would assume that you would create 2 +contracts, one for the positive case and one for the negative case. Contract tests are +used to test contracts between applications and not to simulate full behavior. + +[[getting-started-what-is-a-contract]] +=== What is a contract? + +As consumers of services, we need to define what exactly we want to achieve. We need to +formulate our expectations. That is why we write contracts. In other words a contract is an agreement on how the API / message communication should look like. Let's look at the following example + +Assume that you want to send a request containing the ID of a client company and the +amount it wants to borrow from us. You also want to send it to the /fraudcheck url via +the PUT method. + +==== +[source,groovy,indent=0,role="primary"] +.groovy ---- - $ java -version +include::{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[] ---- -If you are new to Java development or if you want to experiment with Spring Boot, you -might want to try the <> (Command -Line Interface) first. Otherwise, read on for "`classic`" installation instructions. - - - -[[getting-started-installation-instructions-for-java]] -=== Installation Instructions for the Java Developer -You can use Spring Boot in the same way as any standard Java library. To do so, include -the appropriate `+spring-boot-*.jar+` files on your classpath. Spring Boot does not -require any special tools integration, so you can use any IDE or text editor. Also, there -is nothing special about a Spring Boot application, so you can run and debug a Spring -Boot application as you would any other Java program. - -Although you _could_ copy Spring Boot jars, we generally recommend that you use a build -tool that supports dependency management (such as Maven or Gradle). - - - -[[getting-started-maven-installation]] -==== Maven Installation -Spring Boot is compatible with Apache Maven 3.3 or above. If you do not already have -Maven installed, you can follow the instructions at https://maven.apache.org. - -TIP: On many operating systems, Maven can be installed with a package manager. If you use -OSX Homebrew, try `brew install maven`. Ubuntu users can run -`sudo apt-get install maven`. Windows users with https://chocolatey.org/[Chocolatey] can -run `choco install maven` from an elevated (administrator) prompt. - -Spring Boot dependencies use the `org.springframework.boot` `groupId`. Typically, your -Maven POM file inherits from the `spring-boot-starter-parent` project and declares -dependencies to one or more <>. -Spring Boot also provides an optional -<> to create -executable jars. - -The following listing shows a typical `pom.xml` file: - -[source,xml,indent=0,subs="verbatim,quotes,attributes"] +[source,yaml,indent=0,role="secondary"] +.yaml ---- - - - 4.0.0 +include::{introduction_url}/samples/standalone/yml/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.yml[] +---- +==== - com.example - myproject - 0.0.1-SNAPSHOT +[[getting-started-three-second-tour]] +== A Three-second Tour - - - org.springframework.boot - spring-boot-starter-parent - {spring-boot-version} - +This very brief tour walks through using Spring Cloud Contract: - - - - org.springframework.boot - spring-boot-starter-web - - +* <> +* <> - - - - - org.springframework.boot - spring-boot-maven-plugin - - - +You can find a somewhat longer tour +<>. -ifeval::["{spring-boot-repo}" != "release"] - - - - - spring-snapshots - https://repo.spring.io/snapshot - true - - - spring-milestones - https://repo.spring.io/milestone - - - - - spring-snapshots - https://repo.spring.io/snapshot - - - spring-milestones - https://repo.spring.io/milestone - - -endif::[] - +[plantuml, three-second, png] +---- +"API Producer"->"API Producer": add Spring Cloud \nContract (SCC) plugin +"API Producer"->"API Producer": add SCC Verifier dependency +"API Producer"->"API Producer": define contracts +"API Producer"->"Build": run build +"Build"->"SCC Plugin": generate \ntests, stubs and stubs \nartifact (e.g. stubs-jar) +"Build"->"Nexus / Artifactory": upload contracts \nand stubs and the project arifact +"Build"->"API Producer": Build successful +"API Consumer"->"API Consumer": add SCC Stub Runner \ndependency +"API Consumer"->"API Consumer": write a SCC Stub Runner \nbased contract test +"SCC Stub Runner"->"Nexus / Artifactory": test asks for [API Producer] stubs +"Nexus / Artifactory"->"SCC Stub Runner": fetch the [API Producer] stubs +"SCC Stub Runner"->"SCC Stub Runner": run in memory\n HTTP server stubs +"API Consumer"->"SCC Stub Runner": send a request \nto the HTTP server stub +"SCC Stub Runner"->"API Consumer": communication is correct ---- -TIP: The `spring-boot-starter-parent` is a great way to use Spring Boot, but it might not -be suitable all of the time. Sometimes you may need to inherit from a different parent -POM, or you might not like our default settings. In those cases, see -<> for an alternative solution that uses an `import` -scope. +[[getting-started-three-second-tour-producer]] +=== On the Producer Side +To start working with Spring Cloud Contract, add files with `REST`/messaging contracts +expressed in either Groovy DSL or YAML to the contracts directory, which is set by the +`contractsDslDir` property. By default, it is `$rootDir/src/test/resources/contracts`. - -[[getting-started-gradle-installation]] -==== Gradle Installation -Spring Boot is compatible with 5.x. 4.10 is also supported but this support is deprecated -and will be removed in a future release. If you do not already have Gradle installed, you -can follow the instructions at https://gradle.org. - -Spring Boot dependencies can be declared by using the `org.springframework.boot` `group`. -Typically, your project declares dependencies to one or more -<>. Spring Boot -provides a useful <> that can be used to simplify dependency declarations and to create executable -jars. - -.Gradle Wrapper -**** -The Gradle Wrapper provides a nice way of "`obtaining`" Gradle when you need to build a -project. It is a small script and library that you commit alongside your code to -bootstrap the build process. See {gradle-user-guide}/gradle_wrapper.html for details. -**** - -More details on getting started with Spring Boot and Gradle can be found in the -{spring-boot-gradle-plugin-reference}/#getting-started[Getting Started section] of the -Gradle plugin's reference guide. - - - -[[getting-started-installing-the-cli]] -=== Installing the Spring Boot CLI -The Spring Boot CLI (Command Line Interface) is a command line tool that you can use to -quickly prototype with Spring. It lets you run http://groovy-lang.org/[Groovy] scripts, -which means that you have a familiar Java-like syntax without so much boilerplate code. - -You do not need to use the CLI to work with Spring Boot, but it is definitely the -quickest way to get a Spring application off the ground. - - - -[[getting-started-manual-cli-installation]] -==== Manual Installation -You can download the Spring CLI distribution from the Spring software repository: - -* https://repo.spring.io/{spring-boot-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/spring-boot-cli-{spring-boot-version}-bin.zip[spring-boot-cli-{spring-boot-version}-bin.zip] -* https://repo.spring.io/{spring-boot-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/spring-boot-cli-{spring-boot-version}-bin.tar.gz[spring-boot-cli-{spring-boot-version}-bin.tar.gz] - -Cutting edge -https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-cli/[snapshot -distributions] are also available. - -Once downloaded, follow the -{github-raw}/spring-boot-project/spring-boot-cli/src/main/content/INSTALL.txt[INSTALL.txt] -instructions from the unpacked archive. In summary, there is a `spring` script -(`spring.bat` for Windows) in a `bin/` directory in the `.zip` file. Alternatively, you -can use `java -jar` with the `.jar` file (the script helps you to be sure that the -classpath is set correctly). - - - -[[getting-started-sdkman-cli-installation]] -==== Installation with SDKMAN! -SDKMAN! (The Software Development Kit Manager) can be used for managing multiple versions -of various binary SDKs, including Groovy and the Spring Boot CLI. -Get SDKMAN! from https://sdkman.io and install Spring Boot by using the following -commands: - -[indent=0,subs="verbatim,quotes,attributes"] ----- - $ sdk install springboot - $ spring --version - Spring Boot v{spring-boot-version} ----- - -If you develop features for the CLI and want easy access to the version you built, -use the following commands: - -[indent=0,subs="verbatim,quotes,attributes"] ----- - $ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-boot-cli-{spring-boot-version}-bin/spring-{spring-boot-version}/ - $ sdk default springboot dev - $ spring --version - Spring CLI v{spring-boot-version} ----- - -The preceding instructions install a local instance of `spring` called the `dev` -instance. It points at your target build location, so every time you rebuild Spring Boot, -`spring` is up-to-date. - -You can see it by running the following command: - -[indent=0,subs="verbatim,quotes,attributes"] ----- - $ sdk ls springboot - - ================================================================================ - Available Springboot Versions - ================================================================================ - > + dev - * {spring-boot-version} - - ================================================================================ - + - local version - * - installed - > - currently in use - ================================================================================ ----- - - - -[[getting-started-homebrew-cli-installation]] -==== OSX Homebrew Installation -If you are on a Mac and use https://brew.sh/[Homebrew], you can install the Spring Boot -CLI by using the following commands: - -[indent=0] ----- - $ brew tap pivotal/tap - $ brew install springboot ----- - -Homebrew installs `spring` to `/usr/local/bin`. - -NOTE: If you do not see the formula, your installation of brew might be out-of-date. In -that case, run `brew update` and try again. - - - -[[getting-started-macports-cli-installation]] -==== MacPorts Installation -If you are on a Mac and use https://www.macports.org/[MacPorts], you can install the -Spring Boot CLI by using the following command: - -[indent=0] ----- - $ sudo port install spring-boot-cli ----- - - - -[[getting-started-cli-command-line-completion]] -==== Command-line Completion -The Spring Boot CLI includes scripts that provide command completion for the -https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29[BASH] and -https://en.wikipedia.org/wiki/Z_shell[zsh] shells. You can `source` the script (also named -`spring`) in any shell or put it in your personal or system-wide bash completion -initialization. On a Debian system, the system-wide scripts are in -`/shell-completion/bash` and all scripts in that directory are executed when a new shell -starts. For example, to run the script manually if you have installed by using SDKMAN!, -use the following commands: - -[indent=0] ----- - $ . ~/.sdkman/candidates/springboot/current/shell-completion/bash/spring - $ spring - grab help jar run test version ----- - -NOTE: If you install the Spring Boot CLI by using Homebrew or MacPorts, the command-line -completion scripts are automatically registered with your shell. - - - -[[getting-started-scoop-cli-installation]] -==== Windows Scoop Installation -If you are on a Windows and use https://scoop.sh/[Scoop], you can install the Spring Boot -CLI by using the following commands: - -[indent=0] ----- - > scoop bucket add extras - > scoop install springboot ----- - -Scoop installs `spring` to `~/scoop/apps/springboot/current/bin`. - -NOTE: If you do not see the app manifest, your installation of scoop might be out-of-date. -In that case, run `scoop update` and try again. - - - -[[getting-started-cli-example]] -==== Quick-start Spring CLI Example -You can use the following web application to test your installation. To start, create a -file called `app.groovy`, as follows: - -[source,groovy,indent=0,subs="verbatim,quotes,attributes"] ----- - @RestController - class ThisWillActuallyRun { - - @RequestMapping("/") - String home() { - "Hello World!" - } - - } ----- - -Then run it from a shell, as follows: - -[indent=0] ----- - $ spring run app.groovy ----- - -NOTE: The first run of your application is slow, as dependencies are downloaded. -Subsequent runs are much quicker. - -Open `http://localhost:8080` in your favorite web browser. You should see the following -output: - -[indent=0] ----- - Hello World! ----- - - - -[[getting-started-upgrading-from-an-earlier-version]] -=== Upgrading from an Earlier Version of Spring Boot -If you are upgrading from an earlier release of Spring Boot, check the -{github-wiki}/Spring-Boot-2.0-Migration-Guide["`migration guide`" on the project wiki] -that provides detailed upgrade instructions. Check also the -{github-wiki}["`release notes`"] for a list of "`new and noteworthy`" features for each -release. - -When upgrading to a new feature release, some properties may have been renamed or removed. -Spring Boot provides a way to analyze your application's environment and print diagnostics -at startup, but also temporarily migrate properties at runtime for you. To enable that -feature, add the following dependency to your project: +Then add the Spring Cloud Contract Verifier dependency and plugin to your build file, as +shown in the following example: [source,xml,indent=0] ---- - - org.springframework.boot - spring-boot-properties-migrator - runtime - +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0] ---- -WARNING: Properties that are added late to the environment, such as when using -`@PropertySource`, will not be taken into account. +The following listing shows how to add the plugin, which should go in the build/plugins +portion of the file: -NOTE: Once you're done with the migration, please make sure to remove this module from -your project's dependencies. +[source,xml,indent=0] +---- + + org.springframework.cloud + spring-cloud-contract-maven-plugin + ${spring-cloud-contract.version} + true + +---- -To upgrade an existing CLI installation, use the appropriate package manager command (for -example, `brew upgrade`) or, if you manually installed the CLI, follow the -<>, remembering to update -your `PATH` environment variable to remove any older references. +Running `./mvnw clean install` automatically generates tests that verify the application +compliance with the added contracts. By default, the tests get generated under +`org.springframework.cloud.contract.verifier.tests.`. +As the implementation of the functionalities described by the contracts is not yet +present, the tests fail. +To make them pass, you must add the correct implementation of either handling HTTP +requests or messages. Also, you must add a correct base test class for auto-generated +tests to the project. This class is extended by all the auto-generated tests, and it +should contain all the setup necessary to run them (for example `RestAssuredMockMvc` +controller setup or messaging test setup). + +Once the implementation and the test base class are in place, the tests pass, and both the +application and the stub artifacts are built and installed in the local Maven repository. +The changes can now be merged, and both the application and the stub artifacts may be +published in an online repository. + +[[getting-started-three-second-tour-consumer]] +=== On the Consumer Side + +`Spring Cloud Contract Stub Runner` can be used in the integration tests to get a running +WireMock instance or messaging route that simulates the actual service. + +To do so, add the dependency to `Spring Cloud Contract Stub Runner`, as shown in the +following example: + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0] +---- + +You can get the Producer-side stubs installed in your Maven repository in either of two +ways: + +* By checking out the Producer side repository and adding contracts and generating the stubs +by running the following commands: ++ +[source,bash,indent=0] +---- +$ cd local-http-server-repo +$ ./mvnw clean install -DskipTests +---- +TIP: The tests are being skipped because the Producer-side contract implementation is not +in place yet, so the automatically-generated contract tests fail. +* By getting already-existing producer service stubs from a remote repository. To do so, +pass the stub artifact IDs and artifact repository URL as `Spring Cloud Contract +Stub Runner` properties, as shown in the following example: ++ +[source,yaml,indent=0] +---- +include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/{branch}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[] +---- + +Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation, +provide the `group-id` and `artifact-id` values for `Spring Cloud Contract Stub Runner` to +run the collaborators' stubs for you, as shown in the following example: + +[source,java, indent=0] +---- +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.NONE) +@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:6565"}, + stubsMode = StubRunnerProperties.StubsMode.LOCAL) +public class LoanApplicationServiceTests { +---- + +TIP: Use the `REMOTE` `stubsMode` when downloading stubs from an online repository and +`LOCAL` for offline work. + +Now, in your integration test, you can receive stubbed versions of HTTP responses or +messages that are expected to be emitted by the collaborator service. [[getting-started-first-application]] -== Developing Your First Spring Boot Application -This section describes how to develop a simple "`Hello World!`" web application that -highlights some of Spring Boot's key features. We use Maven to build this project, since -most IDEs support it. +== Developing Your First Spring Cloud Contract based application + +This brief tour walks through using Spring Cloud Contract: + +* <> +* <> + +You can find an even more brief tour +<>. + +[[getting-started-first-application-producer]] +=== On the Producer Side + +To start working with `Spring Cloud Contract`, add files with `REST/` messaging contracts +expressed in either Groovy DSL or YAML to the contracts directory, which is set by the +`contractsDslDir` property. By default, it is `$rootDir/src/test/resources/contracts`. + +For the HTTP stubs, a contract defines what kind of response should be returned for a +given request (taking into account the HTTP methods, URLs, headers, status codes, and so +on). The following example shows how an HTTP stub contract: -[TIP] ==== -The https://spring.io[spring.io] web site contains many "`Getting Started`" -https://spring.io/guides[guides] that use Spring Boot. If you need to solve a specific -problem, check there first. +[source,groovy,indent=0,role="primary"] +.groovy +---- +package contracts -You can shortcut the steps below by going to https://start.spring.io and choosing the -"Web" starter from the dependencies searcher. Doing so generates a new project structure -so that you can <>. Check -the {spring-initializr-reference}/#user-guide[Spring Initializr documentation] for more -details. +org.springframework.cloud.contract.spec.Contract.make { + request { + method 'PUT' + url '/fraudcheck' + body([ + "client.id": $(regex('[0-9]{10}')), + loanAmount: 99999 + ]) + headers { + contentType('application/json') + } + } + response { + status OK() + body([ + fraudCheckStatus: "FRAUD", + "rejection.reason": "Amount too high" + ]) + headers { + contentType('application/json') + } + } +} +---- + +[source,yaml,indent=0,role="secondary"] +.yaml +---- +request: + method: PUT + url: /fraudcheck + body: + "client.id": 1234567890 + loanAmount: 99999 + headers: + Content-Type: application/json + matchers: + body: + - path: $.['client.id'] + type: by_regex + value: "[0-9]{10}" +response: + status: 200 + body: + fraudCheckStatus: "FRAUD" + "rejection.reason": "Amount too high" + headers: + Content-Type: application/json;charset=UTF-8 +---- ==== -Before we begin, open a terminal and run the following commands to ensure that you have -valid versions of Java and Maven installed: +In the case of messaging, you can define: -[indent=0] +* The input and the output messages can be defined (taking into account from and where it +was sent, the message body, and the header). +* The methods that should be called after the message is received. +* The methods that, when called, should trigger a message. + +The following example shows a Camel messaging contract: + +==== +[source,groovy,indent=0,role="primary"] +.groovy ---- - $ java -version - java version "1.8.0_102" - Java(TM) SE Runtime Environment (build 1.8.0_102-b14) - Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode) +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_dsl] ---- -[indent=0] +[source,yaml,indent=0,role="secondary"] +.yaml ---- - $ mvn -v - Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T14:33:14-04:00) - Maven home: /usr/local/Cellar/maven/3.3.9/libexec - Java version: 1.8.0_102, vendor: Oracle Corporation +include::{verifier_core_path}/src/test/resources/yml/contract_message_scenario3.yml[indent=0] +---- +==== + + +Then you can add Spring Cloud Contract Verifier dependency and plugin to your build file, +as shown in the following example: + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0] ---- -NOTE: This sample needs to be created in its own folder. Subsequent instructions assume -that you have created a suitable folder and that it is your current directory. +The following listing shows how to add the plugin, which should go in the build/plugins +portion of the file: - - -[[getting-started-first-application-pom]] -=== Creating the POM -We need to start by creating a Maven `pom.xml` file. The `pom.xml` is the recipe that is -used to build your project. Open your favorite text editor and add the following: - -[source,xml,indent=0,subs="verbatim,quotes,attributes"] +[source,xml,indent=0] ---- - - - 4.0.0 - - com.example - myproject - 0.0.1-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-parent - {spring-boot-version} - - - - -ifeval::["{spring-boot-repo}" != "release"] - - - - spring-snapshots - https://repo.spring.io/snapshot - true - - - spring-milestones - https://repo.spring.io/milestone - - - - - spring-snapshots - https://repo.spring.io/snapshot - - - spring-milestones - https://repo.spring.io/milestone - - -endif::[] - + + org.springframework.cloud + spring-cloud-contract-maven-plugin + ${spring-cloud-contract.version} + true + ---- -The preceding listing should give you a working build. You can test it by running `mvn -package` (for now, you can ignore the "`jar will be empty - no content was marked for -inclusion!`" warning). +Running `./mvnw clean install` automatically generates tests that verify the application +compliance with the added contracts. By default, the generated tests are under +`org.springframework.cloud.contract.verifier.tests.`. -NOTE: At this point, you could import the project into an IDE (most modern Java IDEs -include built-in support for Maven). For simplicity, we continue to use a plain text -editor for this example. - - - -[[getting-started-first-application-dependencies]] -=== Adding Classpath Dependencies -Spring Boot provides a number of "`Starters`" that let you add jars to your classpath. -Our applications for smoke tests use the `spring-boot-starter-parent` in the `parent` -section of the POM. The `spring-boot-starter-parent` is a special starter that provides -useful Maven defaults. It also provides a -<> -section so that you can omit `version` tags for "`blessed`" dependencies. - -Other "`Starters`" provide dependencies that you are likely to need when developing a -specific type of application. Since we are developing a web application, we add a -`spring-boot-starter-web` dependency. Before that, we can look at what we currently have -by running the following command: - -[indent=0] ----- - $ mvn dependency:tree - - [INFO] com.example:myproject:jar:0.0.1-SNAPSHOT ----- - -The `mvn dependency:tree` command prints a tree representation of your project -dependencies. You can see that `spring-boot-starter-parent` provides no dependencies by -itself. To add the necessary dependencies, edit your `pom.xml` and add the -`spring-boot-starter-web` dependency immediately below the `parent` section: - -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - - org.springframework.boot - spring-boot-starter-web - - ----- - -If you run `mvn dependency:tree` again, you see that there are now a number of additional -dependencies, including the Tomcat web server and Spring Boot itself. - - - -[[getting-started-first-application-code]] -=== Writing the Code -To finish our application, we need to create a single Java file. By default, Maven -compiles sources from `src/main/java`, so you need to create that folder structure and -then add a file named `src/main/java/Example.java` to contain the following code: +The following example shows a sample auto-generated test for an HTTP contract: [source,java,indent=0] ---- - import org.springframework.boot.*; - import org.springframework.boot.autoconfigure.*; - import org.springframework.web.bind.annotation.*; +@Test +public void validate_shouldMarkClientAsFraud() throws Exception { + // given: + MockMvcRequestSpecification request = given() + .header("Content-Type", "application/vnd.fraud.v1+json") + .body("{\"client.id\":\"1234567890\",\"loanAmount\":99999}"); - @RestController - @EnableAutoConfiguration - public class Example { + // when: + ResponseOptions response = given().spec(request) + .put("/fraudcheck"); - @RequestMapping("/") - String home() { - return "Hello World!"; - } + // then: + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.header("Content-Type")).matches("application/vnd.fraud.v1.json.*"); + // and: + DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); + assertThatJson(parsedJson).field("['fraudCheckStatus']").matches("[A-Z]{5}"); + assertThatJson(parsedJson).field("['rejection.reason']").isEqualTo("Amount too high"); +} +---- - public static void main(String[] args) { - SpringApplication.run(Example.class, args); - } +The preceding example uses Spring's `MockMvc` to run the tests. This is the default test +mode for HTTP contracts. However, JAX-RS client and explicit HTTP invocations can also be +used. (To do so, change the `testMode` property of the plugin to `JAX-RS` or `EXPLICIT`, +respectively.) +Since 2.1.0, it is also possible to use `RestAssuredWebTestClient`with Spring's reactive `WebTestClient` +run under the hood. This is particularly recommended while working with Reactive, `Web-Flux`-based applications. +In order to use `WebTestClient` set `testMode` to `WEBTESTCLIENT`. + +Here is an example of a test generated in `WEBTESTCLIENT` test mode: + +[source,java,indent=0] +---- +@Test + public void validate_shouldRejectABeerIfTooYoung() throws Exception { + // given: + WebTestClientRequestSpecification request = given() + .header("Content-Type", "application/json") + .body("{\"age\":10}"); + + // when: + WebTestClientResponse response = given().spec(request) + .post("/check"); + + // then: + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.header("Content-Type")).matches("application/json.*"); + // and: + DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); + assertThatJson(parsedJson).field("['status']").isEqualTo("NOT_OK"); } ---- -Although there is not much code here, quite a lot is going on. We step through the -important parts in the next few sections. +Apart from the default JUnit 4, you can instead use JUnit 5 or Spock tests, by setting the plugin +`testFramework` property to either `JUNIT5` or `Spock`. +TIP: You can now also generate WireMock scenarios based on the contracts, by including an +order number followed by an underscore at the beginning of the contract file names. +The following example shows an auto-generated test in Spock for a messaging stub contract: -[[getting-started-first-application-annotations]] -==== The `@RestController` and `@RequestMapping` Annotations -The first annotation on our `Example` class is `@RestController`. This is known as a -_stereotype_ annotation. It provides hints for people reading the code and for Spring -that the class plays a specific role. In this case, our class is a web `@Controller`, so -Spring considers it when handling incoming web requests. - -The `@RequestMapping` annotation provides "`routing`" information. It tells Spring that -any HTTP request with the `/` path should be mapped to the `home` method. The -`@RestController` annotation tells Spring to render the resulting string directly back to -the caller. - -TIP: The `@RestController` and `@RequestMapping` annotations are Spring MVC annotations. -(They are not specific to Spring Boot.) See the {spring-reference}web.html#mvc[MVC -section] in the Spring Reference Documentation for more details. - - - -[[getting-started-first-application-auto-configuration]] -==== The @EnableAutoConfiguration Annotation -The second class-level annotation is `@EnableAutoConfiguration`. This annotation tells -Spring Boot to "`guess`" how you want to configure Spring, based on the jar dependencies -that you have added. Since `spring-boot-starter-web` added Tomcat and Spring MVC, the -auto-configuration assumes that you are developing a web application and sets up Spring -accordingly. - -.Starters and Auto-configuration -**** -Auto-configuration is designed to work well with "`Starters`", but the two concepts are -not directly tied. You are free to pick and choose jar dependencies outside of the -starters. Spring Boot still does its best to auto-configure your application. -**** - - - -[[getting-started-first-application-main-method]] -==== The "`main`" Method -The final part of our application is the `main` method. This is just a standard method -that follows the Java convention for an application entry point. Our main method -delegates to Spring Boot's `SpringApplication` class by calling `run`. -`SpringApplication` bootstraps our application, starting Spring, which, in turn, starts -the auto-configured Tomcat web server. We need to pass `Example.class` as an argument to -the `run` method to tell `SpringApplication` which is the primary Spring component. The -`args` array is also passed through to expose any command-line arguments. - - - -[[getting-started-first-application-run]] -=== Running the Example -At this point, your application should work. Since you used the -`spring-boot-starter-parent` POM, you have a useful `run` goal that you can use to start -the application. Type `mvn spring-boot:run` from the root project directory to start the -application. You should see output similar to the following: - -[indent=0,subs="attributes"] +[source,groovy,indent=0] ---- - $ mvn spring-boot:run +given: + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + \'\'\'{"bookName":"foo"}\'\'\', + ['sample': 'header'] + ) - . ____ _ __ _ _ - /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ - ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ - \\/ ___)| |_)| | | | | || (_| | ) ) ) ) - ' |____| .__|_| |_|_| |_\__, | / / / / - =========|_|==============|___/=/_/_/_/ - :: Spring Boot :: (v{spring-boot-version}) - ....... . . . - ....... . . . (log output here) - ....... . . . - ........ Started Example in 2.222 seconds (JVM running for 6.514) +when: + contractVerifierMessaging.send(inputMessage, 'jms:delete') + +then: + noExceptionThrown() + bookWasDeleted() ---- -If you open a web browser to `http://localhost:8080`, you should see the following output: +As the implementation of the functionalities described by the contracts is not yet +present, the tests fail. -[indent=0] +To make them pass, you must add the correct implementation of handling either HTTP +requests or messages. Also, you must add a correct base test class for auto-generated +tests to the project. This class is extended by all the auto-generated tests and should +contain all the setup necessary to run them (for example, `RestAssuredMockMvc` controller +setup or messaging test setup). + +Once the implementation and the test base class are in place, the tests pass, and both the +application and the stub artifacts are built and installed in the local Maven repository. +Information about installing the stubs jar to the local repository appears in the logs, as +shown in the following example: + +[source,bash,indent=0] ---- - Hello World! + [INFO] --- spring-cloud-contract-maven-plugin:1.0.0.BUILD-SNAPSHOT:generateStubs (default-generateStubs) @ http-server --- + [INFO] Building jar: /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar + [INFO] + [INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ http-server --- + [INFO] Building jar: /some/path/http-server/target/http-server-0.0.1-SNAPSHOT.jar + [INFO] + [INFO] --- spring-boot-maven-plugin:1.5.5.BUILD-SNAPSHOT:repackage (default) @ http-server --- + [INFO] + [INFO] --- maven-install-plugin:2.5.2:install (default-install) @ http-server --- + [INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.jar + [INFO] Installing /some/path/http-server/pom.xml to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.pom + [INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar ---- -To gracefully exit the application, press `ctrl-c`. +You can now merge the changes and publish both the application and the stub artifacts +in an online repository. +// TODO: Consider moving this section somewhere else +*Docker Project* +In order to enable working with contracts while creating applications in non-JVM +technologies, the `springcloud/spring-cloud-contract` Docker image has been created. It +contains a project that automatically generates tests for HTTP contracts and executes them +in `EXPLICIT` test mode. Then, if the tests pass, it generates Wiremock stubs and, +optionally, publishes them to an artifact manager. In order to use the image, you can +mount the contracts into the `/contracts` directory and set a few environment variables. +// TODO: We should answer the obvious question: Which environment variables? -[[getting-started-first-application-executable-jar]] -=== Creating an Executable Jar -We finish our example by creating a completely self-contained executable jar file that -we could run in production. Executable jars (sometimes called "`fat jars`") are archives -containing your compiled classes along with all of the jar dependencies that your code -needs to run. +[[getting-started-first-application-consumer]] +=== On the Consumer Side -.Executable jars and Java -**** -Java does not provide a standard way to load nested jar files (jar files that are -themselves contained within a jar). This can be problematic if you are looking to -distribute a self-contained application. +`Spring Cloud Contract Stub Runner` can be used in the integration tests to get a running +WireMock instance or messaging route that simulates the actual service. -To solve this problem, many developers use "`uber`" jars. An uber jar packages all the -classes from all the application's dependencies into a single archive. The problem with -this approach is that it becomes hard to see which libraries are in your application. It -can also be problematic if the same filename is used (but with different content) in -multiple jars. +To get started, add the dependency to `Spring Cloud Contract Stub Runner`: -Spring Boot takes a <> and lets you -actually nest jars directly. -**** - -To create an executable jar, we need to add the `spring-boot-maven-plugin` to our -`pom.xml`. To do so, insert the following lines just below the `dependencies` section: - -[source,xml,indent=0,subs="verbatim,quotes,attributes"] +[source,xml,indent=0] ---- - - - - org.springframework.boot - spring-boot-maven-plugin - - - +include::{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0] ---- -NOTE: The `spring-boot-starter-parent` POM includes `` configuration to bind -the `repackage` goal. If you do not use the parent POM, you need to declare this -configuration yourself. See the {spring-boot-maven-plugin-site}/usage.html[plugin -documentation] for details. +You can get the Producer-side stubs installed in your Maven repository in either of two +ways: -Save your `pom.xml` and run `mvn package` from the command line, as follows: - -[indent=0,subs="attributes"] +* By checking out the Producer side repository and adding contracts and generating the +stubs by running the following commands: ++ +[source,bash,indent=0] ---- - $ mvn package - - [INFO] Scanning for projects... - [INFO] - [INFO] ------------------------------------------------------------------------ - [INFO] Building myproject 0.0.1-SNAPSHOT - [INFO] ------------------------------------------------------------------------ - [INFO] .... .. - [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myproject --- - [INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar - [INFO] - [INFO] --- spring-boot-maven-plugin:{spring-boot-version}:repackage (default) @ myproject --- - [INFO] ------------------------------------------------------------------------ - [INFO] BUILD SUCCESS - [INFO] ------------------------------------------------------------------------ +$ cd local-http-server-repo +$ ./mvnw clean install -DskipTests +---- +NOTE: The tests are skipped because the Producer-side contract implementation is not yet +in place, so the automatically-generated contract tests fail. +* Getting already existing producer service stubs from a remote repository. To do so, +pass the stub artifact IDs and artifact repository URl as `Spring Cloud Contract Stub +Runner` properties, as shown in the following example: ++ +[source,yaml,indent=0] +---- +include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/{branch}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[] ---- -If you look in the `target` directory, you should see `myproject-0.0.1-SNAPSHOT.jar`. The -file should be around 10 MB in size. If you want to peek inside, you can use `jar tvf`, -as follows: +Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation, +provide the `group-id` and `artifact-id` for `Spring Cloud Contract Stub Runner` to run +the collaborators' stubs for you, as shown in the following example: -[indent=0] +[source,java, indent=0] ---- - $ jar tvf target/myproject-0.0.1-SNAPSHOT.jar +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.NONE) +@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:6565"}, + stubsMode = StubRunnerProperties.StubsMode.LOCAL) +public class LoanApplicationServiceTests { ---- -You should also see a much smaller file named `myproject-0.0.1-SNAPSHOT.jar.original` in -the `target` directory. This is the original jar file that Maven created before it was -repackaged by Spring Boot. +TIP: Use the `REMOTE` `stubsMode` when downloading stubs from an online repository and +`LOCAL` for offline work. -To run that application, use the `java -jar` command, as follows: +In your integration test, you can receive stubbed versions of HTTP responses or messages +that are expected to be emitted by the collaborator service. You can see entries similar +to the following in the build logs: -[indent=0,subs="attributes"] +[source,bash,indent=0] ---- - $ java -jar target/myproject-0.0.1-SNAPSHOT.jar - - . ____ _ __ _ _ - /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ - ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ - \\/ ___)| |_)| | | | | || (_| | ) ) ) ) - ' |____| .__|_| |_|_| |_\__, | / / / / - =========|_|==============|___/=/_/_/_/ - :: Spring Boot :: (v{spring-boot-version}) - ....... . . . - ....... . . . (log output here) - ....... . . . - ........ Started Example in 2.536 seconds (JVM running for 2.864) +2016-07-19 14:22:25.403 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Desired version is + - will try to resolve the latest version +2016-07-19 14:22:25.438 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Resolved version is 0.0.1-SNAPSHOT +2016-07-19 14:22:25.439 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Resolving artifact com.example:http-server:jar:stubs:0.0.1-SNAPSHOT using remote repositories [] +2016-07-19 14:22:25.451 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Resolved artifact com.example:http-server:jar:stubs:0.0.1-SNAPSHOT to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar +2016-07-19 14:22:25.465 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacking stub from JAR [URI: file:/path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar] +2016-07-19 14:22:25.475 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacked file to [/var/folders/0p/xwq47sq106x1_g3dtv6qfm940000gq/T/contracts100276532569594265] +2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}] ---- -As before, to exit the application, press `ctrl-c`. +[[getting-started-cdc]] +== Step-by-step Guide to Consumer Driven Contracts (CDC) +Consider an example of Fraud Detection and the Loan Issuance process. The business +scenario is such that we want to issue loans to people but do not want them to steal from +us. The current implementation of our system grants loans to everybody. +Assume that `Loan Issuance` is a client to the `Fraud Detection` server. In the current +sprint, we must develop a new feature: if a client wants to borrow too much money, then +we mark the client as a fraud. + +Technical remark - Fraud Detection has an `artifact-id` of `http-server`, while Loan +Issuance has an artifact-id of `http-client`, and both have a `group-id` of `com.example`. + +Social remark - both client and server development teams need to communicate directly and +discuss changes while going through the process. CDC is all about communication. + +The https://github.com/spring-cloud/spring-cloud-contract/tree/{branch}/samples/standalone/dsl/http-server[server +side code is available here] and https://github.com/spring-cloud/spring-cloud-contract/tree/{branch}/samples/standalone/dsl/http-client[the +client code here]. + +TIP: In this case, the producer owns the contracts. Physically, all the contract are +in the producer's repository. + +[[getting-started-cdc-technical-note]] +=== Technical note + +If using the *SNAPSHOT* / *Milestone* / *Release Candidate* versions please add the +following section to your build: + +[source,xml,indent=0,subs="verbatim,attributes",role="primary"] +.Maven +---- +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=repos,indent=0] +---- + +[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"] +.Gradle +---- +include::{introduction_url}/samples/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0] +---- + +=== Consumer side (Loan Issuance) + +As a developer of the Loan Issuance service (a consumer of the Fraud Detection server), you might do the following steps: + +. Start doing TDD by writing a test for your feature. +. Write the missing implementation. +. Clone the Fraud Detection service repository locally. +. Define the contract locally in the repo of Fraud Detection service. +. Add the Spring Cloud Contract (SCC) plugin. +. Run the integration tests. +. File a pull request. +. Create an initial implementation. +. Take over the pull request. +. Write the missing implementation. +. Deploy your app. +. Work online. + +[plantuml, cdc, png] +---- +"Loan Issuance"->"Loan Issuance": start doing TDD\nby writing a test\nfor your feature +"Loan Issuance"->"Loan Issuance": write the \nmissing implementation +"Loan Issuance"->"Fraud Detection": clone the repository +"Loan Issuance"->"Fraud Detection Clone": start working on the clone +"Fraud Detection Clone"->"Fraud Detection Clone": add missing dependencies\ndefine contracts +"Fraud Detection Clone"->"Fraud Detection Clone": add the Spring Cloud \nContract plugin +"Fraud Detection Clone"->"Fraud Detection \nClone Build": install the stubs locally +"Fraud Detection \nClone Build"->"SCC Plugin": generate stubs \nand stubs \nartifact (e.g. stubs-jar) +"Fraud Detection \nClone Build"->"Local storage": install the stubs locally +"Local storage"->"Fraud Detection Build": stub sucessfully installed +"Fraud Detection Build"->"API Producer": Build successful +"API Consumer"->"API Consumer": add SCC Stub Runner \ndependency +"API Consumer"->"API Consumer": write a SCC Stub Runner \nbased contract test +"SCC Stub Runner"->"Nexus / Artifactory": test asks for [API Producer] stubs +"Nexus / Artifactory"->"SCC Stub Runner": fetch the [API Producer] stubs +"SCC Stub Runner"->"SCC Stub Runner": run in memory\n HTTP server stubs +"API Consumer"->"SCC Stub Runner": send a request \nto the HTTP server stub +"SCC Stub Runner"->"API Consumer": communication is correct +---- + +*Start doing TDD by writing a test for your feature.* + +[source,groovy,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=client_tdd,indent=0] +---- + +Assume that you have written a test of your new feature. If a loan application for a big +amount is received, the system should reject that loan application with some description. + +*Write the missing implementation.* + +At some point in time, you need to send a request to the Fraud Detection service. Assume +that you need to send the request containing the ID of the client and the amount the +client wants to borrow. You want to send it to the `/fraudcheck` url via the `PUT` method. + +[source,groovy,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-client/src/main/java/com/example/loan/LoanApplicationService.java[tags=client_call_server,indent=0] +---- + +For simplicity, the port of the Fraud Detection service is set to `8080`, and the +application runs on `8090`. + +If you start the test at this point, it breaks, because no service currently runs on port +`8080`. + +*Clone the Fraud Detection service repository locally.* + +You can start by playing around with the server side contract. To do so, you must first +clone it. + +[source,bash,indent=0] +---- +$ git clone https://your-git-server.com/server-side.git local-http-server-repo +---- + +*Define the contract locally in the repo of Fraud Detection service.* + +As a consumer, you need to define what exactly you want to achieve. You need to formulate +your expectations. To do so, write the following contract: + +IMPORTANT: Place the contract under `src/test/resources/contracts/fraud` folder. The `fraud` folder +is important because the producer's test base class name references that folder. + +==== +[source,groovy,indent=0,role="primary"] +.groovy +---- +include::{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[] +---- + +[source,yaml,indent=0,role="secondary"] +.yaml +---- +include::{introduction_url}/samples/standalone/yml/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.yml[] +---- +==== + +The YML contract is quite straight-forward. However when you take a look at the Contract +written using a statically typed Groovy DSL - you might wonder what the +`value(client(...), server(...))` parts are. By using this notation, Spring Cloud +Contract lets you define parts of a JSON block, a URL, etc., which are dynamic. In case +of an identifier or a timestamp, you need not hardcode a value. You want to allow some +different ranges of values. To enable ranges of values, you can set regular expressions +matching those values for the consumer side. You can provide the body by means of either +a map notation or String with interpolations. +Consult the <> section for more information. We highly recommend using the map notation! + +TIP: You must understand the map notation in order to set up contracts. Please read the +https://groovy-lang.org/json.html[Groovy docs regarding JSON]. + +The previously shown contract is an agreement between two sides that: + +- if an HTTP request is sent with all of +** a `PUT` method on the `/fraudcheck` endpoint, +** a JSON body with a `client.id` that matches the regular expression `[0-9]{10}` and +`loanAmount` equal to `99999`, +** and a `Content-Type` header with a value of `application/vnd.fraud.v1+json`, +- then an HTTP response is sent to the consumer that +** has status `200`, +** contains a JSON body with the `fraudCheckStatus` field containing a value `FRAUD` and +the `rejectionReason` field having value `Amount too high`, +** and a `Content-Type` header with a value of `application/vnd.fraud.v1+json`. + +Once you are ready to check the API in practice in the integration tests, you need to +install the stubs locally. + +*Add the Spring Cloud Contract Verifier plugin.* + +We can add either a Maven or a Gradle plugin. In this example, you see how to add Maven. +First, add the `Spring Cloud Contract` BOM. + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_bom,indent=0] +---- + +Next, add the `Spring Cloud Contract Verifier` Maven plugin + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0] +---- + +Since the plugin was added, you get the `Spring Cloud Contract Verifier` features which, +from the provided contracts: + +- generate and run tests +- produce and install stubs + +You do not want to generate tests since you, as the consumer, want only to play with the +stubs. You need to skip the test generation and execution. When you execute: + +[source,bash,indent=0] +---- +$ cd local-http-server-repo +$ ./mvnw clean install -DskipTests +---- + +In the logs, you see something like this: + +[source,bash,indent=0] +---- +[INFO] --- spring-cloud-contract-maven-plugin:1.0.0.BUILD-SNAPSHOT:generateStubs (default-generateStubs) @ http-server --- +[INFO] Building jar: /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar +[INFO] +[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ http-server --- +[INFO] Building jar: /some/path/http-server/target/http-server-0.0.1-SNAPSHOT.jar +[INFO] +[INFO] --- spring-boot-maven-plugin:1.5.5.BUILD-SNAPSHOT:repackage (default) @ http-server --- +[INFO] +[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ http-server --- +[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.jar +[INFO] Installing /some/path/http-server/pom.xml to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.pom +[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar +---- + +The following line is extremely important: + +[source,bash,indent=0] +---- +[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar +---- + +It confirms that the stubs of the `http-server` have been installed in the local +repository. + +*Run the integration tests.* + +In order to profit from the Spring Cloud Contract Stub Runner functionality of automatic +stub downloading, you must do the following in your consumer side project (`Loan +Application service`): + +Add the `Spring Cloud Contract` BOM: + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=contract_bom,indent=0] +---- + +Add the dependency to `Spring Cloud Contract Stub Runner`: + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0] +---- + +Annotate your test class with `@AutoConfigureStubRunner`. In the annotation, provide the +`group-id` and `artifact-id` for the Stub Runner to download the stubs of your +collaborators. (Optional step) Because you're playing with the collaborators offline, you +can also provide the offline work switch (`StubRunnerProperties.StubsMode.LOCAL`). + +[source,groovy,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=autoconfigure_stubrunner,indent=0] +---- + +Now, when you run your tests, you see something like this: + +[source,bash,indent=0] +---- +2016-07-19 14:22:25.403 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Desired version is + - will try to resolve the latest version +2016-07-19 14:22:25.438 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Resolved version is 0.0.1-SNAPSHOT +2016-07-19 14:22:25.439 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Resolving artifact com.example:http-server:jar:stubs:0.0.1-SNAPSHOT using remote repositories [] +2016-07-19 14:22:25.451 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Resolved artifact com.example:http-server:jar:stubs:0.0.1-SNAPSHOT to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar +2016-07-19 14:22:25.465 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacking stub from JAR [URI: file:/path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar] +2016-07-19 14:22:25.475 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacked file to [/var/folders/0p/xwq47sq106x1_g3dtv6qfm940000gq/T/contracts100276532569594265] +2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}] +---- + +This output means that Stub Runner has found your stubs and started a server for your app +with group id `com.example`, artifact id `http-server` with version `0.0.1-SNAPSHOT` of +the stubs and with `stubs` classifier on port `8080`. + +*File a pull request.* + +What you have done until now is an iterative process. You can play around with the +contract, install it locally, and work on the consumer side until the contract works as +you wish. + +Once you are satisfied with the results and the test passes, publish a pull request to +the server side. Currently, the consumer side work is done. + +=== Producer side (Fraud Detection server) + +As a developer of the Fraud Detection server (a server to the Loan Issuance service): + +*Create an initial implementation.* + +As a reminder, you can see the initial implementation here: + +[source,java,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0] +include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0] +} +---- + +*Take over the pull request.* + +[source,bash,indent=0] +---- +$ git checkout -b contract-change-pr master +$ git pull https://your-git-server.com/server-side-fork.git contract-change-pr +---- + +You must add the dependencies needed by the autogenerated tests: + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0] +---- + +In the configuration of the Maven plugin, pass the `packageWithBaseClasses` property + +[source,xml,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0] +---- + +IMPORTANT: This example uses "convention based" naming by setting the +`packageWithBaseClasses` property. Doing so means that the two last packages combine to +make the name of the base test class. In our case, the contracts were placed under +`src/test/resources/contracts/fraud`. Since you do not have two packages starting from +the `contracts` folder, pick only one, which should be `fraud`. Add the `Base` suffix and +capitalize `fraud`. That gives you the `FraudBase` test class name. + +All the generated tests extend that class. Over there, you can set up your Spring Context +or whatever is necessary. In this case, use https://github.com/rest-assured/rest-assured[Rest Assured MVC] to +start the server side `FraudDetectionController`. + +[source,java,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/src/test/java/com/example/fraud/FraudBase.java[] +---- + +Now, if you run the `./mvnw clean install`, you get something like this: + +[source,bash,indent=0] +---- +Results : + +Tests in error: + ContractVerifierTest.validate_shouldMarkClientAsFraud:32 » IllegalState Parsed... +---- + +This error occurs because you have a new contract from which a test was generated and it +failed since you have not implemented the feature. The auto-generated test would look +like this: + +[source,java,indent=0] +---- +@Test +public void validate_shouldMarkClientAsFraud() throws Exception { + // given: + MockMvcRequestSpecification request = given() + .header("Content-Type", "application/vnd.fraud.v1+json") + .body("{\"client.id\":\"1234567890\",\"loanAmount\":99999}"); + + // when: + ResponseOptions response = given().spec(request) + .put("/fraudcheck"); + + // then: + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.header("Content-Type")).matches("application/vnd.fraud.v1.json.*"); + // and: + DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); + assertThatJson(parsedJson).field("['fraudCheckStatus']").matches("[A-Z]{5}"); + assertThatJson(parsedJson).field("['rejection.reason']").isEqualTo("Amount too high"); +} +---- + +If you used the Groovy DSL, you can see, all the `producer()` parts of the Contract that were present in the +`value(consumer(...), producer(...))` blocks got injected into the test. +In case of using YAML, the same applied for the `matchers` sections of the `response`. + +Note that, on the producer side, you are also doing TDD. The expectations are expressed +in the form of a test. This test sends a request to our own application with the URL, +headers, and body defined in the contract. It also is expecting precisely defined values +in the response. In other words, you have the `red` part of `red`, `green`, and +`refactor`. It is time to convert the `red` into the `green`. + +*Write the missing implementation.* + +Because you know the expected input and expected output, you can write the missing +implementation: + +[source,java,indent=0] +---- +include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0] +include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=new_impl,indent=0] +include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0] +} +---- + +When you execute `./mvnw clean install` again, the tests pass. Since the `Spring Cloud +Contract Verifier` plugin adds the tests to the `generated-test-sources`, you can +actually run those tests from your IDE. + +*Deploy your app.* + +Once you finish your work, you can deploy your change. First, merge the branch: + +[source,bash,indent=0] +---- +$ git checkout master +$ git merge --no-ff contract-change-pr +$ git push origin master +---- + +Your CI might run something like `./mvnw clean deploy`, which would publish both the +application and the stub artifacts. + +=== Consumer Side (Loan Issuance) Final Step + +As a developer of the Loan Issuance service (a consumer of the Fraud Detection server): + +*Merge branch to master.* + +[source,bash,indent=0] +---- +$ git checkout master +$ git merge --no-ff contract-change-pr +---- + +*Work online.* + +Now you can disable the offline work for Spring Cloud Contract Stub Runner and indicate +where the repository with your stubs is located. At this moment the stubs of the server +side are automatically downloaded from Nexus/Artifactory. You can set the value of +`stubsMode` to `REMOTE`. The following code shows an example of +achieving the same thing by changing the properties. + +[source,yaml,indent=0] +---- +include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/{branch}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[] +---- + +That's it! [[getting-started-whats-next]] == What to Read Next -Hopefully, this section provided some of the Spring Boot basics and got you on your way +Hopefully, this section provided some of the {project-full-name} basics and got you on your way to writing your own applications. If you are a task-oriented type of developer, you might want to jump over to https://spring.io and check out some of the https://spring.io/guides/[getting started] guides that solve specific "`How do I do that -with Spring?`" problems. We also have Spring Boot-specific +with Spring?`" problems. We also have {project-full-name}-specific "`<>`" reference documentation. -Otherwise, the next logical step is to read _<>_. If +Otherwise, the next logical step is to read _<>_. If you are really impatient, you could also jump ahead and read about -_<>_. +_<>_. + +// TODO: Update the video +// TODO: Check if we can link courses +In addition to that you can check out the video from the Warsaw JUG about Spring Cloud Contract: + +video::sAAklvxmPmk[youtube,start=538,width=640,height=480] + +You can read the following articles / presentations: + +// TODO: Update the readings +- https://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura[Slides from Marcin Grzejszczak's talk about Accurest] +- https://toomuchcoding.com/blog/categories/accurest/[Accurest related articles from Marcin Grzejszczak's blog] +- https://toomuchcoding.com/blog/categories/spring-cloud-contract/[Spring Cloud Contract related articles from Marcin Grzejszczak's blog] +- https://groovy-lang.org/json.html[Groovy docs regarding JSON] + +You can find the default project samples at +https://github.com/spring-cloud-samples/spring-cloud-contract-samples[samples]. \ No newline at end of file diff --git a/docs/src/main/asciidoc/project-features.adoc b/docs/src/main/asciidoc/project-features.adoc new file mode 100644 index 0000000000..c48708d7cc --- /dev/null +++ b/docs/src/main/asciidoc/project-features.adoc @@ -0,0 +1,9041 @@ +[[boot-features]] += Spring Boot Features +include::attributes.adoc[] + +This section dives into the details of Spring Boot. Here you can learn about the key +features that you may want to use and customize. If you have not already done so, you +might want to read the "<>" and +"<>" sections, so that you have a good grounding of the +basics. + + + +[[boot-features-spring-application]] +== SpringApplication +The `SpringApplication` class provides a convenient way to bootstrap a Spring application +that is started from a `main()` method. In many situations, you can delegate to the +static `SpringApplication.run` method, as shown in the following example: + +[source,java,indent=0] +---- + public static void main(String[] args) { + SpringApplication.run(MySpringConfiguration.class, args); + } +---- + +When your application starts, you should see something similar to the following output: + +[indent=0,subs="attributes"] +---- + . ____ _ __ _ _ + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ + \\/ ___)| |_)| | | | | || (_| | ) ) ) ) + ' |____| .__|_| |_|_| |_\__, | / / / / + =========|_|==============|___/=/_/_/_/ + :: Spring Boot :: v{spring-boot-version} + +2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb) +2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy +2014-03-04 13:09:54.912 INFO 41370 --- [ main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080 +2014-03-04 13:09:56.501 INFO 41370 --- [ main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658) +---- + +By default, `INFO` logging messages are shown, including some relevant startup details, +such as the user that launched the application. If you need a log level other than `INFO`, +you can set it, as described in <>, + + + +[[boot-features-startup-failure]] +=== Startup Failure +If your application fails to start, registered `FailureAnalyzers` get a chance to provide +a dedicated error message and a concrete action to fix the problem. For instance, if you +start a web application on port `8080` and that port is already in use, you should see +something similar to the following message: + +[indent=0] +---- + *************************** + APPLICATION FAILED TO START + *************************** + + Description: + + Embedded servlet container failed to start. Port 8080 was already in use. + + Action: + + Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. +---- + +NOTE: Spring Boot provides numerous `FailureAnalyzer` implementations, and you can +<>. + +If no failure analyzers are able to handle the exception, you can still display the full +conditions report to better understand what went wrong. To do so, you need to +<> or +<> for +`org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener`. + +For instance, if you are running your application by using `java -jar`, you can enable +the `debug` property as follows: + +[indent=0,subs="attributes"] +---- + $ java -jar myproject-0.0.1-SNAPSHOT.jar --debug +---- + + + +[[boot-features-lazy-initialization]] +=== Lazy Initialization +`SpringApplication` allows an application to be initialized lazily. When lazy +initialization is enabled, beans are created as they are needed rather than during +application startup. As a result, enabling lazy initialization can reduce the time that +it takes your application to start. In a web application, enabling lazy initialization +will result in many web-related beans not being initialized until an HTTP request is +received. + +A downside of lazy initialization is that it can delay the discovery of a problem with +the application. If a misconfigured bean is initialized lazily, a failure will no longer +occur during startup and the problem will only become apparent when the bean is +initialized. Care must also be taken to ensure that the JVM has sufficient memory to +accommodate all of the application's beans and not just those that are initialized during +startup. For these reasons, lazy initialization is not enabled by default and it is +recommended that fine-tuning of the JVM's heap size is done before enabling lazy +initialization. + +Lazy initialization can be enabled programatically using the `lazyInitialization` method +on `SpringApplicationBuilder` or the `setLazyInitialization` method on +`SpringApplication`. Alternatively, it can be enabled using the +`spring.main.lazy-initialization` property as shown in the following example: + +[source,properties,indent=0] +---- + spring.main.lazy-initialization=true +---- + +TIP: If you want to disable lazy initialization for certain beans while using lazy +initialization for the rest of the application, you can explicitly set their lazy attribute +to false using the `@Lazy(false)` annotation. + + + +[[boot-features-banner]] +=== Customizing the Banner +The banner that is printed on start up can be changed by adding a `banner.txt` file to +your classpath or by setting the `spring.banner.location` property to the location of such +a file. If the file has an encoding other than UTF-8, you can set `spring.banner.charset`. +In addition to a text file, you can also add a `banner.gif`, `banner.jpg`, or `banner.png` +image file to your classpath or set the `spring.banner.image.location` property. Images +are converted into an ASCII art representation and printed above any text banner. + +Inside your `banner.txt` file, you can use any of the following placeholders: + +.Banner variables +|=== +| Variable | Description + +|`${application.version}` +|The version number of your application, as declared in `MANIFEST.MF`. For example, +`Implementation-Version: 1.0` is printed as `1.0`. + +|`${application.formatted-version}` +|The version number of your application, as declared in `MANIFEST.MF` and formatted for +display (surrounded with brackets and prefixed with `v`). For example `(v1.0)`. + +|`${spring-boot.version}` +|The Spring Boot version that you are using. For example `{spring-boot-version}`. + +|`${spring-boot.formatted-version}` +|The Spring Boot version that you are using, formatted for display (surrounded with +brackets and prefixed with `v`). For example `(v{spring-boot-version})`. + +|`${Ansi.NAME}` (or `${AnsiColor.NAME}`, `${AnsiBackground.NAME}`, `${AnsiStyle.NAME}`) +|Where `NAME` is the name of an ANSI escape code. See +{sc-spring-boot}/ansi/AnsiPropertySource.{sc-ext}[`AnsiPropertySource`] for details. + +|`${application.title}` +|The title of your application, as declared in `MANIFEST.MF`. For example +`Implementation-Title: MyApp` is printed as `MyApp`. +|=== + +TIP: The `SpringApplication.setBanner(...)` method can be used if you want to generate +a banner programmatically. Use the `org.springframework.boot.Banner` interface and +implement your own `printBanner()` method. + +You can also use the `spring.main.banner-mode` property to determine if the banner has +to be printed on `System.out` (`console`), sent to the configured logger (`log`), or not +produced at all (`off`). + +The printed banner is registered as a singleton bean under the following name: +`springBootBanner`. + + + +[[boot-features-customizing-spring-application]] +=== Customizing SpringApplication +If the `SpringApplication` defaults are not to your taste, you can instead create a local +instance and customize it. For example, to turn off the banner, you could write: + +[source,java,indent=0] +---- + public static void main(String[] args) { + SpringApplication app = new SpringApplication(MySpringConfiguration.class); + app.setBannerMode(Banner.Mode.OFF); + app.run(args); + } +---- + +NOTE: The constructor arguments passed to `SpringApplication` are configuration sources +for Spring beans. In most cases, these are references to `@Configuration` classes, but +they could also be references to XML configuration or to packages that should be scanned. + +It is also possible to configure the `SpringApplication` by using an +`application.properties` file. See _<>_ for details. + +For a complete list of the configuration options, see the +{dc-spring-boot}/SpringApplication.{dc-ext}[`SpringApplication` Javadoc]. + + + +[[boot-features-fluent-builder-api]] +=== Fluent Builder API +If you need to build an `ApplicationContext` hierarchy (multiple contexts with a +parent/child relationship) or if you prefer using a "`fluent`" builder API, you can +use the `SpringApplicationBuilder`. + +The `SpringApplicationBuilder` lets you chain together multiple method calls and includes +`parent` and `child` methods that let you create a hierarchy, as shown in the following +example: + +[source,java,indent=0] +---- +include::{code-examples}/builder/SpringApplicationBuilderExample.java[tag=hierarchy] +---- + +NOTE: There are some restrictions when creating an `ApplicationContext` hierarchy. For +example, Web components *must* be contained within the child context, and the same +`Environment` is used for both parent and child contexts. See the +{dc-spring-boot}/builder/SpringApplicationBuilder.{dc-ext}[`SpringApplicationBuilder` +Javadoc] for full details. + + + +[[boot-features-application-events-and-listeners]] +=== Application Events and Listeners +In addition to the usual Spring Framework events, such as +{spring-javadoc}/context/event/ContextRefreshedEvent.{dc-ext}[`ContextRefreshedEvent`], +a `SpringApplication` sends some additional application events. + +[NOTE] +==== +Some events are actually triggered before the `ApplicationContext` is created, so you +cannot register a listener on those as a `@Bean`. You can register them with the +`SpringApplication.addListeners(...)` method or the +`SpringApplicationBuilder.listeners(...)` method. + +If you want those listeners to be registered automatically, regardless of the way the +application is created, you can add a `META-INF/spring.factories` file to your project +and reference your listener(s) by using the +`org.springframework.context.ApplicationListener` key, as shown in the following example: + +[indent=0] +---- + org.springframework.context.ApplicationListener=com.example.project.MyListener +---- + +==== + +Application events are sent in the following order, as your application runs: + +. An `ApplicationStartingEvent` is sent at the start of a run but before any processing, +except for the registration of listeners and initializers. +. An `ApplicationEnvironmentPreparedEvent` is sent when the `Environment` to be used in +the context is known but before the context is created. +. An `ApplicationContextInitializedEvent` is sent when the `ApplicationContext` is prepared +and ApplicationContextInitializers have been called but before any bean definitions are loaded. +. An `ApplicationPreparedEvent` is sent just before the refresh is started but after bean +definitions have been loaded. +. An `ApplicationStartedEvent` is sent after the context has been refreshed but before any +application and command-line runners have been called. +. An `ApplicationReadyEvent` is sent after any application and command-line runners have +been called. It indicates that the application is ready to service requests. +. An `ApplicationFailedEvent` is sent if there is an exception on startup. + +The above list only includes `SpringApplicationEvent`s that are tied to a `SpringApplication`. +In addition to these, the following events are also published after `ApplicationPreparedEvent` +and before `ApplicationStartedEvent`: + +. A `ContextRefreshedEvent` is sent when an `ApplicationContext` is refreshed. +. A `WebServerInitializedEvent` is sent after the `WebServer` is ready. `ServletWebServerInitializedEvent` +and `ReactiveWebServerInitializedEvent` are the servlet and reactive variants respectively. + +TIP: You often need not use application events, but it can be handy to know that they +exist. Internally, Spring Boot uses events to handle a variety of tasks. + +Application events are sent by using Spring Framework's event publishing mechanism. Part +of this mechanism ensures that an event published to the listeners in a child context is +also published to the listeners in any ancestor contexts. As a result of this, if your +application uses a hierarchy of `SpringApplication` instances, a listener may receive +multiple instances of the same type of application event. + +To allow your listener to distinguish between an event for its context and an event for +a descendant context, it should request that its application context is injected and then +compare the injected context with the context of the event. The context can be injected +by implementing `ApplicationContextAware` or, if the listener is a bean, by using +`@Autowired`. + + + +[[boot-features-web-environment]] +=== Web Environment +A `SpringApplication` attempts to create the right type of `ApplicationContext` on your +behalf. The algorithm used to determine a `WebApplicationType` is fairly simple: + +* If Spring MVC is present, an `AnnotationConfigServletWebServerApplicationContext` is +used +* If Spring MVC is not present and Spring WebFlux is present, an +`AnnotationConfigReactiveWebServerApplicationContext` is used +* Otherwise, `AnnotationConfigApplicationContext` is used + +This means that if you are using Spring MVC and the new `WebClient` from Spring WebFlux in +the same application, Spring MVC will be used by default. You can override that easily +by calling `setWebApplicationType(WebApplicationType)`. + +It is also possible to take complete control of the `ApplicationContext` type that is +used by calling `setApplicationContextClass(...)`. + +TIP: It is often desirable to call `setWebApplicationType(WebApplicationType.NONE)` when +using `SpringApplication` within a JUnit test. + + + +[[boot-features-application-arguments]] +=== Accessing Application Arguments +If you need to access the application arguments that were passed to +`SpringApplication.run(...)`, you can inject a +`org.springframework.boot.ApplicationArguments` bean. The `ApplicationArguments` +interface provides access to both the raw `String[]` arguments as well as parsed `option` +and `non-option` arguments, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.boot.*; + import org.springframework.beans.factory.annotation.*; + import org.springframework.stereotype.*; + + @Component + public class MyBean { + + @Autowired + public MyBean(ApplicationArguments args) { + boolean debug = args.containsOption("debug"); + List files = args.getNonOptionArgs(); + // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"] + } + + } +---- + +TIP: Spring Boot also registers a `CommandLinePropertySource` with the Spring +`Environment`. This lets you also inject single application arguments by using the +`@Value` annotation. + + + +[[boot-features-command-line-runner]] +=== Using the ApplicationRunner or CommandLineRunner +If you need to run some specific code once the `SpringApplication` has started, you can +implement the `ApplicationRunner` or `CommandLineRunner` interfaces. Both interfaces work +in the same way and offer a single `run` method, which is called just before +`SpringApplication.run(...)` completes. + +The `CommandLineRunner` interfaces provides access to application arguments as a simple +string array, whereas the `ApplicationRunner` uses the `ApplicationArguments` interface +discussed earlier. The following example shows a `CommandLineRunner` with a `run` method: + +[source,java,indent=0] +---- + import org.springframework.boot.*; + import org.springframework.stereotype.*; + + @Component + public class MyBean implements CommandLineRunner { + + public void run(String... args) { + // Do something... + } + + } +---- + +If several `CommandLineRunner` or `ApplicationRunner` beans are defined that must be +called in a specific order, you can additionally implement the +`org.springframework.core.Ordered` interface or use the +`org.springframework.core.annotation.Order` annotation. + + + +[[boot-features-application-exit]] +=== Application Exit +Each `SpringApplication` registers a shutdown hook with the JVM to ensure that the +`ApplicationContext` closes gracefully on exit. All the standard Spring lifecycle +callbacks (such as the `DisposableBean` interface or the `@PreDestroy` annotation) can be +used. + +In addition, beans may implement the `org.springframework.boot.ExitCodeGenerator` +interface if they wish to return a specific exit code when `SpringApplication.exit()` is +called. This exit code can then be passed to `System.exit()` to return it as a status +code, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/ExitCodeApplication.java[tag=example] +---- + +Also, the `ExitCodeGenerator` interface may be implemented by exceptions. When such an +exception is encountered, Spring Boot returns the exit code provided by the implemented +`getExitCode()` method. + + +[[boot-features-application-admin]] +=== Admin Features +It is possible to enable admin-related features for the application by specifying the +`spring.application.admin.enabled` property. This exposes the +{sc-spring-boot}/admin/SpringApplicationAdminMXBean.{sc-ext}[`SpringApplicationAdminMXBean`] +on the platform `MBeanServer`. You could use this feature to administer your Spring Boot +application remotely. This feature could also be useful for any service wrapper +implementation. + +TIP: If you want to know on which HTTP port the application is running, get the property +with a key of `local.server.port`. + +CAUTION: Take care when enabling this feature, as the MBean exposes a method to shutdown +the application. + + + +[[boot-features-external-config]] +== Externalized Configuration +Spring Boot lets you externalize your configuration so that you can work with the same +application code in different environments. You can use properties files, YAML files, +environment variables, and command-line arguments to externalize configuration. Property +values can be injected directly into your beans by using the `@Value` annotation, +accessed through Spring's `Environment` abstraction, or be +<> through `@ConfigurationProperties`. + +Spring Boot uses a very particular `PropertySource` order that is designed to allow +sensible overriding of values. Properties are considered in the following order: + +. <> +on your home directory (`~/.spring-boot-devtools.properties` when devtools is active). +. {spring-javadoc}/test/context/TestPropertySource.{dc-ext}[`@TestPropertySource`] +annotations on your tests. +. `properties` attribute on your tests. Available on +{dc-spring-boot-test}/context/SpringBootTest.{dc-ext}[`@SpringBootTest`] and the +<>. +. Command line arguments. +. Properties from `SPRING_APPLICATION_JSON` (inline JSON embedded in an environment +variable or system property). +. `ServletConfig` init parameters. +. `ServletContext` init parameters. +. JNDI attributes from `java:comp/env`. +. Java System properties (`System.getProperties()`). +. OS environment variables. +. A `RandomValuePropertySource` that has properties only in `+random.*+`. +. <> outside of your packaged jar +(`application-\{profile}.properties` and YAML variants). +. <> packaged inside your jar (`application-\{profile}.properties` +and YAML variants). +. Application properties outside of your packaged jar (`application.properties` and YAML +variants). +. Application properties packaged inside your jar (`application.properties` and YAML +variants). +. {spring-javadoc}/context/annotation/PropertySource.{dc-ext}[`@PropertySource`] +annotations on your `@Configuration` classes. +. Default properties (specified by setting `SpringApplication.setDefaultProperties`). + +To provide a concrete example, suppose you develop a `@Component` that uses a `name` +property, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.stereotype.*; + import org.springframework.beans.factory.annotation.*; + + @Component + public class MyBean { + + @Value("${name}") + private String name; + + // ... + + } +---- + +On your application classpath (for example, inside your jar) you can have an +`application.properties` file that provides a sensible default property value for `name`. +When running in a new environment, an `application.properties` file can be provided +outside of your jar that overrides the `name`. For one-off testing, you can launch with a +specific command line switch (for example, `java -jar app.jar --name="Spring"`). + +[TIP] +==== +The `SPRING_APPLICATION_JSON` properties can be supplied on the command line with an +environment variable. For example, you could use the following line in a UN{asterisk}X +shell: + +---- +$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar +---- + +In the preceding example, you end up with `acme.name=test` in the Spring `Environment`. +You can also supply the JSON as `spring.application.json` in a System property, as shown +in the following example: + +---- +$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar +---- + +You can also supply the JSON by using a command line argument, as shown in the following +example: + +---- +$ java -jar myapp.jar --spring.application.json='{"name":"test"}' +---- + +You can also supply the JSON as a JNDI variable, as follows: +`java:comp/env/spring.application.json`. +==== + + + +[[boot-features-external-config-random-values]] +=== Configuring Random Values +The `RandomValuePropertySource` is useful for injecting random values (for example, into +secrets or test cases). It can produce integers, longs, uuids, or strings, as shown in the +following example: + +[source,properties,indent=0] +---- + my.secret=${random.value} + my.number=${random.int} + my.bignumber=${random.long} + my.uuid=${random.uuid} + my.number.less.than.ten=${random.int(10)} + my.number.in.range=${random.int[1024,65536]} +---- + +The `+random.int*+` syntax is `OPEN value (,max) CLOSE` where the `OPEN,CLOSE` are any +character and `value,max` are integers. If `max` is provided, then `value` is the minimum +value and `max` is the maximum value (exclusive). + + + +[[boot-features-external-config-command-line-args]] +=== Accessing Command Line Properties +By default, `SpringApplication` converts any command line option arguments (that is, +arguments starting with `--`, such as `--server.port=9000`) to a `property` and adds +them to the Spring `Environment`. As mentioned previously, command line properties always +take precedence over other property sources. + +If you do not want command line properties to be added to the `Environment`, you can +disable them by using `SpringApplication.setAddCommandLineProperties(false)`. + + + +[[boot-features-external-config-application-property-files]] +=== Application Property Files +`SpringApplication` loads properties from `application.properties` files in the following +locations and adds them to the Spring `Environment`: + +. A `/config` subdirectory of the current directory +. The current directory +. A classpath `/config` package +. The classpath root + +The list is ordered by precedence (properties defined in locations higher in the list +override those defined in lower locations). + +NOTE: You can also <> as an +alternative to '.properties'. + +If you do not like `application.properties` as the configuration file name, you can +switch to another file name by specifying a `spring.config.name` environment property. +You can also refer to an explicit location by using the `spring.config.location` +environment property (which is a comma-separated list of directory locations or file +paths). The following example shows how to specify a different file name: + +[indent=0] +---- + $ java -jar myproject.jar --spring.config.name=myproject +---- + +The following example shows how to specify two locations: + +[indent=0] +---- + $ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties +---- + +WARNING: `spring.config.name` and `spring.config.location` are used very early to +determine which files have to be loaded, so they must be defined as an environment +property (typically an OS environment variable, a system property, or a command-line +argument). + +If `spring.config.location` contains directories (as opposed to files), they should end +in `/` (and, at runtime, be appended with the names generated from `spring.config.name` +before being loaded, including profile-specific file names). Files specified in +`spring.config.location` are used as-is, with no support for profile-specific variants, +and are overridden by any profile-specific properties. + +Config locations are searched in reverse order. By default, the configured locations are +`classpath:/,classpath:/config/,file:./,file:./config/`. The resulting search order is +the following: + +. `file:./config/` +. `file:./` +. `classpath:/config/` +. `classpath:/` + +When custom config locations are configured by using `spring.config.location`, they +replace the default locations. For example, if `spring.config.location` is configured with +the value `classpath:/custom-config/,file:./custom-config/`, the search order becomes the +following: + +. `file:./custom-config/` +. `classpath:custom-config/` + +Alternatively, when custom config locations are configured by using +`spring.config.additional-location`, they are used in addition to the default locations. +Additional locations are searched before the default locations. For example, if +additional locations of `classpath:/custom-config/,file:./custom-config/` are configured, +the search order becomes the following: + +. `file:./custom-config/` +. `classpath:custom-config/` +. `file:./config/` +. `file:./` +. `classpath:/config/` +. `classpath:/` + +This search ordering lets you specify default values in one configuration file and then +selectively override those values in another. You can provide default values for your +application in `application.properties` (or whatever other basename you choose with +`spring.config.name`) in one of the default locations. These default values can then be +overridden at runtime with a different file located in one of the custom locations. + +NOTE: If you use environment variables rather than system properties, most operating +systems disallow period-separated key names, but you can use underscores instead (for +example, `SPRING_CONFIG_NAME` instead of `spring.config.name`). + +NOTE: If your application runs in a container, then JNDI properties (in `java:comp/env`) +or servlet context initialization parameters can be used instead of, or as well as, +environment variables or system properties. + + + +[[boot-features-external-config-profile-specific-properties]] +=== Profile-specific Properties +In addition to `application.properties` files, profile-specific properties can also be +defined by using the following naming convention: `application-\{profile}.properties`. The +`Environment` has a set of default profiles (by default, `[default]`) that are used if no +active profiles are set. In other words, if no profiles are explicitly activated, then +properties from `application-default.properties` are loaded. + +Profile-specific properties are loaded from the same locations as standard +`application.properties`, with profile-specific files always overriding the non-specific +ones, whether or not the profile-specific files are inside or outside your +packaged jar. + +If several profiles are specified, a last-wins strategy applies. For example, profiles +specified by the `spring.profiles.active` property are added after those configured +through the `SpringApplication` API and therefore take precedence. + +NOTE: If you have specified any files in `spring.config.location`, profile-specific +variants of those files are not considered. Use directories in +`spring.config.location` if you want to also use profile-specific properties. + + + +[[boot-features-external-config-placeholders-in-properties]] +=== Placeholders in Properties +The values in `application.properties` are filtered through the existing `Environment` +when they are used, so you can refer back to previously defined values (for example, from +System properties). + +[source,properties,indent=0] +---- + app.name=MyApp + app.description=${app.name} is a Spring Boot application +---- + +TIP: You can also use this technique to create "`short`" variants of existing Spring Boot +properties. See the _<>_ how-to for +details. + + + +[[boot-features-encrypting-properties]] +=== Encrypting Properties +Spring Boot does not provide any built in support for encrypting property values, however, +it does provide the hook points necessary to modify values contained in the Spring +`Environment`. The `EnvironmentPostProcessor` interface allows you to manipulate the +`Environment` before the application starts. See <> +for details. + +If you're looking for a secure way to store credentials and passwords, the +https://cloud.spring.io/spring-cloud-vault/[Spring Cloud Vault] project provides +support for storing externalized configuration in +https://www.vaultproject.io/[HashiCorp Vault]. + + + +[[boot-features-external-config-yaml]] +=== Using YAML Instead of Properties +https://yaml.org[YAML] is a superset of JSON and, as such, is a convenient format for +specifying hierarchical configuration data. The `SpringApplication` class automatically +supports YAML as an alternative to properties whenever you have the +https://bitbucket.org/asomov/snakeyaml[SnakeYAML] library on your classpath. + +NOTE: If you use "`Starters`", SnakeYAML is automatically provided by +`spring-boot-starter`. + + + +[[boot-features-external-config-loading-yaml]] +==== Loading YAML +Spring Framework provides two convenient classes that can be used to load YAML documents. +The `YamlPropertiesFactoryBean` loads YAML as `Properties` and the `YamlMapFactoryBean` +loads YAML as a `Map`. + +For example, consider the following YAML document: + +[source,yaml,indent=0] +---- + environments: + dev: + url: https://dev.example.com + name: Developer Setup + prod: + url: https://another.example.com + name: My Cool App +---- + +The preceding example would be transformed into the following properties: + +[source,properties,indent=0] +---- + environments.dev.url=https://dev.example.com + environments.dev.name=Developer Setup + environments.prod.url=https://another.example.com + environments.prod.name=My Cool App +---- + +YAML lists are represented as property keys with `[index]` dereferencers. For example, +consider the following YAML: + +[source,yaml,indent=0] +---- + my: + servers: + - dev.example.com + - another.example.com +---- + +The preceding example would be transformed into these properties: + +[source,properties,indent=0] +---- + my.servers[0]=dev.example.com + my.servers[1]=another.example.com +---- + +To bind to properties like that by using Spring Boot's `Binder` utilities (which is what +`@ConfigurationProperties` does), you need to have a property in the target bean of type +`java.util.List` (or `Set`) and you either need to provide a setter or initialize it with +a mutable value. For example, the following example binds to the properties shown +previously: + +[source,java,indent=0] +---- + @ConfigurationProperties(prefix="my") + public class Config { + + private List servers = new ArrayList(); + + public List getServers() { + return this.servers; + } + } +---- + + + +[[boot-features-external-config-exposing-yaml-to-spring]] +==== Exposing YAML as Properties in the Spring Environment +The `YamlPropertySourceLoader` class can be used to expose YAML as a `PropertySource` in +the Spring `Environment`. Doing so lets you use the `@Value` annotation with placeholders +syntax to access YAML properties. + + + +[[boot-features-external-config-multi-profile-yaml]] +==== Multi-profile YAML Documents +You can specify multiple profile-specific YAML documents in a single file by using a +`spring.profiles` key to indicate when the document applies, as shown in the following +example: + +[source,yaml,indent=0] +---- + server: + address: 192.168.1.100 + --- + spring: + profiles: development + server: + address: 127.0.0.1 + --- + spring: + profiles: production & eu-central + server: + address: 192.168.1.120 +---- + +In the preceding example, if the `development` profile is active, the `server.address` +property is `127.0.0.1`. Similarly, if the `production` *and* `eu-central` profiles are +active, the `server.address` property is `192.168.1.120`. If the `development`, +`production` and `eu-central` profiles are *not* enabled, then the value for the property +is `192.168.1.100`. + +[NOTE] +==== +`spring.profiles` can therefore contain a simple profile name (for example `production`) +or a profile expression. A profile expression allows for more complicated profile logic +to be expressed, for example `production & (eu-central | eu-west)`. Check the +{spring-reference}core.html#beans-definition-profiles-java[reference guide] for more +details. +==== + +If none are explicitly active when the application context starts, the default profiles +are activated. So, in the following YAML, we set a value for `spring.security.user.password` +that is available *only* in the "default" profile: + +[source,yaml,indent=0] +---- + server: + port: 8000 + --- + spring: + profiles: default + security: + user: + password: weak +---- + +Whereas, in the following example, the password is always set because it is not attached +to any profile, and it would have to be explicitly reset in all other profiles as +necessary: + +[source,yaml,indent=0] +---- + server: + port: 8000 + spring: + security: + user: + password: weak +---- + +Spring profiles designated by using the `spring.profiles` element may optionally be +negated by using the `!` character. If both negated and non-negated profiles are +specified for a single document, at least one non-negated profile must match, and no +negated profiles may match. + + + +[[boot-features-external-config-yaml-shortcomings]] +==== YAML Shortcomings +YAML files cannot be loaded by using the `@PropertySource` annotation. So, in the case +that you need to load values that way, you need to use a properties file. + +Using the multi YAML document syntax in profile-specific YAML files can lead to unexpected +behavior. For example, consider the following config in a file called `application-dev.yml`, +with the `dev` profile being active: + +[source,yaml,indent=0] +---- + server: + port: 8000 + --- + spring: + profiles: !test + security: + user: + password: weak +---- + +In the example above, profile negation and profile expressions will not behave as expected. +We recommend that you don't combine profile-specific YAML files and multiple YAML documents and stick +to using only one of them. + + + +[[boot-features-external-config-typesafe-configuration-properties]] +=== Type-safe Configuration Properties +Using the `@Value("$\{property}")` annotation to inject configuration properties can +sometimes be cumbersome, especially if you are working with multiple properties or your +data is hierarchical in nature. Spring Boot provides an alternative method of working +with properties that lets strongly typed beans govern and validate the configuration of +your application. + +TIP: See also the <>. + + + +[[boot-features-external-config-java-bean-binding]] +==== JavaBean properties binding +It is possible to bind a bean declaring standard JavaBean properties as shown in the +following example: + +[source,java,indent=0] +---- + package com.example; + + import java.net.InetAddress; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import org.springframework.boot.context.properties.ConfigurationProperties; + + @ConfigurationProperties("acme") + public class AcmeProperties { + + private boolean enabled; + + private InetAddress remoteAddress; + + private final Security security = new Security(); + + public boolean isEnabled() { ... } + + public void setEnabled(boolean enabled) { ... } + + public InetAddress getRemoteAddress() { ... } + + public void setRemoteAddress(InetAddress remoteAddress) { ... } + + public Security getSecurity() { ... } + + public static class Security { + + private String username; + + private String password; + + private List roles = new ArrayList<>(Collections.singleton("USER")); + + public String getUsername() { ... } + + public void setUsername(String username) { ... } + + public String getPassword() { ... } + + public void setPassword(String password) { ... } + + public List getRoles() { ... } + + public void setRoles(List roles) { ... } + + } + } +---- + +The preceding POJO defines the following properties: + +* `acme.enabled`, with a value of `false` by default. +* `acme.remote-address`, with a type that can be coerced from `String`. +* `acme.security.username`, with a nested "security" object whose name is determined by +the name of the property. In particular, the return type is not used at all there and +could have been `SecurityProperties`. +* `acme.security.password`. +* `acme.security.roles`, with a collection of `String` that defaults to `USER`. + +[NOTE] +==== +Such arrangement relies on a default empty constructor and getters and setters are usually +mandatory, since binding is through standard Java Beans property descriptors, just like in +Spring MVC. A setter may be omitted in the following cases: + +* Maps, as long as they are initialized, need a getter but not necessarily a setter, +since they can be mutated by the binder. +* Collections and arrays can be accessed either through an index (typically with YAML) or +by using a single comma-separated value (properties). In the latter case, a setter is +mandatory. We recommend to always add a setter for such types. If you initialize a +collection, make sure it is not immutable (as in the preceding example). +* If nested POJO properties are initialized (like the `Security` field in the preceding +example), a setter is not required. If you want the binder to create the instance on the +fly by using its default constructor, you need a setter. + +Some people use Project Lombok to add getters and setters automatically. Make sure that +Lombok does not generate any particular constructor for such a type, as it is used +automatically by the container to instantiate the object. + +Finally, only standard Java Bean properties are considered and binding on static +properties is not supported. +==== + + + +[[boot-features-external-config-constructor-binding]] +==== Constructor binding +The example in the previous section can be rewritten in an immutable fashion as shown in +the following example: + +[source,java,indent=0] +---- + package com.example; + + import java.net.InetAddress; + import java.util.List; + + import org.springframework.boot.context.properties.ConfigurationProperties; + import org.springframework.boot.context.properties.DefaultValue; + + @ConfigurationProperties("acme") + public class AcmeProperties { + + private final boolean enabled; + + private final InetAddress remoteAddress; + + private final Security security; + + public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) { + this.enabled = enabled; + this.remoteAddress = remoteAddress; + this.security = security; + } + + public boolean isEnabled() { ... } + + public InetAddress getRemoteAddress() { ... } + + public Security getSecurity() { ... } + + public static class Security { + + private final String username; + + private final String password; + + private final List roles; + + public Security(String username, String password, + @DefaultValue("USER") List roles) { + this.username = username; + this.password = password; + this.roles = roles; + } + + public String getUsername() { ... } + + public String getPassword() { ... } + + public List getRoles() { ... } + + } + + } +---- + +In this setup one, and only one constructor must be defined with the list of properties +that you wish to bind and not other properties than the ones in the constructor are bound. + +Default values can be specified using `@DefaultValue` and the same conversion service will +be applied to coerce the `String` value to the target type of a missing property. + + + +[[boot-features-external-config-enabling]] +==== Enabling `@ConfigurationProperties`-annotated types +Spring Boot provides an infrastructure to bind such types and register them as beans +automatically. If your application uses `@SpringBootApplication`, classes annotated with +`@ConfigurationProperties` will automatically be scanned and registered as beans. By default, +scanning will occur from the package of the class that declares this annotation. If you want +to define specific packages to scan, you can do so using an explicit `@ConfigurationPropertiesScan` +directive on your `@SpringBootApplication`-annotated class as shown in the following example: + +[source,java,indent=0] +---- + @SpringBootApplication + @ConfigurationPropertiesScan({ "com.example.app", "org.acme.another" }) + public class MyApplication { + } +---- + +Sometimes, classes annotated with `@ConfigurationProperties` might not be suitable +for scanning, for example, if you're developing your own auto-configuration. In these +cases, you can specify the list of types to process on any `@Configuration` class as +shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + @EnableConfigurationProperties(AcmeProperties.class) + public class MyConfiguration { + } +---- + +[NOTE] +==== +When the `@ConfigurationProperties` bean is registered using scanning or via +`@EnableConfigurationProperties`, the bean has a conventional name: `-`, +where `` is the environment key prefix specified in the `@ConfigurationProperties` +annotation and `` is the fully qualified name of the bean. If the annotation does not +provide any prefix, only the fully qualified name of the bean is used. + +The bean name in the example above is `acme-com.example.AcmeProperties`. +==== + +We recommend that `@ConfigurationProperties` only deal with the environment and, in +particular, does not inject other beans from the context. In particular, it is not +possible to inject other beans using the constructor as this would trigger the constructor +binder that only deals with the environment. + +For corner cases, setter injection can be used or any of the `*Aware` interfaces provided +by the framework (such as `EnvironmentAware` if you need access to the `Environment`). + +NOTE: Annotating a `@ConfigurationProperties` type with `@Component` will result in two +beans of the same type if the type is also scanned as part of classpath scanning. If you want +to register the bean yourself using `@Component`, consider disabling scanning of +`@ConfigurationProperties`. + + + +[[boot-features-external-config-using]] +==== Using `@ConfigurationProperties`-annotated types +This style of configuration works particularly well with the `SpringApplication` external +YAML configuration, as shown in the following example: + +[source,yaml,indent=0] +---- + # application.yml + + acme: + remote-address: 192.168.1.1 + security: + username: admin + roles: + - USER + - ADMIN + + # additional configuration as required +---- + +To work with `@ConfigurationProperties` beans, you can inject them in the same way +as any other bean, as shown in the following example: + +[source,java,indent=0] +---- + @Service + public class MyService { + + private final AcmeProperties properties; + + @Autowired + public MyService(AcmeProperties properties) { + this.properties = properties; + } + + //... + + @PostConstruct + public void openConnection() { + Server server = new Server(this.properties.getRemoteAddress()); + // ... + } + + } +---- + +TIP: Using `@ConfigurationProperties` also lets you generate metadata files that can be +used by IDEs to offer auto-completion for your own keys. See the +<> for details. + + + +[[boot-features-external-config-3rd-party-configuration]] +==== Third-party Configuration +As well as using `@ConfigurationProperties` to annotate a class, you can also use it on +public `@Bean` methods. Doing so can be particularly useful when you want to bind +properties to third-party components that are outside of your control. + +To configure a bean from the `Environment` properties, add `@ConfigurationProperties` to +its bean registration, as shown in the following example: + +[source,java,indent=0] +---- + @ConfigurationProperties(prefix = "another") + @Bean + public AnotherComponent anotherComponent() { + ... + } +---- + +Any JavaBean property defined with the `another` prefix is mapped onto that +`AnotherComponent` bean in manner similar to the preceding `AcmeProperties` example. + + + +[[boot-features-external-config-relaxed-binding]] +==== Relaxed Binding +Spring Boot uses some relaxed rules for binding `Environment` properties to +`@ConfigurationProperties` beans, so there does not need to be an exact match between the +`Environment` property name and the bean property name. Common examples where this is +useful include dash-separated environment properties (for example, `context-path` binds +to `contextPath`), and capitalized environment properties (for example, `PORT` binds to +`port`). + +For example, consider the following `@ConfigurationProperties` class: + +[source,java,indent=0] +---- + @ConfigurationProperties(prefix="acme.my-project.person") + public class OwnerProperties { + + private String firstName; + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + } +---- + +In the preceding example, the following properties names can all be used: + +.relaxed binding +[cols="1,4"] +|=== +| Property | Note + +|`acme.my-project.person.first-name` +|Kebab case, which is recommended for use in `.properties` and `.yml` files. + +|`acme.myProject.person.firstName` +|Standard camel case syntax. + +|`acme.my_project.person.first_name` +|Underscore notation, which is an alternative format for use in `.properties` and `.yml` +files. + +|`ACME_MYPROJECT_PERSON_FIRSTNAME` +|Upper case format, which is recommended when using system environment variables. +|=== + +NOTE: The `prefix` value for the annotation _must_ be in kebab case (lowercase and +separated by `-`, such as `acme.my-project.person`). + +.relaxed binding rules per property source +[cols="2,4,4"] +|=== +| Property Source | Simple | List + +|Properties Files +|Camel case, kebab case, or underscore notation +|Standard list syntax using `[ ]` or comma-separated values + +|YAML Files +|Camel case, kebab case, or underscore notation +|Standard YAML list syntax or comma-separated values + +|Environment Variables +|Upper case format with underscore as the delimiter. `_` should not be used within a +property name +|Numeric values surrounded by underscores, such as `MY_ACME_1_OTHER = my.acme[1].other` + +|System properties +|Camel case, kebab case, or underscore notation +|Standard list syntax using `[ ]` or comma-separated values +|=== + +TIP: We recommend that, when possible, properties are stored in lower-case kebab format, +such as `my.property-name=acme`. + +When binding to `Map` properties, if the `key` contains anything other than lowercase +alpha-numeric characters or `-`, you need to use the bracket notation so that the original +value is preserved. If the key is not surrounded by `[]`, any characters that are not alpha-numeric +or `-` are removed. For example, consider binding the following properties to a `Map`: + +[source,yaml,indent=0] +---- + acme: + map: + "[/key1]": value1 + "[/key2]": value2 + /key3: value3 + +---- + +The properties above will bind to a `Map` with `/key1`, `/key2` and `key3` as the keys in the map. + + +[[boot-features-external-config-complex-type-merge]] +==== Merging Complex Types +When lists are configured in more than one place, overriding works by replacing the entire +list. + +For example, assume a `MyPojo` object with `name` and `description` attributes that are +`null` by default. The following example exposes a list of `MyPojo` objects from +`AcmeProperties`: + +[source,java,indent=0] +---- + @ConfigurationProperties("acme") + public class AcmeProperties { + + private final List list = new ArrayList<>(); + + public List getList() { + return this.list; + } + + } +---- + +Consider the following configuration: + +[source,yaml,indent=0] +---- + acme: + list: + - name: my name + description: my description + --- + spring: + profiles: dev + acme: + list: + - name: my another name +---- + +If the `dev` profile is not active, `AcmeProperties.list` contains one `MyPojo` entry, +as previously defined. If the `dev` profile is enabled, however, the `list` _still_ +contains only one entry (with a name of `my another name` and a description of `null`). +This configuration _does not_ add a second `MyPojo` instance to the list, and it does not +merge the items. + +When a `List` is specified in multiple profiles, the one with the highest priority +(and only that one) is used. Consider the following example: + +[source,yaml,indent=0] +---- + acme: + list: + - name: my name + description: my description + - name: another name + description: another description + --- + spring: + profiles: dev + acme: + list: + - name: my another name +---- + +In the preceding example, if the `dev` profile is active, `AcmeProperties.list` contains +_one_ `MyPojo` entry (with a name of `my another name` and a description of `null`). +For YAML, both comma-separated lists and YAML lists can be used for +completely overriding the contents of the list. + +For `Map` properties, you can bind with property values drawn from multiple sources. However, +for the same property in multiple sources, the one with the highest priority is used. +The following example exposes a `Map` from `AcmeProperties`: + +[source,java,indent=0] +---- + @ConfigurationProperties("acme") + public class AcmeProperties { + + private final Map map = new HashMap<>(); + + public Map getMap() { + return this.map; + } + + } +---- + +Consider the following configuration: + +[source,yaml,indent=0] +---- + acme: + map: + key1: + name: my name 1 + description: my description 1 + --- + spring: + profiles: dev + acme: + map: + key1: + name: dev name 1 + key2: + name: dev name 2 + description: dev description 2 +---- + +If the `dev` profile is not active, `AcmeProperties.map` contains one entry with key `key1` +(with a name of `my name 1` and a description of `my description 1`). +If the `dev` profile is enabled, however, `map` contains two entries with keys `key1` +(with a name of `dev name 1` and a description of `my description 1`) and +`key2` (with a name of `dev name 2` and a description of `dev description 2`). + +NOTE: The preceding merging rules apply to properties from all property sources and not just +YAML files. + +[[boot-features-external-config-conversion]] +==== Properties Conversion +Spring Boot attempts to coerce the external application properties to the right type when +it binds to the `@ConfigurationProperties` beans. If you need custom type conversion, you +can provide a `ConversionService` bean (with a bean named `conversionService`) or custom +property editors (through a `CustomEditorConfigurer` bean) or custom `Converters` (with +bean definitions annotated as `@ConfigurationPropertiesBinding`). + +NOTE: As this bean is requested very early during the application lifecycle, make sure to +limit the dependencies that your `ConversionService` is using. Typically, any dependency +that you require may not be fully initialized at creation time. You may want to rename +your custom `ConversionService` if it is not required for configuration keys coercion and +only rely on custom converters qualified with `@ConfigurationPropertiesBinding`. + + + +[[boot-features-external-config-conversion-duration]] +===== Converting durations +Spring Boot has dedicated support for expressing durations. If you expose a +`java.time.Duration` property, the following formats in application properties are +available: + +* A regular `long` representation (using milliseconds as the default unit unless a +`@DurationUnit` has been specified) +* The standard ISO-8601 format +{java-javadoc}/java/time/Duration.html#parse-java.lang.CharSequence-[used by +`java.time.Duration`] +* A more readable format where the value and the unit are coupled (e.g. `10s` means 10 +seconds) + +Consider the following example: + +[source,java,indent=0] +---- +include::{code-examples}/context/properties/bind/AppSystemProperties.java[tag=example] +---- + +To specify a session timeout of 30 seconds, `30`, `PT30S` and `30s` are all equivalent. A +read timeout of 500ms can be specified in any of the following form: `500`, `PT0.5S` and +`500ms`. + +You can also use any of the supported units. These are: + +* `ns` for nanoseconds +* `us` for microseconds +* `ms` for milliseconds +* `s` for seconds +* `m` for minutes +* `h` for hours +* `d` for days + +The default unit is milliseconds and can be overridden using `@DurationUnit` as illustrated +in the sample above. + +TIP: If you are upgrading from a previous version that is simply using `Long` to express +the duration, make sure to define the unit (using `@DurationUnit`) if it isn't +milliseconds alongside the switch to `Duration`. Doing so gives a transparent upgrade path +while supporting a much richer format. + + + +[[boot-features-external-config-conversion-datasize]] +===== Converting Data Sizes +Spring Framework has a `DataSize` value type that allows to express size in bytes. If you +expose a `DataSize` property, the following formats in application properties are +available: + +* A regular `long` representation (using bytes as the default unit unless a +`@DataSizeUnit` has been specified) +* A more readable format where the value and the unit are coupled (e.g. `10MB` means 10 +megabytes) + +Consider the following example: + +[source,java,indent=0] +---- +include::{code-examples}/context/properties/bind/AppIoProperties.java[tag=example] +---- + +To specify a buffer size of 10 megabytes, `10` and `10MB` are equivalent. A size threshold +of 256 bytes can be specified as `256` or `256B`. + +You can also use any of the supported units. These are: + +* `B` for bytes +* `KB` for kilobytes +* `MB` for megabytes +* `GB` for gigabytes +* `TB` for terabytes + +The default unit is bytes and can be overridden using `@DataSizeUnit` as illustrated +in the sample above. + +TIP: If you are upgrading from a previous version that is simply using `Long` to express +the size, make sure to define the unit (using `@DataSizeUnit`) if it isn't bytes alongside +the switch to `DataSize`. Doing so gives a transparent upgrade path while supporting a +much richer format. + + + +[[boot-features-external-config-validation]] +==== @ConfigurationProperties Validation +Spring Boot attempts to validate `@ConfigurationProperties` classes whenever they are +annotated with Spring's `@Validated` annotation. You can use JSR-303 `javax.validation` +constraint annotations directly on your configuration class. To do so, ensure that a +compliant JSR-303 implementation is on your classpath and then add constraint annotations +to your fields, as shown in the following example: + +[source,java,indent=0] +---- + @ConfigurationProperties(prefix="acme") + @Validated + public class AcmeProperties { + + @NotNull + private InetAddress remoteAddress; + + // ... getters and setters + + } +---- + +TIP: You can also trigger validation by annotating the `@Bean` method that creates the +configuration properties with `@Validated`. + +Although nested properties will also be validated when bound, it's good practice to +also annotate the associated field as `@Valid`. This ensure that validation is triggered +even if no nested properties are found. The following example builds on the preceding +`AcmeProperties` example: + +[source,java,indent=0] +---- + @ConfigurationProperties(prefix="acme") + @Validated + public class AcmeProperties { + + @NotNull + private InetAddress remoteAddress; + + @Valid + private final Security security = new Security(); + + // ... getters and setters + + public static class Security { + + @NotEmpty + public String username; + + // ... getters and setters + + } + + } +---- + +You can also add a custom Spring `Validator` by creating a bean definition called +`configurationPropertiesValidator`. The `@Bean` method should be declared `static`. The +configuration properties validator is created very early in the application's lifecycle, +and declaring the `@Bean` method as static lets the bean be created without having to +instantiate the `@Configuration` class. Doing so avoids any problems that may be caused +by early instantiation. + +TIP: The `spring-boot-actuator` module includes an endpoint that exposes all +`@ConfigurationProperties` beans. Point your web browser to +`/actuator/configprops` or use the equivalent JMX endpoint. See the +"<>" +section for details. + + + +[[boot-features-external-config-vs-value]] +==== @ConfigurationProperties vs. @Value +The `@Value` annotation is a core container feature, and it does not provide the same +features as type-safe configuration properties. The following table summarizes the +features that are supported by `@ConfigurationProperties` and `@Value`: + +[cols="4,2,2"] +|=== +|Feature |`@ConfigurationProperties` |`@Value` + +| <> +| Yes +| No + +| <> +| Yes +| No + +| `SpEL` evaluation +| No +| Yes +|=== + +If you define a set of configuration keys for your own components, we recommend you +group them in a POJO annotated with `@ConfigurationProperties`. You should also be aware +that, since `@Value` does not support relaxed binding, it is not a good candidate if you +need to provide the value by using environment variables. + +Finally, while you can write a `SpEL` expression in `@Value`, such expressions are not +processed from <>. + + + +[[boot-features-profiles]] +== Profiles +Spring Profiles provide a way to segregate parts of your application configuration and +make it be available only in certain environments. Any `@Component`, `@Configuration` +or `@ConfigurationProperties` can be marked with `@Profile` to limit when it is loaded, +as shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + @Profile("production") + public class ProductionConfiguration { + + // ... + + } +---- + +NOTE: If `@ConfigurationProperties` beans are registered via `@EnableConfigurationProperties` +instead of automatic scanning, the `@Profile` annotation needs to be specified on the `@Configuration` +class that has the `@EnableConfigurationProperties` annotation. In the case where `@ConfigurationProperties` +are scanned, `@Profile` can be specified on the `@ConfigurationProperties` class itself. + +You can use a `spring.profiles.active` `Environment` property to specify which profiles +are active. You can specify the property in any of the ways described earlier in this +chapter. For example, you could include it in your `application.properties`, as shown in +the following example: + +[source,properties,indent=0] +---- + spring.profiles.active=dev,hsqldb +---- + +You could also specify it on the command line by using the following switch: +`--spring.profiles.active=dev,hsqldb`. + + + +[[boot-features-adding-active-profiles]] +=== Adding Active Profiles +The `spring.profiles.active` property follows the same ordering rules as other +properties: The highest `PropertySource` wins. This means that you can specify active +profiles in `application.properties` and then *replace* them by using the command line +switch. + +Sometimes, it is useful to have profile-specific properties that *add* to the active +profiles rather than replace them. The `spring.profiles.include` property can be used to +unconditionally add active profiles. The `SpringApplication` entry point also has a Java +API for setting additional profiles (that is, on top of those activated by the +`spring.profiles.active` property). See the `setAdditionalProfiles()` method in +{dc-spring-boot}/SpringApplication.html[SpringApplication]. + +For example, when an application with the following properties is run by using the +switch, `--spring.profiles.active=prod`, the `proddb` and `prodmq` profiles are also +activated: + +[source,yaml,indent=0] +---- + --- + my.property: fromyamlfile + --- + spring.profiles: prod + spring.profiles.include: + - proddb + - prodmq +---- + +NOTE: Remember that the `spring.profiles` property can be defined in a YAML document to +determine when this particular document is included in the configuration. See +<> for more details. + + + +[[boot-features-programmatically-setting-profiles]] +=== Programmatically Setting Profiles +You can programmatically set active profiles by calling +`SpringApplication.setAdditionalProfiles(...)` before your application runs. It is also +possible to activate profiles by using Spring's `ConfigurableEnvironment` interface. + + + +[[boot-features-profile-specific-configuration]] +=== Profile-specific Configuration Files +Profile-specific variants of both `application.properties` (or `application.yml`) and +files referenced through `@ConfigurationProperties` are considered as files and loaded. +See "<>" for details. + + + +[[boot-features-logging]] +== Logging +Spring Boot uses https://commons.apache.org/logging[Commons Logging] for all internal +logging but leaves the underlying log implementation open. Default configurations are +provided for +{java-javadoc}/java/util/logging/package-summary.html[Java Util +Logging], https://logging.apache.org/log4j/2.x/[Log4J2], and +https://logback.qos.ch/[Logback]. In each case, loggers are pre-configured to use console +output with optional file output also available. + +By default, if you use the "`Starters`", Logback is used for logging. Appropriate Logback +routing is also included to ensure that dependent libraries that use Java Util Logging, +Commons Logging, Log4J, or SLF4J all work correctly. + +TIP: There are a lot of logging frameworks available for Java. Do not worry if the above +list seems confusing. Generally, you do not need to change your logging dependencies and +the Spring Boot defaults work just fine. + + + +[[boot-features-logging-format]] +=== Log Format +The default log output from Spring Boot resembles the following example: + +[indent=0] +---- +2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52 +2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms +2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] +2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] +---- + +The following items are output: + +* Date and Time: Millisecond precision and easily sortable. +* Log Level: `ERROR`, `WARN`, `INFO`, `DEBUG`, or `TRACE`. +* Process ID. +* A `---` separator to distinguish the start of actual log messages. +* Thread name: Enclosed in square brackets (may be truncated for console output). +* Logger name: This is usually the source class name (often abbreviated). +* The log message. + +NOTE: Logback does not have a `FATAL` level. It is mapped to `ERROR`. + + +[[boot-features-logging-console-output]] +=== Console Output +The default log configuration echoes messages to the console as they are written. By +default, `ERROR`-level, `WARN`-level, and `INFO`-level messages are logged. You can also +enable a "`debug`" mode by starting your application with a `--debug` flag. + +[indent=0] +---- + $ java -jar myapp.jar --debug +---- + +NOTE: You can also specify `debug=true` in your `application.properties`. + +When the debug mode is enabled, a selection of core loggers (embedded container, +Hibernate, and Spring Boot) are configured to output more information. Enabling the debug +mode does _not_ configure your application to log all messages with `DEBUG` level. + +Alternatively, you can enable a "`trace`" mode by starting your application with a +`--trace` flag (or `trace=true` in your `application.properties`). Doing so enables trace +logging for a selection of core loggers (embedded container, Hibernate schema generation, +and the whole Spring portfolio). + +[[boot-features-logging-color-coded-output]] +==== Color-coded Output +If your terminal supports ANSI, color output is used to aid readability. You can set +`spring.output.ansi.enabled` to a +{dc-spring-boot}/ansi/AnsiOutput.Enabled.{dc-ext}[supported value] to override the auto +detection. + +Color coding is configured by using the `%clr` conversion word. In its simplest form, the +converter colors the output according to the log level, as shown in the following +example: + +[source,indent=0] +---- +%clr(%5p) +---- + +The following table describes the mapping of log levels to colors: + +|=== +|Level | Color + +|`FATAL` +| Red + +|`ERROR` +| Red + +|`WARN` +| Yellow + +|`INFO` +| Green + +|`DEBUG` +| Green + +|`TRACE` +| Green +|=== + +Alternatively, you can specify the color or style that should be used by providing it as +an option to the conversion. For example, to make the text yellow, use the following +setting: + +[source,indent=0] +---- +%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow} +---- + +The following colors and styles are supported: + +* `blue` +* `cyan` +* `faint` +* `green` +* `magenta` +* `red` +* `yellow` + +[[boot-features-logging-file-output]] +=== File Output +By default, Spring Boot logs only to the console and does not write log files. If you +want to write log files in addition to the console output, you need to set a +`logging.file.name` or `logging.file.path` property (for example, in your +`application.properties`). + +The following table shows how the `logging.*` properties can be used together: + +.Logging properties +[cols="1,1,1,4"] +|=== +|`logging.file.name` |`logging.file.path` |Example |Description + +|_(none)_ +|_(none)_ +| +|Console only logging. + +|Specific file +|_(none)_ +|`my.log` +|Writes to the specified log file. Names can be an exact location or relative to the +current directory. + +|_(none)_ +|Specific directory +|`/var/log` +|Writes `spring.log` to the specified directory. Names can be an exact location or +relative to the current directory. +|=== + +Log files rotate when they reach 10 MB and, as with console output, `ERROR`-level, +`WARN`-level, and `INFO`-level messages are logged by default. Size limits can be changed +using the `logging.file.max-size` property. Previously rotated files are archived +indefinitely unless the `logging.file.max-history` property has been set. The total size +of log archives can be capped using `logging.file.total-size-cap`. When the total size of +log archives exceeds that threshold, backups will be deleted. To force log archive cleanup +on application startup, use the `logging.file.clean-history-on-start` property. + +NOTE: The logging system is initialized early in the application lifecycle. Consequently, +logging properties are not found in property files loaded through `@PropertySource` +annotations. + +TIP: Logging properties are independent of the actual logging infrastructure. As a +result, specific configuration keys (such as `logback.configurationFile` for Logback) are +not managed by spring Boot. + + +[[boot-features-custom-log-levels]] +=== Log Levels +All the supported logging systems can have the logger levels set in the Spring +`Environment` (for example, in `application.properties`) by using +`+logging.level.=+` where `level` is one of TRACE, DEBUG, INFO, WARN, +ERROR, FATAL, or OFF. The `root` logger can be configured by using `logging.level.root`. + +The following example shows potential logging settings in `application.properties`: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + logging.level.root=WARN + logging.level.org.springframework.web=DEBUG + logging.level.org.hibernate=ERROR +---- + + + +[[boot-features-custom-log-groups]] +=== Log Groups +It's often useful to be able to group related loggers together so that they can all be +configured at the same time. For example, you might commonly change the logging levels for +_all_ Tomcat related loggers, but you can't easily remember top level packages. + +To help with this, Spring Boot allows you to define logging groups in your Spring +`Environment`. For example, here's how you could define a "`tomcat`" group by adding +it to your `application.properties`: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat +---- + +Once defined, you can change the level for all the loggers in the group with a single +line: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + logging.level.tomcat=TRACE +---- + +Spring Boot includes the following pre-defined logging groups that can be used +out-of-the-box: + +[cols="1,4"] +|=== +|Name |Loggers + +|web +|`org.springframework.core.codec`, `org.springframework.http`, `org.springframework.web` + +|sql +|`org.springframework.jdbc.core`, `org.hibernate.SQL`, `org.jooq.tools.LoggerListener` + +|=== + + + +[[boot-features-custom-log-configuration]] +=== Custom Log Configuration +The various logging systems can be activated by including the appropriate libraries on +the classpath and can be further customized by providing a suitable configuration file in +the root of the classpath or in a location specified by the following Spring `Environment` +property: `logging.config`. + +You can force Spring Boot to use a particular logging system by using the +`org.springframework.boot.logging.LoggingSystem` system property. The value should be the +fully qualified class name of a `LoggingSystem` implementation. You can also disable +Spring Boot's logging configuration entirely by using a value of `none`. + +NOTE: Since logging is initialized *before* the `ApplicationContext` is created, it is +not possible to control logging from `@PropertySources` in Spring `@Configuration` files. +The only way to change the logging system or disable it entirely is via System properties. + +Depending on your logging system, the following files are loaded: + +|=== +|Logging System |Customization + +|Logback +|`logback-spring.xml`, `logback-spring.groovy`, `logback.xml`, or `logback.groovy` + +|Log4j2 +|`log4j2-spring.xml` or `log4j2.xml` + +|JDK (Java Util Logging) +|`logging.properties` +|=== + +NOTE: When possible, we recommend that you use the `-spring` variants for your logging +configuration (for example, `logback-spring.xml` rather than `logback.xml`). If you use +standard configuration locations, Spring cannot completely control log initialization. + +WARNING: There are known classloading issues with Java Util Logging that cause problems +when running from an 'executable jar'. We recommend that you avoid it when running from +an 'executable jar' if at all possible. + +To help with the customization, some other properties are transferred from the Spring +`Environment` to System properties, as described in the following table: + +|=== +|Spring Environment |System Property |Comments + +|`logging.exception-conversion-word` +|`LOG_EXCEPTION_CONVERSION_WORD` +|The conversion word used when logging exceptions. + +|`logging.file.clean-history-on-start` +|`LOG_FILE_CLEAN_HISTORY_ON_START` +|Whether to clean the archive log files on startup (if LOG_FILE enabled). (Only supported +with the default Logback setup.) + +|`logging.file.name` +|`LOG_FILE` +|If defined, it is used in the default log configuration. + +|`logging.file.max-size` +|`LOG_FILE_MAX_SIZE` +|Maximum log file size (if LOG_FILE enabled). (Only supported with the default Logback +setup.) + +|`logging.file.max-history` +|`LOG_FILE_MAX_HISTORY` +|Maximum number of archive log files to keep (if LOG_FILE enabled). (Only supported with +the default Logback setup.) + +|`logging.file.path` +|`LOG_PATH` +|If defined, it is used in the default log configuration. + +|`logging.file.total-size-cap` +|`LOG_FILE_TOTAL_SIZE_CAP` +|Total size of log backups to be kept (if LOG_FILE enabled). (Only supported with the +default Logback setup.) + +|`logging.pattern.console` +|`CONSOLE_LOG_PATTERN` +|The log pattern to use on the console (stdout). (Only supported with the default Logback +setup.) + +|`logging.pattern.dateformat` +|`LOG_DATEFORMAT_PATTERN` +|Appender pattern for log date format. (Only supported with the default Logback setup.) + +|`logging.pattern.file` +|`FILE_LOG_PATTERN` +|The log pattern to use in a file (if `LOG_FILE` is enabled). (Only supported with the +default Logback setup.) + +|`logging.pattern.level` +|`LOG_LEVEL_PATTERN` +|The format to use when rendering the log level (default `%5p`). (Only supported with the +default Logback setup.) + +|`PID` +|`PID` +|The current process ID (discovered if possible and when not already defined as an OS +environment variable). +|=== + +All the supported logging systems can consult System properties when parsing their +configuration files. See the default configurations in `spring-boot.jar` for examples: + +* {github-code}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml[Logback] +* {github-code}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml[Log4j 2] +* {github-code}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties[Java Util logging] + +[TIP] +==== +If you want to use a placeholder in a logging property, you should use +<> and not +the syntax of the underlying framework. Notably, if you use Logback, you should use `:` +as the delimiter between a property name and its default value and not use `:-`. +==== + +[TIP] +==== + +You can add MDC and other ad-hoc content to log lines by overriding only the +`LOG_LEVEL_PATTERN` (or `logging.pattern.level` with Logback). For example, if you use +`logging.pattern.level=user:%X\{user} %5p`, then the default log format contains an MDC +entry for "user", if it exists, as shown in the following example. + +---- +2015-09-30 12:30:04.031 user:someone INFO 22174 --- [ nio-8080-exec-0] demo.Controller +Handling authenticated request +---- +==== + + + +[[boot-features-logback-extensions]] +=== Logback Extensions +Spring Boot includes a number of extensions to Logback that can help with advanced +configuration. You can use these extensions in your `logback-spring.xml` configuration +file. + +NOTE: Because the standard `logback.xml` configuration file is loaded too early, you +cannot use extensions in it. You need to either use `logback-spring.xml` or define a +`logging.config` property. + +WARNING: The extensions cannot be used with Logback's +https://logback.qos.ch/manual/configuration.html#autoScan[configuration scanning]. If you +attempt to do so, making changes to the configuration file results in an error similar to +one of the following being logged: + +---- +ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]] +ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]] +---- + + + +==== Profile-specific Configuration +The `` tag lets you optionally include or exclude sections of +configuration based on the active Spring profiles. Profile sections are supported +anywhere within the `` element. Use the `name` attribute to specify which +profile accepts the configuration. The `` tag can contain a simple profile +name (for example `staging`) or a profile expression. A profile expression allows for more +complicated profile logic to be expressed, for example +`production & (eu-central | eu-west)`. Check the +{spring-reference}core.html#beans-definition-profiles-java[reference guide] for more +details. The following listing shows three sample profiles: + +[source,xml,indent=0] +---- + + + + + + + + + + + +---- + + + +==== Environment Properties +The `` tag lets you expose properties from the Spring `Environment` for +use within Logback. Doing so can be useful if you want to access values from your +`application.properties` file in your Logback configuration. The tag works in a similar +way to Logback's standard `` tag. However, rather than specifying a direct +`value`, you specify the `source` of the property (from the `Environment`). If you need +to store the property somewhere other than in `local` scope, you can use the `scope` +attribute. If you need a fallback value (in case the property is not set in the +`Environment`), you can use the `defaultValue` attribute. The following example shows how +to expose properties for use within Logback: + +[source,xml,indent=0] +---- + + + ${fluentHost} + ... + +---- + +NOTE: The `source` must be specified in kebab case (such as `my.property-name`). +However, properties can be added to the `Environment` by using the relaxed rules. + + + +[[boot-features-internationalization]] +== Internationalization +Spring Boot supports localized messages so that your application can cater to users +of different language preferences. By default, Spring Boot looks for the presence of +a `messages` resource bundle at the root of the classpath. + +NOTE: The auto-configuration applies when the default properties file for the configured +resource bundle is available (i.e. `messages.properties` by default). If your resource +bundle contains only language-specific properties files, you are required to add the +default. + +The basename of the resource bundle as well as several other attributes can be configured +using the `spring.messages` namespace, as shown in the following example: + +[source,properties,indent=0] +---- + spring.messages.basename=messages,config.i18n.messages + spring.messages.fallback-to-system-locale=false +---- + +TIP: `spring.messages.basename` supports comma-separated list of locations, either a +package qualifier or a resource resolved from the classpath root. + +See {sc-spring-boot-autoconfigure}/context/MessageSourceProperties.{sc-ext}[ +`MessageSourceProperties`] for more supported options. + + + + +[[boot-features-json]] +== JSON +Spring Boot provides integration with three JSON mapping libraries: + +- Gson +- Jackson +- JSON-B + +Jackson is the preferred and default library. + + + +[[boot-features-json-jackson]] +=== Jackson +Auto-configuration for Jackson is provided and Jackson is part of +`spring-boot-starter-json`. When Jackson is on the classpath an `ObjectMapper` +bean is automatically configured. Several configuration properties are provided for +<>. + + + +[[boot-features-json-gson]] +=== Gson +Auto-configuration for Gson is provided. When Gson is on the classpath a `Gson` bean is +automatically configured. Several `+spring.gson.*+` configuration properties are +provided for customizing the configuration. To take more control, one or more +`GsonBuilderCustomizer` beans can be used. + + + +[[boot-features-json-json-b]] +=== JSON-B +Auto-configuration for JSON-B is provided. When the JSON-B API and an implementation are +on the classpath a `Jsonb` bean will be automatically configured. The preferred JSON-B +implementation is Apache Johnzon for which dependency management is provided. + + + +[[boot-features-developing-web-applications]] +== Developing Web Applications +Spring Boot is well suited for web application development. You can create a +self-contained HTTP server by using embedded Tomcat, Jetty, Undertow, or Netty. Most web +applications use the `spring-boot-starter-web` module to get up and running quickly. You +can also choose to build reactive web applications by using the +`spring-boot-starter-webflux` module. + +If you have not yet developed a Spring Boot web application, you can follow the +"Hello World!" example in the +_<>_ section. + + + +[[boot-features-spring-mvc]] +=== The "`Spring Web MVC Framework`" +The {spring-reference}web.html#mvc[Spring Web MVC framework] (often referred to as simply +"`Spring MVC`") is a rich "`model view controller`" web framework. Spring MVC lets you +create special `@Controller` or `@RestController` beans to handle incoming HTTP requests. +Methods in your controller are mapped to HTTP by using `@RequestMapping` annotations. + +The following code shows a typical `@RestController` that serves JSON data: + +[source,java,indent=0] +---- + @RestController + @RequestMapping(value="/users") + public class MyRestController { + + @RequestMapping(value="/\{user}", method=RequestMethod.GET) + public User getUser(@PathVariable Long user) { + // ... + } + + @RequestMapping(value="/\{user}/customers", method=RequestMethod.GET) + List getUserCustomers(@PathVariable Long user) { + // ... + } + + @RequestMapping(value="/\{user}", method=RequestMethod.DELETE) + public User deleteUser(@PathVariable Long user) { + // ... + } + + } +---- + +Spring MVC is part of the core Spring Framework, and detailed information is available in +the {spring-reference}web.html#mvc[reference documentation]. There are also several +guides that cover Spring MVC available at https://spring.io/guides. + + + +[[boot-features-spring-mvc-auto-configuration]] +==== Spring MVC Auto-configuration +Spring Boot provides auto-configuration for Spring MVC that works well with most +applications. + +The auto-configuration adds the following features on top of Spring's defaults: + +* Inclusion of `ContentNegotiatingViewResolver` and `BeanNameViewResolver` beans. +* Support for serving static resources, including support for WebJars (covered +<>)). +* Automatic registration of `Converter`, `GenericConverter`, and `Formatter` beans. +* Support for `HttpMessageConverters` (covered +<>). +* Automatic registration of `MessageCodesResolver` (covered +<>). +* Static `index.html` support. +* Custom `Favicon` support (covered <>). +* Automatic use of a `ConfigurableWebBindingInitializer` bean (covered +<>). + +If you want to keep Spring Boot MVC features and you want to add additional +{spring-reference}web.html#mvc[MVC configuration] (interceptors, formatters, view +controllers, and other features), you can add your own `@Configuration` class of type +`WebMvcConfigurer` but *without* `@EnableWebMvc`. If you wish to provide custom +instances of `RequestMappingHandlerMapping`, `RequestMappingHandlerAdapter`, or +`ExceptionHandlerExceptionResolver`, you can declare a `WebMvcRegistrationsAdapter` +instance to provide such components. + +If you want to take complete control of Spring MVC, you can add your own `@Configuration` +annotated with `@EnableWebMvc`. + + +[[boot-features-spring-mvc-message-converters]] +==== HttpMessageConverters +Spring MVC uses the `HttpMessageConverter` interface to convert HTTP requests and +responses. Sensible defaults are included out of the box. For example, objects can be +automatically converted to JSON (by using the Jackson library) or XML (by using the +Jackson XML extension, if available, or by using JAXB if the Jackson XML extension is not +available). By default, strings are encoded in `UTF-8`. + +If you need to add or customize converters, you can use Spring Boot's +`HttpMessageConverters` class, as shown in the following listing: + +[source,java,indent=0] +---- + import org.springframework.boot.autoconfigure.http.HttpMessageConverters; + import org.springframework.context.annotation.*; + import org.springframework.http.converter.*; + + @Configuration(proxyBeanMethods = false) + public class MyConfiguration { + + @Bean + public HttpMessageConverters customConverters() { + HttpMessageConverter additional = ... + HttpMessageConverter another = ... + return new HttpMessageConverters(additional, another); + } + + } +---- + +Any `HttpMessageConverter` bean that is present in the context is added to the list of +converters. You can also override default converters in the same way. + + + +[[boot-features-json-components]] +==== Custom JSON Serializers and Deserializers +If you use Jackson to serialize and deserialize JSON data, you might want to write your +own `JsonSerializer` and `JsonDeserializer` classes. Custom serializers are usually +https://github.com/FasterXML/jackson-docs/wiki/JacksonHowToCustomSerializers[registered with Jackson through +a module], but Spring Boot provides an alternative `@JsonComponent` annotation that makes +it easier to directly register Spring Beans. + +You can use the `@JsonComponent` annotation directly on `JsonSerializer`, +`JsonDeserializer` or `KeyDeserializer` implementations. You can also use it on classes +that contain serializers/deserializers as inner classes, as shown in the following example: + +[source,java,indent=0] +---- + import java.io.*; + import com.fasterxml.jackson.core.*; + import com.fasterxml.jackson.databind.*; + import org.springframework.boot.jackson.*; + + @JsonComponent + public class Example { + + public static class Serializer extends JsonSerializer { + // ... + } + + public static class Deserializer extends JsonDeserializer { + // ... + } + + } +---- + +All `@JsonComponent` beans in the `ApplicationContext` are automatically registered with +Jackson. Because `@JsonComponent` is meta-annotated with `@Component`, the usual +component-scanning rules apply. + +Spring Boot also provides +{sc-spring-boot}/jackson/JsonObjectSerializer.{sc-ext}[`JsonObjectSerializer`] and +{sc-spring-boot}/jackson/JsonObjectDeserializer.{sc-ext}[`JsonObjectDeserializer`] base +classes that provide useful alternatives to the standard Jackson versions when +serializing objects. See +{dc-spring-boot}/jackson/JsonObjectSerializer.{dc-ext}[`JsonObjectSerializer`] +and {dc-spring-boot}/jackson/JsonObjectDeserializer.{dc-ext}[`JsonObjectDeserializer`] in +the Javadoc for details. + + + +[[boot-features-spring-message-codes]] +==== MessageCodesResolver +Spring MVC has a strategy for generating error codes for rendering error messages from +binding errors: `MessageCodesResolver`. If you set the +`spring.mvc.message-codes-resolver.format` property `PREFIX_ERROR_CODE` or +`POSTFIX_ERROR_CODE`, Spring Boot creates one for you (see the enumeration in +{spring-javadoc}/validation/DefaultMessageCodesResolver.Format.{dc-ext}[`DefaultMessageCodesResolver.Format`]). + + + +[[boot-features-spring-mvc-static-content]] +==== Static Content +By default, Spring Boot serves static content from a directory called `/static` (or +`/public` or `/resources` or `/META-INF/resources`) in the classpath or from the root of +the `ServletContext`. It uses the `ResourceHttpRequestHandler` from Spring MVC so that +you can modify that behavior by adding your own `WebMvcConfigurer` and overriding the +`addResourceHandlers` method. + +In a stand-alone web application, the default servlet from the container is also enabled +and acts as a fallback, serving content from the root of the `ServletContext` if Spring +decides not to handle it. Most of the time, this does not happen (unless you modify the +default MVC configuration), because Spring can always handle requests through the +`DispatcherServlet`. + +By default, resources are mapped on `+/**+`, but you can tune that with the +`spring.mvc.static-path-pattern` property. For instance, relocating all resources to +`/resources/**` can be achieved as follows: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.mvc.static-path-pattern=/resources/** +---- + +You can also customize the static resource locations by using the +`spring.resources.static-locations` property (replacing the default values with a list of +directory locations). The root Servlet context path, `"/"`, is automatically added as a +location as well. + +In addition to the "`standard`" static resource locations mentioned earlier, a special +case is made for https://www.webjars.org/[Webjars content]. Any resources with a path in +`+/webjars/**+` are served from jar files if they are packaged in the Webjars format. + +TIP: Do not use the `src/main/webapp` directory if your application is packaged as a jar. +Although this directory is a common standard, it works *only* with war packaging, and it +is silently ignored by most build tools if you generate a jar. + +Spring Boot also supports the advanced resource handling features provided by Spring MVC, +allowing use cases such as cache-busting static resources or using version agnostic URLs +for Webjars. + +To use version agnostic URLs for Webjars, add the `webjars-locator-core` dependency. +Then declare your Webjar. Using jQuery as an example, adding +`"/webjars/jquery/jquery.min.js"` results in +`"/webjars/jquery/x.y.z/jquery.min.js"`. where `x.y.z` is the Webjar version. + +NOTE: If you use JBoss, you need to declare the `webjars-locator-jboss-vfs` +dependency instead of the `webjars-locator-core`. Otherwise, all Webjars resolve as a +`404`. + +To use cache busting, the following configuration configures a cache busting solution for +all static resources, effectively adding a content hash, such as +``, in URLs: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.resources.chain.strategy.content.enabled=true + spring.resources.chain.strategy.content.paths=/** +---- + +NOTE: Links to resources are rewritten in templates at runtime, thanks to a +`ResourceUrlEncodingFilter` that is auto-configured for Thymeleaf and FreeMarker. You +should manually declare this filter when using JSPs. Other template engines are currently +not automatically supported but can be with custom template macros/helpers and the use of +the +{spring-javadoc}/web/servlet/resource/ResourceUrlProvider.{dc-ext}[`ResourceUrlProvider`]. + +When loading resources dynamically with, for example, a JavaScript module loader, +renaming files is not an option. That is why other strategies are also supported and can +be combined. A "fixed" strategy adds a static version string in the URL without changing +the file name, as shown in the following example: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.resources.chain.strategy.content.enabled=true + spring.resources.chain.strategy.content.paths=/** + spring.resources.chain.strategy.fixed.enabled=true + spring.resources.chain.strategy.fixed.paths=/js/lib/ + spring.resources.chain.strategy.fixed.version=v12 +---- + +With this configuration, JavaScript modules located under `"/js/lib/"` use a fixed +versioning strategy (`"/v12/js/lib/mymodule.js"`), while other resources still use the +content one (``). + +See {sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[`ResourceProperties`] +for more supported options. + +[TIP] +==== +This feature has been thoroughly described in a dedicated +https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources[blog +post] and in Spring Framework's +{spring-reference}web.html#mvc-config-static-resources[reference documentation]. +==== + +[[boot-features-spring-mvc-welcome-page]] +==== Welcome Page +Spring Boot supports both static and templated welcome pages. It first looks for an +`index.html` file in the configured static content locations. If one is not found, it +then looks for an `index` template. If either is found, it is automatically used as the +welcome page of the application. + + + +[[boot-features-spring-mvc-favicon]] +==== Custom Favicon +Spring Boot looks for a `favicon.ico` in the configured static content locations and the +root of the classpath (in that order). If such a file is present, it is automatically +used as the favicon of the application. + + +[[boot-features-spring-mvc-pathmatch]] +==== Path Matching and Content Negotiation +Spring MVC can map incoming HTTP requests to handlers by looking at the request path and +matching it to the mappings defined in your application (for example, `@GetMapping` +annotations on Controller methods). + +Spring Boot chooses to disable suffix pattern matching by default, which means that +requests like `"GET /projects/spring-boot.json"` won't be matched to +`@GetMapping("/projects/spring-boot")` mappings. +This is considered as a +{spring-reference}web.html#mvc-ann-requestmapping-suffix-pattern-match[best practice +for Spring MVC applications]. This feature was mainly useful in the past for HTTP +clients which did not send proper "Accept" request headers; we needed to make sure +to send the correct Content Type to the client. Nowadays, Content Negotiation +is much more reliable. + +There are other ways to deal with HTTP clients that don't consistently send proper +"Accept" request headers. Instead of using suffix matching, we can use a query +parameter to ensure that requests like `"GET /projects/spring-boot?format=json"` +will be mapped to `@GetMapping("/projects/spring-boot")`: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.mvc.contentnegotiation.favor-parameter=true + + # We can change the parameter name, which is "format" by default: + # spring.mvc.contentnegotiation.parameter-name=myparam + + # We can also register additional file extensions/media types with: + spring.mvc.contentnegotiation.media-types.markdown=text/markdown +---- + +If you understand the caveats and would still like your application to use +suffix pattern matching, the following configuration is required: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.mvc.contentnegotiation.favor-path-extension=true + spring.mvc.pathmatch.use-suffix-pattern=true +---- + +Alternatively, rather than open all suffix patterns, it's more secure to just support +registered suffix patterns: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.mvc.contentnegotiation.favor-path-extension=true + spring.mvc.pathmatch.use-registered-suffix-pattern=true + + # You can also register additional file extensions/media types with: + # spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc +---- + + + +[[boot-features-spring-mvc-web-binding-initializer]] +==== ConfigurableWebBindingInitializer +Spring MVC uses a `WebBindingInitializer` to initialize a `WebDataBinder` for a +particular request. If you create your own `ConfigurableWebBindingInitializer` `@Bean`, +Spring Boot automatically configures Spring MVC to use it. + + + +[[boot-features-spring-mvc-template-engines]] +==== Template Engines +As well as REST web services, you can also use Spring MVC to serve dynamic HTML content. +Spring MVC supports a variety of templating technologies, including Thymeleaf, +FreeMarker, and JSPs. Also, many other templating engines include their own Spring MVC +integrations. + +Spring Boot includes auto-configuration support for the following templating engines: + + * https://freemarker.apache.org/docs/[FreeMarker] + * http://docs.groovy-lang.org/docs/next/html/documentation/template-engines.html#_the_markuptemplateengine[Groovy] + * https://www.thymeleaf.org[Thymeleaf] + * https://mustache.github.io/[Mustache] + +TIP: If possible, JSPs should be avoided. There are several +<> when using them with embedded +servlet containers. + +When you use one of these templating engines with the default configuration, your +templates are picked up automatically from `src/main/resources/templates`. + +TIP: Depending on how you run your application, IntelliJ IDEA orders the classpath +differently. Running your application in the IDE from its main method results in a +different ordering than when you run your application by using Maven or Gradle or from +its packaged jar. This can cause Spring Boot to fail to find the templates on the +classpath. If you have this problem, you can reorder the classpath in the IDE to place +the module's classes and resources first. Alternatively, you can configure the template +prefix to search every `templates` directory on the classpath, as follows: +`classpath*:/templates/`. + + + +[[boot-features-error-handling]] +==== Error Handling +By default, Spring Boot provides an `/error` mapping that handles all errors in a +sensible way, and it is registered as a "`global`" error page in the servlet container. +For machine clients, it produces a JSON response with details of the error, the HTTP +status, and the exception message. For browser clients, there is a "`whitelabel`" error +view that renders the same data in HTML format (to customize it, add a `View` that +resolves to `error`). To replace the default behavior completely, you can implement +`ErrorController` and register a bean definition of that type or add a bean of type +`ErrorAttributes` to use the existing mechanism but replace the contents. + +TIP: The `BasicErrorController` can be used as a base class for a custom +`ErrorController`. This is particularly useful if you want to add a handler for a new +content type (the default is to handle `text/html` specifically and provide a fallback +for everything else). To do so, extend `BasicErrorController`, add a public method with a +`@RequestMapping` that has a `produces` attribute, and create a bean of your new type. + +You can also define a class annotated with `@ControllerAdvice` to customize the JSON +document to return for a particular controller and/or exception type, as shown in the +following example: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + @ControllerAdvice(basePackageClasses = AcmeController.class) + public class AcmeControllerAdvice extends ResponseEntityExceptionHandler { + + @ExceptionHandler(YourException.class) + @ResponseBody + ResponseEntity handleControllerException(HttpServletRequest request, Throwable ex) { + HttpStatus status = getStatus(request); + return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status); + } + + private HttpStatus getStatus(HttpServletRequest request) { + Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); + if (statusCode == null) { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + return HttpStatus.valueOf(statusCode); + } + + } +---- + +In the preceding example, if `YourException` is thrown by a controller defined in the +same package as `AcmeController`, a JSON representation of the `CustomErrorType` POJO is +used instead of the `ErrorAttributes` representation. + + + +[[boot-features-error-handling-custom-error-pages]] +===== Custom Error Pages +If you want to display a custom HTML error page for a given status code, you can add a +file to an `/error` folder. Error pages can either be static HTML (that is, added under +any of the static resource folders) or be built by using templates. The name of the file +should be the exact status code or a series mask. + +For example, to map `404` to a static HTML file, your folder structure would be as +follows: + +[source,indent=0,subs="verbatim,quotes,attributes"] +---- + src/ + +- main/ + +- java/ + | + + +- resources/ + +- public/ + +- error/ + | +- 404.html + +- +---- + +To map all `5xx` errors by using a FreeMarker template, your folder structure would be as +follows: + +[source,indent=0,subs="verbatim,quotes,attributes"] +---- + src/ + +- main/ + +- java/ + | + + +- resources/ + +- templates/ + +- error/ + | +- 5xx.ftlh + +- +---- + +For more complex mappings, you can also add beans that implement the `ErrorViewResolver` +interface, as shown in the following example: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + public class MyErrorViewResolver implements ErrorViewResolver { + + @Override + public ModelAndView resolveErrorView(HttpServletRequest request, + HttpStatus status, Map model) { + // Use the request or status to optionally return a ModelAndView + return ... + } + + } +---- + + +You can also use regular Spring MVC features such as +{spring-reference}web.html#mvc-exceptionhandlers[`@ExceptionHandler` methods] and +{spring-reference}web.html#mvc-ann-controller-advice[`@ControllerAdvice`]. The +`ErrorController` then picks up any unhandled exceptions. + + + +[[boot-features-error-handling-mapping-error-pages-without-mvc]] +===== Mapping Error Pages outside of Spring MVC +For applications that do not use Spring MVC, you can use the `ErrorPageRegistrar` +interface to directly register `ErrorPages`. This abstraction works directly with the +underlying embedded servlet container and works even if you do not have a Spring MVC +`DispatcherServlet`. + + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + @Bean + public ErrorPageRegistrar errorPageRegistrar(){ + return new MyErrorPageRegistrar(); + } + + // ... + + private static class MyErrorPageRegistrar implements ErrorPageRegistrar { + + @Override + public void registerErrorPages(ErrorPageRegistry registry) { + registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400")); + } + + } +---- + +NOTE: If you register an `ErrorPage` with a path that ends up being handled by a `Filter` +(as is common with some non-Spring web frameworks, like Jersey and Wicket), then the +`Filter` has to be explicitly registered as an `ERROR` dispatcher, as shown in the +following example: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + @Bean + public FilterRegistrationBean myFilter() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new MyFilter()); + ... + registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); + return registration; + } +---- + +Note that the default `FilterRegistrationBean` does not include the `ERROR` dispatcher +type. + + + +[[boot-features-error-handling-websphere]] +CAUTION:When deployed to a servlet container, Spring Boot uses its error page filter to +forward a request with an error status to the appropriate error page. The request can only +be forwarded to the correct error page if the response has not already been committed. By +default, WebSphere Application Server 8.0 and later commits the response upon successful +completion of a servlet's service method. You should disable this behavior by setting +`com.ibm.ws.webcontainer.invokeFlushAfterService` to `false`. + + + +[[boot-features-spring-hateoas]] +==== Spring HATEOAS +If you develop a RESTful API that makes use of hypermedia, Spring Boot provides +auto-configuration for Spring HATEOAS that works well with most applications. The +auto-configuration replaces the need to use `@EnableHypermediaSupport` and registers a +number of beans to ease building hypermedia-based applications, including a +`LinkDiscoverers` (for client side support) and an `ObjectMapper` configured to correctly +marshal responses into the desired representation. The `ObjectMapper` is customized by +setting the various `spring.jackson.*` properties or, if one exists, by a +`Jackson2ObjectMapperBuilder` bean. + +You can take control of Spring HATEOAS's configuration by using +`@EnableHypermediaSupport`. Note that doing so disables the `ObjectMapper` customization +described earlier. + + + +[[boot-features-cors]] +==== CORS Support + +https://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross-origin resource sharing] +(CORS) is a https://www.w3.org/TR/cors/[W3C specification] implemented by +https://caniuse.com/#feat=cors[most browsers] that lets you specify in a flexible +way what kind of cross-domain requests are authorized, instead of using some less secure +and less powerful approaches such as IFRAME or JSONP. + +As of version 4.2, Spring MVC {spring-reference}web.html#cors[supports CORS]. +Using {spring-reference}web.html#controller-method-cors-configuration[controller method +CORS configuration] with +{spring-javadoc}/web/bind/annotation/CrossOrigin.{dc-ext}[`@CrossOrigin`] +annotations in your Spring Boot application does not require any specific configuration. +{spring-reference}web.html#global-cors-configuration[Global CORS configuration] can be +defined by registering a `WebMvcConfigurer` bean with a customized +`addCorsMappings(CorsRegistry)` method, as shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + public class MyConfiguration { + + @Bean + public WebMvcConfigurer corsConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/api/**"); + } + }; + } + } +---- + + + +[[boot-features-webflux]] +=== The "`Spring WebFlux Framework`" + +Spring WebFlux is the new reactive web framework introduced in Spring Framework 5.0. +Unlike Spring MVC, it does not require the Servlet API, is fully asynchronous and +non-blocking, and implements the https://www.reactive-streams.org/[Reactive Streams] +specification through https://projectreactor.io/[the Reactor project]. + +Spring WebFlux comes in two flavors: functional and annotation-based. The +annotation-based one is quite close to the Spring MVC model, as shown in the +following example: + +[source,java,indent=0] +---- + @RestController + @RequestMapping("/users") + public class MyRestController { + + @GetMapping("/\{user}") + public Mono getUser(@PathVariable Long user) { + // ... + } + + @GetMapping("/\{user}/customers") + public Flux getUserCustomers(@PathVariable Long user) { + // ... + } + + @DeleteMapping("/\{user}") + public Mono deleteUser(@PathVariable Long user) { + // ... + } + + } +---- + +"`WebFlux.fn`", the functional variant, separates the routing configuration from the +actual handling of the requests, as shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + public class RoutingConfiguration { + + @Bean + public RouterFunction monoRouterFunction(UserHandler userHandler) { + return route(GET("/\{user}").and(accept(APPLICATION_JSON)), userHandler::getUser) + .andRoute(GET("/\{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers) + .andRoute(DELETE("/\{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser); + } + + } + + @Component + public class UserHandler { + + public Mono getUser(ServerRequest request) { + // ... + } + + public Mono getUserCustomers(ServerRequest request) { + // ... + } + + public Mono deleteUser(ServerRequest request) { + // ... + } + } +---- + +WebFlux is part of the Spring Framework and detailed information is available in its +{spring-reference}web-reactive.html#webflux-fn[reference documentation]. + +TIP: You can define as many `RouterFunction` beans as you like to modularize the +definition of the router. Beans can be ordered if you need to apply a precedence. + +To get started, add the `spring-boot-starter-webflux` module to your application. + +NOTE: Adding both `spring-boot-starter-web` and `spring-boot-starter-webflux` modules in +your application results in Spring Boot auto-configuring Spring MVC, not WebFlux. This +behavior has been chosen because many Spring developers add `spring-boot-starter-webflux` +to their Spring MVC application to use the reactive `WebClient`. You can still enforce +your choice by setting the chosen application type to +`SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)`. + + + +[[boot-features-webflux-auto-configuration]] +==== Spring WebFlux Auto-configuration +Spring Boot provides auto-configuration for Spring WebFlux that works well with most +applications. + +The auto-configuration adds the following features on top of Spring's defaults: + +* Configuring codecs for `HttpMessageReader` and `HttpMessageWriter` instances (described +<>). +* Support for serving static resources, including support for WebJars (described +<>). + +If you want to keep Spring Boot WebFlux features and you want to add additional +{spring-reference}web.html#web-reactive[WebFlux configuration], you can add your own +`@Configuration` class of type `WebFluxConfigurer` but *without* `@EnableWebFlux`. + +If you want to take complete control of Spring WebFlux, you can add your own +`@Configuration` annotated with `@EnableWebFlux`. + + + +[[boot-features-webflux-httpcodecs]] +==== HTTP Codecs with HttpMessageReaders and HttpMessageWriters +Spring WebFlux uses the `HttpMessageReader` and `HttpMessageWriter` interfaces to convert +HTTP requests and responses. They are configured with `CodecConfigurer` to have sensible +defaults by looking at the libraries available in your classpath. + +Spring Boot applies further customization by using `CodecCustomizer` instances. For +example, `spring.jackson.*` configuration keys are applied to the Jackson codec. + +If you need to add or customize codecs, you can create a custom `CodecCustomizer` +component, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.boot.web.codec.CodecCustomizer; + + @Configuration(proxyBeanMethods = false) + public class MyConfiguration { + + @Bean + public CodecCustomizer myCodecCustomizer() { + return codecConfigurer -> { + // ... + } + } + + } +---- + +You can also leverage <>. + + + +[[boot-features-webflux-static-content]] +==== Static Content +By default, Spring Boot serves static content from a directory called `/static` (or +`/public` or `/resources` or `/META-INF/resources`) in the classpath. It uses the +`ResourceWebHandler` from Spring WebFlux so that you can modify that behavior by adding +your own `WebFluxConfigurer` and overriding the `addResourceHandlers` method. + +By default, resources are mapped on `+/**+`, but you can tune that by setting the +`spring.webflux.static-path-pattern` property. For instance, relocating all resources to +`/resources/**` can be achieved as follows: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.webflux.static-path-pattern=/resources/** +---- + +You can also customize the static resource locations by using +`spring.resources.static-locations`. Doing so replaces the default values with a list of +directory locations. If you do so, the default welcome page detection switches to your +custom locations. So, if there is an `index.html` in any of your locations on startup, it +is the home page of the application. + +In addition to the "`standard`" static resource locations listed earlier, a special case +is made for https://www.webjars.org/[Webjars content]. Any resources with a path in +`+/webjars/**+` are served from jar files if they are packaged in the Webjars format. + +TIP: Spring WebFlux applications do not strictly depend on the Servlet API, so they +cannot be deployed as war files and do not use the `src/main/webapp` directory. + + + +[[boot-features-webflux-template-engines]] +==== Template Engines +As well as REST web services, you can also use Spring WebFlux to serve dynamic HTML +content. Spring WebFlux supports a variety of templating technologies, including +Thymeleaf, FreeMarker, and Mustache. + +Spring Boot includes auto-configuration support for the following templating engines: + + * https://freemarker.apache.org/docs/[FreeMarker] + * https://www.thymeleaf.org[Thymeleaf] + * https://mustache.github.io/[Mustache] + +When you use one of these templating engines with the default configuration, your +templates are picked up automatically from `src/main/resources/templates`. + + + +[[boot-features-webflux-error-handling]] +==== Error Handling + +Spring Boot provides a `WebExceptionHandler` that handles all errors in a sensible way. +Its position in the processing order is immediately before the handlers provided by +WebFlux, which are considered last. For machine clients, it produces a JSON response +with details of the error, the HTTP status, and the exception message. For browser +clients, there is a "`whitelabel`" error handler that renders the same data in HTML +format. You can also provide your own HTML templates to display errors (see the +<>). + +The first step to customizing this feature often involves using the existing mechanism +but replacing or augmenting the error contents. For that, you can add a bean of type +`ErrorAttributes`. + +To change the error handling behavior, you can implement `ErrorWebExceptionHandler` and +register a bean definition of that type. Because a `WebExceptionHandler` is quite +low-level, Spring Boot also provides a convenient `AbstractErrorWebExceptionHandler` to +let you handle errors in a WebFlux functional way, as shown in the following example: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { + + // Define constructor here + + @Override + protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) { + + return RouterFunctions + .route(aPredicate, aHandler) + .andRoute(anotherPredicate, anotherHandler); + } + + } +---- + +For a more complete picture, you can also subclass `DefaultErrorWebExceptionHandler` +directly and override specific methods. + + + +[[boot-features-webflux-error-handling-custom-error-pages]] +===== Custom Error Pages + +If you want to display a custom HTML error page for a given status code, you can add a +file to an `/error` folder. Error pages can either be static HTML (that is, added under +any of the static resource folders) or built with templates. The name of the file should +be the exact status code or a series mask. + +For example, to map `404` to a static HTML file, your folder structure would be as +follows: + +[source,indent=0,subs="verbatim,quotes,attributes"] +---- + src/ + +- main/ + +- java/ + | + + +- resources/ + +- public/ + +- error/ + | +- 404.html + +- +---- + +To map all `5xx` errors by using a Mustache template, your folder structure would be as +follows: + +[source,indent=0,subs="verbatim,quotes,attributes"] +---- + src/ + +- main/ + +- java/ + | + + +- resources/ + +- templates/ + +- error/ + | +- 5xx.mustache + +- +---- + + + +[[boot-features-webflux-web-filters]] +==== Web Filters +Spring WebFlux provides a `WebFilter` interface that can be implemented to filter HTTP +request-response exchanges. `WebFilter` beans found in the application context will +be automatically used to filter each exchange. + +Where the order of the filters is important they can implement `Ordered` or be annotated +with `@Order`. Spring Boot auto-configuration may configure web filters for you. When it +does so, the orders shown in the following table will be used: + +|=== +| Web Filter | Order + +|`MetricsWebFilter` +|`Ordered.HIGHEST_PRECEDENCE + 1` + +|`WebFilterChainProxy` (Spring Security) +|`-100` + +|`HttpTraceWebFilter` +|`Ordered.LOWEST_PRECEDENCE - 10` + +|=== + + + +[[boot-features-jersey]] +=== JAX-RS and Jersey +If you prefer the JAX-RS programming model for REST endpoints, you can use one of the +available implementations instead of Spring MVC. https://jersey.github.io/[Jersey] and +https://cxf.apache.org/[Apache CXF] work quite well out of the box. CXF requires you to +register its `Servlet` or `Filter` as a `@Bean` in your application context. Jersey has +some native Spring support, so we also provide auto-configuration support for it in +Spring Boot, together with a starter. + +To get started with Jersey, include the `spring-boot-starter-jersey` as a dependency +and then you need one `@Bean` of type `ResourceConfig` in which you register all the +endpoints, as shown in the following example: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + @Component + public class JerseyConfig extends ResourceConfig { + + public JerseyConfig() { + register(Endpoint.class); + } + + } +---- + +WARNING: Jersey's support for scanning executable archives is rather limited. For example, +it cannot scan for endpoints in a package found in a <> or in `WEB-INF/classes` when running an executable war file. +To avoid this limitation, the `packages` method should not be used, and endpoints should +be registered individually by using the `register` method, as shown in the preceding +example. + +For more advanced customizations, you can also register an arbitrary number of beans that +implement `ResourceConfigCustomizer`. + +All the registered endpoints should be `@Components` with HTTP resource annotations +(`@GET` and others), as shown in the following example: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + @Component + @Path("/hello") + public class Endpoint { + + @GET + public String message() { + return "Hello"; + } + + } +---- + +Since the `Endpoint` is a Spring `@Component`, its lifecycle is managed by Spring and you +can use the `@Autowired` annotation to inject dependencies and use the `@Value` +annotation to inject external configuration. By default, the Jersey servlet is registered +and mapped to `/*`. You can change the mapping by adding `@ApplicationPath` to your +`ResourceConfig`. + +By default, Jersey is set up as a Servlet in a `@Bean` of type `ServletRegistrationBean` +named `jerseyServletRegistration`. By default, the servlet is initialized lazily, but you +can customize that behavior by setting `spring.jersey.servlet.load-on-startup`. You can +disable or override that bean by creating one of your own with the same name. You can +also use a filter instead of a servlet by setting `spring.jersey.type=filter` (in which +case, the `@Bean` to replace or override is `jerseyFilterRegistration`). The filter has +an `@Order`, which you can set with `spring.jersey.filter.order`. Both the servlet and +the filter registrations can be given init parameters by using `spring.jersey.init.*` to +specify a map of properties. + + + +[[boot-features-embedded-container]] +=== Embedded Servlet Container Support +Spring Boot includes support for embedded https://tomcat.apache.org/[Tomcat], +https://www.eclipse.org/jetty/[Jetty], and +https://github.com/undertow-io/undertow[Undertow] servers. Most developers use the +appropriate "`Starter`" to obtain a fully configured instance. By default, the embedded +server listens for HTTP requests on port `8080`. + + + +[[boot-features-embedded-container-servlets-filters-listeners]] +==== Servlets, Filters, and listeners +When using an embedded servlet container, you can register servlets, filters, and all the +listeners (such as `HttpSessionListener`) from the Servlet spec, either by using Spring +beans or by scanning for Servlet components. + + +[[boot-features-embedded-container-servlets-filters-listeners-beans]] +===== Registering Servlets, Filters, and Listeners as Spring Beans +Any `Servlet`, `Filter`, or servlet `*Listener` instance that is a Spring bean is +registered with the embedded container. This can be particularly convenient if you want +to refer to a value from your `application.properties` during configuration. + +By default, if the context contains only a single Servlet, it is mapped to `/`. In the +case of multiple servlet beans, the bean name is used as a path prefix. Filters map to +`+/*+`. + +If convention-based mapping is not flexible enough, you can use the +`ServletRegistrationBean`, `FilterRegistrationBean`, and +`ServletListenerRegistrationBean` classes for complete control. + +Filter beans can be ordered to control their position in the filter chain by using +`@Order` or implemented `Ordered`. It is usually safe to leave Filter beans unordered. +However, if a specific order is required, you should avoid configuring a Filter that reads +the request body at `Ordered.HIGHEST_PRECEDENCE`, since it might go against the character +encoding configuration of your application. If a Servlet filter wraps the request, it +should be configured with an order that is less than or equal to +`OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER`. + +TIP: To see the order of every `Filter` in your application, enable debug level logging +for the `web` <> +(`logging.level.web=debug`). Details of the registered filters, including their order and +URL patterns, will then be logged at startup. + + + +[[boot-features-embedded-container-context-initializer]] +==== Servlet Context Initialization +Embedded servlet containers do not directly execute the Servlet 3.0+ +`javax.servlet.ServletContainerInitializer` interface or Spring's +`org.springframework.web.WebApplicationInitializer` interface. This is an intentional +design decision intended to reduce the risk that third party libraries designed to run +inside a war may break Spring Boot applications. + +If you need to perform servlet context initialization in a Spring Boot application, you +should register a bean that implements the +`org.springframework.boot.web.servlet.ServletContextInitializer` interface. The +single `onStartup` method provides access to the `ServletContext` and, if necessary, can +easily be used as an adapter to an existing `WebApplicationInitializer`. + + + +[[boot-features-embedded-container-servlets-filters-listeners-scanning]] +===== Scanning for Servlets, Filters, and listeners +When using an embedded container, automatic registration of classes annotated with +`@WebServlet`, `@WebFilter`, and `@WebListener` can be enabled by using +`@ServletComponentScan`. + +TIP: `@ServletComponentScan` has no effect in a standalone container, where the +container's built-in discovery mechanisms are used instead. + + + +[[boot-features-embedded-container-application-context]] +==== The ServletWebServerApplicationContext +Under the hood, Spring Boot uses a different type of `ApplicationContext` for embedded +servlet container support. The `ServletWebServerApplicationContext` is a special type of +`WebApplicationContext` that bootstraps itself by searching for a single +`ServletWebServerFactory` bean. Usually a `TomcatServletWebServerFactory`, +`JettyServletWebServerFactory`, or `UndertowServletWebServerFactory` +has been auto-configured. + +NOTE: You usually do not need to be aware of these implementation classes. Most +applications are auto-configured, and the appropriate `ApplicationContext` and +`ServletWebServerFactory` are created on your behalf. + + + +[[boot-features-customizing-embedded-containers]] +==== Customizing Embedded Servlet Containers +Common servlet container settings can be configured by using Spring `Environment` +properties. Usually, you would define the properties in your `application.properties` +file. + +Common server settings include: + +* Network settings: Listen port for incoming HTTP requests (`server.port`), interface +address to bind to `server.address`, and so on. +* Session settings: Whether the session is persistent (`server.servlet.session.persistent`), +session timeout (`server.servlet.session.timeout`), location of session data +(`server.servlet.session.store-dir`), and session-cookie configuration +(`server.servlet.session.cookie.*`). +* Error management: Location of the error page (`server.error.path`) and so on. +* <> +* <> + +Spring Boot tries as much as possible to expose common settings, but this is not always +possible. For those cases, dedicated namespaces offer server-specific customizations (see +`server.tomcat` and `server.undertow`). For instance, +<> can be configured with specific +features of the embedded servlet container. + +TIP: See the +{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] class +for a complete list. + + + +[[boot-features-programmatic-embedded-container-customization]] +===== Programmatic Customization +If you need to programmatically configure your embedded servlet container, you can +register a Spring bean that implements the `WebServerFactoryCustomizer` interface. +`WebServerFactoryCustomizer` provides access to the +`ConfigurableServletWebServerFactory`, which includes numerous customization setter +methods. The following example shows programmatically setting the port: + +[source,java,indent=0] +---- + import org.springframework.boot.web.server.WebServerFactoryCustomizer; + import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; + import org.springframework.stereotype.Component; + + @Component + public class CustomizationBean implements WebServerFactoryCustomizer { + + @Override + public void customize(ConfigurableServletWebServerFactory server) { + server.setPort(9000); + } + + } +---- + +NOTE: `TomcatServletWebServerFactory`, `JettyServletWebServerFactory` and `UndertowServletWebServerFactory` +are dedicated variants of `ConfigurableServletWebServerFactory` that have additional customization setter methods +for Tomcat, Jetty and Undertow respectively. + + + +[[boot-features-customizing-configurableservletwebserverfactory-directly]] +===== Customizing ConfigurableServletWebServerFactory Directly +If the preceding customization techniques are too limited, you can register the +`TomcatServletWebServerFactory`, `JettyServletWebServerFactory`, or +`UndertowServletWebServerFactory` bean yourself. + +[source,java,indent=0] +---- + @Bean + public ConfigurableServletWebServerFactory webServerFactory() { + TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); + factory.setPort(9000); + factory.setSessionTimeout(10, TimeUnit.MINUTES); + factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html")); + return factory; + } +---- + +Setters are provided for many configuration options. Several protected method "`hooks`" +are also provided should you need to do something more exotic. See the +{dc-spring-boot}/web/servlet/server/ConfigurableServletWebServerFactory.{dc-ext}[source +code documentation] for details. + + + +[[boot-features-jsp-limitations]] +==== JSP Limitations +When running a Spring Boot application that uses an embedded servlet container (and is +packaged as an executable archive), there are some limitations in the JSP support. + +* With Jetty and Tomcat, it should work if you use war packaging. An executable war will + work when launched with `java -jar`, and will also be deployable to any standard + container. JSPs are not supported when using an executable jar. + +* Undertow does not support JSPs. + +* Creating a custom `error.jsp` page does not override the default view for +<>. +<> should be used +instead. + + + +[[boot-features-reactive-server]] +=== Embedded Reactive Server Support +Spring Boot includes support for the following embedded reactive web servers: +Reactor Netty, Tomcat, Jetty, and Undertow. Most developers use the appropriate “Starter” +to obtain a fully configured instance. By default, the embedded server listens for HTTP +requests on port 8080. + + + +[[boot-features-reactive-server-resources]] +=== Reactive Server Resources Configuration +When auto-configuring a Reactor Netty or Jetty server, Spring Boot will create specific +beans that will provide HTTP resources to the server instance: `ReactorResourceFactory` +or `JettyResourceFactory`. + +By default, those resources will be also shared with the Reactor Netty and Jetty clients +for optimal performances, given: + +* the same technology is used for server and client +* the client instance is built using the `WebClient.Builder` bean auto-configured by +Spring Boot + +Developers can override the resource configuration for Jetty and Reactor Netty by providing +a custom `ReactorResourceFactory` or `JettyResourceFactory` bean - this will be applied to +both clients and servers. + +You can learn more about the resource configuration on the client side in the +<>. + + + +[[boot-features-rsocket]] +== RSocket + +https://rsocket.io[RSocket] is a binary protocol for use on byte stream transports. +It enables symmetric interaction models via async message passing over a single connection. + +Spring Framework, with the Spring Messaging module supports RSocket both on the server and +the client side. On the server side, it lets you create special `@Controller` beans +to handle incoming RSocket messages. +Methods in your controller are mapped to RSocket routes by using `@MessageMapping` annotations. + +The following code shows a typical `@Controller`: + +[source,java,indent=0] +---- + @Controller + public class MyRSocketController { + + @MessageMapping("chat.room.{name}") + public Flux enterChatRoom(@DestinationVariable String chatRoom, + Flux messages) { + // ... + } + + @MessageMapping("users.\{user}.info") + Mono getUserInfo(@DestinationVariable String user) { + // ... + } + + } +---- + + + +[[boot-features-rsocket-strategies-auto-configuration]] +=== RSocket Strategies Auto-configuration +Spring Boot auto-configures an `RSocketStrategies` bean that provides all the required +infrastructure for encoding and decoding RSocket payloads. By default, the +auto-configuration will try to configure the following (in order): + +1. https://cbor.io/[CBOR] codecs with Jackson +2. JSON codecs with Jackson + +The `spring-boot-starter-rsocket` Starter provides both dependencies. + +Developers can customize the `RSocketStrategies` component by creating beans that +implement the `RSocketStrategiesCustomizer` interface. Note that their `@Order` is +important, as it determines the order of codecs. + + + +[[boot-features-rsocket-server-auto-configuration]] +=== RSocket server Auto-configuration +Spring Boot provides auto-configuration for RSocket servers. The required dependencies +are provided by the `spring-boot-starter-rsocket`. + +Spring Boot will start an RSocket server as a new embedded server in your application, +or will plug the RSocket infrastructure into an existing reactive Web server. This +depends on the type of application and its configuration. + +In case of a WebFlux application (i.e. of type `WebApplicationType.REACTIVE`), the +RSocket server will be plugged into the existing Web Server only if the following +properties match: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.rsocket.server.mapping-path=/rsocket # a mapping path is defined + spring.rsocket.server.transport=websocket # websocket is chosen as a transport + #spring.rsocket.server.port= # no port is defined +---- + +The only other way to create an RSocket server is to start an independent, embedded +RSocket server. Besides the dependency requirements, the only required configuration +is to define a port for that server: + +[source,properties,indent=0,subs="verbatim,quotes,attributes"] +---- + spring.rsocket.server.port=9898 # the only required configuration + spring.rsocket.server.transport=tcp # you're free to configure other properties +---- + + + +[[boot-features-rsocket-messaging]] +=== Spring Messaging RSocket support +Spring Boot will auto-configure the Spring Messaging infrastructure for RSocket. + +An `RSocketStrategies` bean is created to provide encoding and decoding support +for RSocket messages. By default, Spring Boot will try to auto-configure JSON +support with Jackson for `application/json` and `"application/*+json"` media types. +Check out the <> to know more +about customization possibilities. + +Developers can create `RSocketStrategiesCustomizer` beans to add other strategies, +assuming there are `Encoder` and `Decoder` implementations available. + + + +[[boot-features-rsocket-requester]] +=== Calling RSocket Services with `RSocketRequester` + +Once the `RSocket` channel is established between server and client, any party can send or +receive requests to the other. + +As a server, you can get injected an `RSocketRequester` instance on any handler method of +an RSocket `@Controller`. As a client, you need to configure and establish an RSocket +connection first. Spring Boot auto-configures an `RSocketRequester.Builder` for such cases +with the expected codecs. + +The `RSocketRequester.Builder` instance is a prototype bean, meaning each injection point +will provide you with a new instance - this is done on purpose since this builder is stateful +and you shouldn't create requesters with different setups using the same instance. + +The following code shows a typical example: + +[source,java,indent=0] +---- + @Service + public class MyService { + + private final RSocketRequester rsocketRequester; + + public MyService(RSocketRequester.Builder rsocketRequesterBuilder) { + this.rsocketRequester = rsocketRequesterBuilder + .connectTcp("example.org", 9090).block(); + } + + public Mono someRSocketCall(String name) { + return this.requester.route("user").data(name) + .retrieveMono(User.class); + } + + } +---- + + + +[[boot-features-security]] +== Security +If {spring-security}[Spring Security] is on the classpath, then web applications are +secured by default. Spring Boot relies on Spring Security’s content-negotiation strategy +to determine whether to use `httpBasic` or `formLogin`. To add method-level security to a +web application, you can also add `@EnableGlobalMethodSecurity` with your desired +settings. Additional information can be found in the +{spring-security-reference}#jc-method[Spring Security Reference Guide]. + +The default `UserDetailsService` has a single user. The user name is `user`, and the +password is random and is printed at INFO level when the application starts, as shown in +the following example: + +[indent=0] +---- + Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35 +---- + +NOTE: If you fine-tune your logging configuration, ensure that the +`org.springframework.boot.autoconfigure.security` category is set to log `INFO`-level +messages. Otherwise, the default password is not printed. + +You can change the username and password by providing a `spring.security.user.name` and +`spring.security.user.password`. + +The basic features you get by default in a web application are: + +* A `UserDetailsService` (or `ReactiveUserDetailsService` in case of a WebFlux application) +bean with in-memory store and a single user with a generated password (see +{dc-spring-boot}/autoconfigure/security/SecurityProperties.User.html[`SecurityProperties.User`] +for the properties of the user). +* Form-based login or HTTP Basic security (depending on the `Accept` header in the request) for +the entire application (including actuator endpoints if actuator is on the classpath). +* A `DefaultAuthenticationEventPublisher` for publishing authentication events. + +You can provide a different `AuthenticationEventPublisher` by adding a bean for it. + + + +[[boot-features-security-mvc]] +=== MVC Security +The default security configuration is implemented in `SecurityAutoConfiguration` and +`UserDetailsServiceAutoConfiguration`. `SecurityAutoConfiguration` imports +`SpringBootWebSecurityConfiguration` for web security and +`UserDetailsServiceAutoConfiguration` configures authentication, which is also +relevant in non-web applications. To switch off the default web application security +configuration completely, you can add a bean of type `WebSecurityConfigurerAdapter` (doing +so does not disable the `UserDetailsService` configuration or Actuator's security). + +To also switch off the `UserDetailsService` configuration, you can add a bean of type +`UserDetailsService`, `AuthenticationProvider`, or `AuthenticationManager`. + +Access rules can be overridden by adding a custom `WebSecurityConfigurerAdapter`. Spring +Boot provides convenience methods that can be used to override access rules for actuator +endpoints and static resources. `EndpointRequest` can be used to create a `RequestMatcher` +that is based on the `management.endpoints.web.base-path` property. +`PathRequest` can be used to create a `RequestMatcher` for resources in +commonly used locations. + + + +[[boot-features-security-webflux]] +=== WebFlux Security +Similar to Spring MVC applications, you can secure your WebFlux applications by adding +the `spring-boot-starter-security` dependency. The default security configuration is +implemented in `ReactiveSecurityAutoConfiguration` and +`UserDetailsServiceAutoConfiguration`. `ReactiveSecurityAutoConfiguration` imports +`WebFluxSecurityConfiguration` for web security and `UserDetailsServiceAutoConfiguration` +configures authentication, which is also relevant in non-web applications. To switch off the default web application security +configuration completely, you can add a bean of type `WebFilterChainProxy` (doing so does +not disable the `UserDetailsService` configuration or Actuator's security). + +To also switch off the `UserDetailsService` configuration, you can add a bean of type +`ReactiveUserDetailsService` or `ReactiveAuthenticationManager`. + +Access rules can be configured by adding a custom `SecurityWebFilterChain`. Spring +Boot provides convenience methods that can be used to override access rules for actuator +endpoints and static resources. `EndpointRequest` can be used to create a +`ServerWebExchangeMatcher` that is based on the `management.endpoints.web.base-path` +property. + +`PathRequest` can be used to create a `ServerWebExchangeMatcher` for resources in +commonly used locations. + +For example, you can customize your security configuration by adding something like: + +[source,java,indent=0] +---- +include::{code-examples}/web/security/CustomWebFluxSecurityExample.java[tag=configuration] +---- + + + +[[boot-features-security-oauth2]] +=== OAuth2 +https://oauth.net/2/[OAuth2] is a widely used authorization framework that is supported by +Spring. + + + +[[boot-features-security-oauth2-client]] +==== Client +If you have `spring-security-oauth2-client` on your classpath, you can take advantage of +some auto-configuration to make it easy to set up an OAuth2/Open ID Connect clients. This configuration +makes use of the properties under `OAuth2ClientProperties`. The same properties are applicable to both servlet and reactive applications. + +You can register multiple OAuth2 clients and providers under the +`spring.security.oauth2.client` prefix, as shown in the following example: + +[source,properties,indent=0] +---- + spring.security.oauth2.client.registration.my-client-1.client-id=abcd + spring.security.oauth2.client.registration.my-client-1.client-secret=password + spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope + spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider + spring.security.oauth2.client.registration.my-client-1.scope=user + spring.security.oauth2.client.registration.my-client-1.redirect-uri-template=https://my-redirect-uri.com + spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic + spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code + + spring.security.oauth2.client.registration.my-client-2.client-id=abcd + spring.security.oauth2.client.registration.my-client-2.client-secret=password + spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope + spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider + spring.security.oauth2.client.registration.my-client-2.scope=email + spring.security.oauth2.client.registration.my-client-2.redirect-uri-template=https://my-redirect-uri.com + spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic + spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code + + spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=https://my-auth-server/oauth/authorize + spring.security.oauth2.client.provider.my-oauth-provider.token-uri=https://my-auth-server/oauth/token + spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=https://my-auth-server/userinfo + spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header + spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=https://my-auth-server/token_keys + spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name +---- + +For OpenID Connect providers that support https://openid.net/specs/openid-connect-discovery-1_0.html[OpenID Connect discovery], +the configuration can be further simplified. The provider needs to be configured with an `issuer-uri` which is the +URI that the it asserts as its Issuer Identifier. For example, if the +`issuer-uri` provided is "https://example.com", then an `OpenID Provider Configuration Request` +will be made to "https://example.com/.well-known/openid-configuration". The result is expected +to be an `OpenID Provider Configuration Response`. The following example shows how an OpenID Connect +Provider can be configured with the `issuer-uri`: + +[source,properties,indent=0] +---- + spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/ +---- + + + +By default, Spring Security's `OAuth2LoginAuthenticationFilter` only processes URLs +matching `/login/oauth2/code/*`. If you want to customize the `redirect-uri` to +use a different pattern, you need to provide configuration to process that custom pattern. +For example, for servlet applications, you can add your own `WebSecurityConfigurerAdapter` that resembles the +following: + +[source,java,indent=0] +---- +public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .oauth2Login() + .redirectionEndpoint() + .baseUri("/custom-callback"); + } +} +---- + + + +[[boot-features-security-oauth2-common-providers]] +===== OAuth2 client registration for common providers +For common OAuth2 and OpenID providers, including Google, Github, Facebook, and Okta, +we provide a set of provider defaults (`google`, `github`, `facebook`, and `okta`, +respectively). + +If you do not need to customize these providers, you can set the `provider` attribute to +the one for which you need to infer defaults. Also, if the key for the client registration matches a +default supported provider, Spring Boot infers that as well. + +In other words, the two configurations in the following example use the Google provider: + +[source,properties,indent=0] +---- + spring.security.oauth2.client.registration.my-client.client-id=abcd + spring.security.oauth2.client.registration.my-client.client-secret=password + spring.security.oauth2.client.registration.my-client.provider=google + + spring.security.oauth2.client.registration.google.client-id=abcd + spring.security.oauth2.client.registration.google.client-secret=password +---- + + + +[[boot-features-security-oauth2-server]] +==== Resource Server +If you have `spring-security-oauth2-resource-server` on your classpath, Spring Boot can +set up an OAuth2 Resource Server. For JWT configuration, a JWK Set URI or OIDC Issuer URI +needs to be specified, as shown in the following examples: + +[source,properties,indent=0] +---- + spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys +---- + +[source,properties,indent=0] +---- + spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/ +---- + +NOTE: If the authorization server does not support a JWK Set URI, you can configure the +resource server with the Public Key used for verifying the signature of the JWT. This can +be done using the `spring.security.oauth2.resourceserver.jwt.public-key-location` property, +where the value needs to point to a file containing the public key in the PEM-encoded x509 +format. + +The same properties are applicable for both servlet and reactive applications. + +Alternatively, you can define your own `JwtDecoder` bean for servlet applications +or a `ReactiveJwtDecoder` for reactive applications. + +In cases where opaque tokens are used instead of JWTs, you can configure the following properties +to validate tokens via introspection: + +[source,properties,indent=0] +---- + spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://example.com/check-token + spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id + spring.security.oauth2.resourceserver.opaquetoken.client-secret-my-client-secret +---- + +Again, the same properties are applicable for both servlet and reactive applications. + +Alternatively, you can define your own `OAuth2TokenIntrospectionClient` bean for servlet applications +or a `ReactiveOAuth2TokenIntrospectionClient` for reactive applications. + +==== Authorization Server +Currently, Spring Security does not provide support for implementing an OAuth 2.0 +Authorization Server. However, this functionality is available from +the https://projects.spring.io/spring-security-oauth/[Spring Security OAuth] project, +which will eventually be superseded by Spring Security completely. Until then, you can +use the `spring-security-oauth2-autoconfigure` module to easily set up an OAuth 2.0 authorization server; +see its https://docs.spring.io/spring-security-oauth2-boot[documentation] for instructions. + + + +[[boot-features-security-actuator]] +=== Actuator Security +For security purposes, all actuators other than `/health` and `/info` are disabled by +default. The `management.endpoints.web.exposure.include` property can be used to enable +the actuators. + +If Spring Security is on the classpath and no other WebSecurityConfigurerAdapter is +present, all actuators other than `/health` and `/info` are secured by Spring Boot +auto-configuration. If you define a custom `WebSecurityConfigurerAdapter`, Spring Boot +auto-configuration will back off and you will be in full control of actuator access rules. + +NOTE: Before setting the `management.endpoints.web.exposure.include`, ensure that the +exposed actuators do not contain sensitive information and/or are secured by placing them +behind a firewall or by something like Spring Security. + + + +[[boot-features-security-csrf]] +==== Cross Site Request Forgery Protection +Since Spring Boot relies on Spring Security's defaults, CSRF protection is turned on by +default. This means that the actuator endpoints that require a `POST` (shutdown and +loggers endpoints), `PUT` or `DELETE` will get a 403 forbidden error when the default +security configuration is in use. + +NOTE: We recommend disabling CSRF protection completely only if you are creating a service +that is used by non-browser clients. + +Additional information about CSRF protection can be found in the +{spring-security-reference}#csrf[Spring Security Reference Guide]. + + + +[[boot-features-sql]] +== Working with SQL Databases +The {spring-framework}[Spring Framework] provides extensive support for working with SQL +databases, from direct JDBC access using `JdbcTemplate` to complete "`object relational +mapping`" technologies such as Hibernate. {spring-data}[Spring Data] provides an +additional level of functionality: creating `Repository` implementations directly from +interfaces and using conventions to generate queries from your method names. + + + +[[boot-features-configure-datasource]] +=== Configure a DataSource +Java's `javax.sql.DataSource` interface provides a standard method of working with +database connections. Traditionally, a 'DataSource' uses a `URL` along with some +credentials to establish a database connection. + +TIP: See <> for more +advanced examples, typically to take full control over the configuration of the +DataSource. + + + +[[boot-features-embedded-database-support]] +==== Embedded Database Support +It is often convenient to develop applications by using an in-memory embedded database. +Obviously, in-memory databases do not provide persistent storage. You need to populate +your database when your application starts and be prepared to throw away data when your +application ends. + +TIP: The "`How-to`" section includes a <>. + +Spring Boot can auto-configure embedded https://www.h2database.com[H2], +http://hsqldb.org/[HSQL], and https://db.apache.org/derby/[Derby] databases. You need not +provide any connection URLs. You need only include a build dependency to the embedded +database that you want to use. + +[NOTE] +==== +If you are using this feature in your tests, you may notice that the same database is +reused by your whole test suite regardless of the number of application contexts that you +use. If you want to make sure that each context has a separate embedded database, you +should set `spring.datasource.generate-unique-name` to `true`. +==== + +For example, the typical POM dependencies would be as follows: + +[source,xml,indent=0] +---- + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.hsqldb + hsqldb + runtime + +---- + +NOTE: You need a dependency on `spring-jdbc` for an embedded database to be +auto-configured. In this example, it is pulled in transitively through +`spring-boot-starter-data-jpa`. + +TIP: If, for whatever reason, you do configure the connection URL for an embedded +database, take care to ensure that the database's automatic shutdown is disabled. If you +use H2, you should use `DB_CLOSE_ON_EXIT=FALSE` to do so. If you use HSQLDB, you should +ensure that `shutdown=true` is not used. Disabling the database's automatic shutdown lets +Spring Boot control when the database is closed, thereby ensuring that it happens once +access to the database is no longer needed. + + + +[[boot-features-connect-to-production-database]] +==== Connection to a Production Database +Production database connections can also be auto-configured by using a pooling +`DataSource`. Spring Boot uses the following algorithm for choosing a specific +implementation: + +. We prefer https://github.com/brettwooldridge/HikariCP[HikariCP] for its performance and +concurrency. If HikariCP is available, we always choose it. +. Otherwise, if the Tomcat pooling `DataSource` is available, we use it. +. If neither HikariCP nor the Tomcat pooling datasource are available and if +https://commons.apache.org/proper/commons-dbcp/[Commons DBCP2] is available, we use it. + +If you use the `spring-boot-starter-jdbc` or `spring-boot-starter-data-jpa` "`starters`", +you automatically get a dependency to `HikariCP`. + +NOTE: You can bypass that algorithm completely and specify the connection pool to use by +setting the `spring.datasource.type` property. This is especially important if you run +your application in a Tomcat container, as `tomcat-jdbc` is provided by default. + +TIP: Additional connection pools can always be configured manually. If you define your +own `DataSource` bean, auto-configuration does not occur. + +DataSource configuration is controlled by external configuration properties in +`+spring.datasource.*+`. For example, you might declare the following section in +`application.properties`: + +[source,properties,indent=0] +---- + spring.datasource.url=jdbc:mysql://localhost/test + spring.datasource.username=dbuser + spring.datasource.password=dbpass + spring.datasource.driver-class-name=com.mysql.jdbc.Driver +---- + +NOTE: You should at least specify the URL by setting the `spring.datasource.url` +property. Otherwise, Spring Boot tries to auto-configure an embedded database. + +TIP: You often do not need to specify the `driver-class-name`, since Spring Boot can +deduce it for most databases from the `url`. + +NOTE: For a pooling `DataSource` to be created, we need to be able to verify that a valid +`Driver` class is available, so we check for that before doing anything. In other words, +if you set `spring.datasource.driver-class-name=com.mysql.jdbc.Driver`, then that class +has to be loadable. + +See +{sc-spring-boot-autoconfigure}/jdbc/DataSourceProperties.{sc-ext}[`DataSourceProperties`] +for more of the supported options. These are the standard options that work regardless of +the actual implementation. It is also possible to fine-tune implementation-specific +settings by using their respective prefix (`+spring.datasource.hikari.*+`, +`+spring.datasource.tomcat.*+`, and `+spring.datasource.dbcp2.*+`). Refer to the +documentation of the connection pool implementation you are using for more details. + +For instance, if you use the +https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html#Common_Attributes[Tomcat +connection pool], you could customize many additional settings, as shown in the following +example: + + +[source,properties,indent=0] +---- + # Number of ms to wait before throwing an exception if no connection is available. + spring.datasource.tomcat.max-wait=10000 + + # Maximum number of active connections that can be allocated from this pool at the same time. + spring.datasource.tomcat.max-active=50 + + # Validate the connection before borrowing it from the pool. + spring.datasource.tomcat.test-on-borrow=true +---- + + + +[[boot-features-connecting-to-a-jndi-datasource]] +==== Connection to a JNDI DataSource +If you deploy your Spring Boot application to an Application Server, you might want to +configure and manage your DataSource by using your Application Server's built-in features +and access it by using JNDI. + +The `spring.datasource.jndi-name` property can be used as an alternative to the +`spring.datasource.url`, `spring.datasource.username`, and `spring.datasource.password` +properties to access the `DataSource` from a specific JNDI location. For example, the +following section in `application.properties` shows how you can access a JBoss AS defined +`DataSource`: + +[source,properties,indent=0] +---- + spring.datasource.jndi-name=java:jboss/datasources/customers +---- + + + +[[boot-features-using-jdbc-template]] +=== Using JdbcTemplate +Spring's `JdbcTemplate` and `NamedParameterJdbcTemplate` classes are auto-configured, and +you can `@Autowire` them directly into your own beans, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.jdbc.core.JdbcTemplate; + import org.springframework.stereotype.Component; + + @Component + public class MyBean { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public MyBean(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + // ... + + } +---- + +You can customize some properties of the template by using the `spring.jdbc.template.*` +properties, as shown in the following example: + +[source,properties,indent=0] +---- + spring.jdbc.template.max-rows=500 +---- + +NOTE: The `NamedParameterJdbcTemplate` reuses the same `JdbcTemplate` instance behind the +scenes. If more than one `JdbcTemplate` is defined and no primary candidate exists, the +`NamedParameterJdbcTemplate` is not auto-configured. + + + +[[boot-features-jpa-and-spring-data]] +=== JPA and Spring Data JPA +The Java Persistence API is a standard technology that lets you "`map`" objects to +relational databases. The `spring-boot-starter-data-jpa` POM provides a quick way to get +started. It provides the following key dependencies: + +* Hibernate: One of the most popular JPA implementations. +* Spring Data JPA: Makes it easy to implement JPA-based repositories. +* Spring ORMs: Core ORM support from the Spring Framework. + +TIP: We do not go into too many details of JPA or {spring-data}[Spring Data] here. You can +follow the https://spring.io/guides/gs/accessing-data-jpa/["`Accessing Data with JPA`"] +guide from https://spring.io and read the {spring-data-jpa}[Spring Data JPA] and +https://hibernate.org/orm/documentation/[Hibernate] reference documentation. + + + +[[boot-features-entity-classes]] +==== Entity Classes +Traditionally, JPA "`Entity`" classes are specified in a `persistence.xml` file. With +Spring Boot, this file is not necessary and "`Entity Scanning`" is used instead. By +default, all packages below your main configuration class (the one annotated with +`@EnableAutoConfiguration` or `@SpringBootApplication`) are searched. + +Any classes annotated with `@Entity`, `@Embeddable`, or `@MappedSuperclass` are +considered. A typical entity class resembles the following example: + +[source,java,indent=0] +---- + package com.example.myapp.domain; + + import java.io.Serializable; + import javax.persistence.*; + + @Entity + public class City implements Serializable { + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + // ... additional members, often include @OneToMany mappings + + protected City() { + // no-args constructor required by JPA spec + // this one is protected since it shouldn't be used directly + } + + public City(String name, String state) { + this.name = name; + this.state = state; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + // ... etc + + } +---- + +TIP: You can customize entity scanning locations by using the `@EntityScan` annotation. +See the "`<>`" +how-to. + + + +[[boot-features-spring-data-jpa-repositories]] +==== Spring Data JPA Repositories +{spring-data-jpa}[Spring Data JPA] repositories are interfaces that you can define to +access data. JPA queries are created automatically from your method names. For example, a +`CityRepository` interface might declare a `findAllByState(String state)` method to find +all the cities in a given state. + +For more complex queries, you can annotate your method with Spring Data's +{spring-data-javadoc}/repository/Query.html[`Query`] annotation. + +Spring Data repositories usually extend from the +{spring-data-commons-javadoc}/repository/Repository.html[`Repository`] or +{spring-data-commons-javadoc}/repository/CrudRepository.html[`CrudRepository`] +interfaces. If you use auto-configuration, repositories are searched from the package +containing your main configuration class (the one annotated with +`@EnableAutoConfiguration` or `@SpringBootApplication`) down. + +The following example shows a typical Spring Data repository interface definition: + +[source,java,indent=0] +---- + package com.example.myapp.domain; + + import org.springframework.data.domain.*; + import org.springframework.data.repository.*; + + public interface CityRepository extends Repository { + + Page findAll(Pageable pageable); + + City findByNameAndStateAllIgnoringCase(String name, String state); + + } +---- + +Spring Data JPA repositories support three different modes of bootstrapping: default, +deferred, and lazy. To enable deferred or lazy bootstrapping, set the +`spring.data.jpa.repositories.bootstrap-mode` to `deferred` or `lazy` respectively. When +using deferred or lazy bootstrapping, the auto-configured `EntityManagerFactoryBuilder` +will use the context's `AsyncTaskExecutor`, if any, as the bootstrap executor. If more +than one exists, the one named `applicationTaskExecutor` will be used. + +TIP: We have barely scratched the surface of Spring Data JPA. For complete details, see +the https://docs.spring.io/spring-data/jpa/docs/current/reference/html/[Spring Data JPA +reference documentation]. + + + +[[boot-features-creating-and-dropping-jpa-databases]] +==== Creating and Dropping JPA Databases +By default, JPA databases are automatically created *only* if you use an embedded +database (H2, HSQL, or Derby). You can explicitly configure JPA settings by using +`+spring.jpa.*+` properties. For example, to create and drop tables you can add the +following line to your `application.properties`: + +[indent=0] +---- + spring.jpa.hibernate.ddl-auto=create-drop +---- + +NOTE: Hibernate's own internal property name for this (if you happen to remember it +better) is `hibernate.hbm2ddl.auto`. You can set it, along with other Hibernate native +properties, by using `+spring.jpa.properties.*+` (the prefix is stripped before adding +them to the entity manager). The following line shows an example of setting JPA +properties for Hibernate: + +[indent=0] +---- + spring.jpa.properties.hibernate.globally_quoted_identifiers=true +---- + +The line in the preceding example passes a value of `true` for the +`hibernate.globally_quoted_identifiers` property to the Hibernate entity manager. + +By default, the DDL execution (or validation) is deferred until the `ApplicationContext` +has started. There is also a `spring.jpa.generate-ddl` flag, but it is not used if +Hibernate auto-configuration is active, because the `ddl-auto` settings are more +fine-grained. + + + +[[boot-features-jpa-in-web-environment]] +==== Open EntityManager in View +If you are running a web application, Spring Boot by default registers +{spring-javadoc}/orm/jpa/support/OpenEntityManagerInViewInterceptor.{dc-ext}[`OpenEntityManagerInViewInterceptor`] +to apply the "`Open EntityManager in View`" pattern, to allow for lazy loading in web +views. If you do not want this behavior, you should set `spring.jpa.open-in-view` to +`false` in your `application.properties`. + + + +[[boot-features-data-jdbc]] +=== Spring Data JDBC +Spring Data includes repository support for JDBC and will automatically generate SQL for +the methods on `CrudRepository`. For more advanced queries, a `@Query` annotation is +provided. + +Spring Boot will auto-configure Spring Data's JDBC repositories when the necessary +dependencies are on the classpath. They can be added to your project with a single +dependency on `spring-boot-starter-data-jdbc`. If necessary, you can take control of +Spring Data JDBC's configuration by adding the `@EnableJdbcRepositories` annotation or a +`JdbcConfiguration` subclass to your application. + +TIP: For complete details of Spring Data JDBC, please refer to the +https://projects.spring.io/spring-data-jdbc/[reference documentation]. + + + +[[boot-features-sql-h2-console]] +=== Using H2's Web Console +The https://www.h2database.com[H2 database] provides a +https://www.h2database.com/html/quickstart.html#h2_console[browser-based console] that +Spring Boot can auto-configure for you. The console is auto-configured when the following +conditions are met: + +* You are developing a servlet-based web application. +* `com.h2database:h2` is on the classpath. +* You are using <>. + +TIP: If you are not using Spring Boot's developer tools but would still like to make use +of H2's console, you can configure the `spring.h2.console.enabled` property with a value +of `true`. + +NOTE: The H2 console is only intended for use during development, so you should take +care to ensure that `spring.h2.console.enabled` is not set to `true` in production. + + + +[[boot-features-sql-h2-console-custom-path]] +==== Changing the H2 Console's Path +By default, the console is available at `/h2-console`. You can customize the console's +path by using the `spring.h2.console.path` property. + + + +[[boot-features-jooq]] +=== Using jOOQ +jOOQ Object Oriented Querying (https://www.jooq.org/[jOOQ]) is a popular product from +https://www.datageekery.com/[Data Geekery] which generates Java code from your +database and lets you build type-safe SQL queries through its fluent API. Both the +commercial and open source editions can be used with Spring Boot. + + + +==== Code Generation +In order to use jOOQ type-safe queries, you need to generate Java classes from your +database schema. You can follow the instructions in the +{jooq-manual}/#jooq-in-7-steps-step3[jOOQ user manual]. If you use the +`jooq-codegen-maven` plugin and you also use the `spring-boot-starter-parent` +"`parent POM`", you can safely omit the plugin's `` tag. You can also use Spring +Boot-defined version variables (such as `h2.version`) to declare the plugin's database +dependency. The following listing shows an example: + +[source,xml,indent=0] +---- + + org.jooq + jooq-codegen-maven + + ... + + + + com.h2database + h2 + ${h2.version} + + + + + org.h2.Driver + jdbc:h2:~/yourdatabase + + + ... + + + +---- + + + +==== Using DSLContext +The fluent API offered by jOOQ is initiated through the `org.jooq.DSLContext` interface. +Spring Boot auto-configures a `DSLContext` as a Spring Bean and connects it to your +application `DataSource`. To use the `DSLContext`, you can `@Autowire` it, as shown in +the following example: + +[source,java,indent=0] +---- + @Component + public class JooqExample implements CommandLineRunner { + + private final DSLContext create; + + @Autowired + public JooqExample(DSLContext dslContext) { + this.create = dslContext; + } + + } +---- + +TIP: The jOOQ manual tends to use a variable named `create` to hold the `DSLContext`. + +You can then use the `DSLContext` to construct your queries, as shown in the following +example: + +[source,java,indent=0] +---- + public List authorsBornAfter1980() { + return this.create.selectFrom(AUTHOR) + .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1))) + .fetch(AUTHOR.DATE_OF_BIRTH); + } +---- + + + +==== jOOQ SQL Dialect +Unless the `spring.jooq.sql-dialect` property has been configured, Spring Boot determines +the SQL dialect to use for your datasource. If Spring Boot could not detect the dialect, +it uses `DEFAULT`. + +NOTE: Spring Boot can only auto-configure dialects supported by the open source version +of jOOQ. + + + +==== Customizing jOOQ +More advanced customizations can be achieved by defining your own `@Bean` definitions, +which is used when the jOOQ `Configuration` is created. You can define beans for the +following jOOQ Types: + +* `ConnectionProvider` +* `ExecutorProvider` +* `TransactionProvider` +* `RecordMapperProvider` +* `RecordUnmapperProvider` +* `RecordListenerProvider` +* `ExecuteListenerProvider` +* `VisitListenerProvider` +* `TransactionListenerProvider` + +You can also create your own `org.jooq.Configuration` `@Bean` if you want to take +complete control of the jOOQ configuration. + + + +[[boot-features-nosql]] +== Working with NoSQL Technologies +Spring Data provides additional projects that help you access a variety of NoSQL +technologies, including: +https://projects.spring.io/spring-data-mongodb/[MongoDB], +https://projects.spring.io/spring-data-neo4j/[Neo4J], +https://github.com/spring-projects/spring-data-elasticsearch/[Elasticsearch], +https://projects.spring.io/spring-data-solr/[Solr], +https://projects.spring.io/spring-data-redis/[Redis], +https://projects.spring.io/spring-data-gemfire/[Gemfire], +https://projects.spring.io/spring-data-cassandra/[Cassandra], +https://projects.spring.io/spring-data-couchbase/[Couchbase] and +https://projects.spring.io/spring-data-ldap/[LDAP]. +Spring Boot provides auto-configuration for Redis, MongoDB, Neo4j, Elasticsearch, Solr +Cassandra, Couchbase, and LDAP. You can make use of the other projects, but you must +configure them yourself. Refer to the appropriate reference documentation at +https://projects.spring.io/spring-data[projects.spring.io/spring-data]. + + + +[[boot-features-redis]] +=== Redis +https://redis.io/[Redis] is a cache, message broker, and richly-featured key-value store. +Spring Boot offers basic auto-configuration for the +https://github.com/lettuce-io/lettuce-core/[Lettuce] and +https://github.com/xetorthio/jedis/[Jedis] client libraries and the abstractions on top +of them provided by https://github.com/spring-projects/spring-data-redis[Spring Data +Redis]. + +There is a `spring-boot-starter-data-redis` "`Starter`" for collecting the dependencies +in a convenient way. By default, it uses +https://github.com/lettuce-io/lettuce-core/[Lettuce]. That starter handles both +traditional and reactive applications. + +TIP: we also provide a `spring-boot-starter-data-redis-reactive` "`Starter`" for +consistency with the other stores with reactive support. + + + +[[boot-features-connecting-to-redis]] +==== Connecting to Redis +You can inject an auto-configured `RedisConnectionFactory`, `StringRedisTemplate`, or +vanilla `RedisTemplate` instance as you would any other Spring Bean. By default, the +instance tries to connect to a Redis server at `localhost:6379`. The following listing +shows an example of such a bean: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private StringRedisTemplate template; + + @Autowired + public MyBean(StringRedisTemplate template) { + this.template = template; + } + + // ... + + } +---- + +TIP: You can also register an arbitrary number of beans that implement +`LettuceClientConfigurationBuilderCustomizer` for more advanced customizations. If you +use Jedis, `JedisClientConfigurationBuilderCustomizer` is also available. + +If you add your own `@Bean` of any of the auto-configured types, it replaces the default +(except in the case of `RedisTemplate`, when the exclusion is based on the bean name, +`redisTemplate`, not its type). By default, if `commons-pool2` is on the classpath, you +get a pooled connection factory. + + + +[[boot-features-mongodb]] +=== MongoDB +https://www.mongodb.com/[MongoDB] is an open-source NoSQL document database that uses a +JSON-like schema instead of traditional table-based relational data. Spring Boot offers +several conveniences for working with MongoDB, including the +`spring-boot-starter-data-mongodb` and `spring-boot-starter-data-mongodb-reactive` +"`Starters`". + + + +[[boot-features-connecting-to-mongodb]] +==== Connecting to a MongoDB Database +To access Mongo databases, you can inject an auto-configured +`org.springframework.data.mongodb.MongoDbFactory`. By default, the instance tries to +connect to a MongoDB server at `mongodb://localhost/test` The following example shows how +to connect to a MongoDB database: + +[source,java,indent=0] +---- + import org.springframework.data.mongodb.MongoDbFactory; + import com.mongodb.DB; + + @Component + public class MyBean { + + private final MongoDbFactory mongo; + + @Autowired + public MyBean(MongoDbFactory mongo) { + this.mongo = mongo; + } + + // ... + + public void example() { + DB db = mongo.getDb(); + // ... + } + + } +---- + +You can set the `spring.data.mongodb.uri` property to change the URL and configure +additional settings such as the _replica set_, as shown in the following example: + +[source,properties,indent=0] +---- + spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test +---- + +Alternatively, as long as you use Mongo 2.x, you can specify a `host`/`port`. For +example, you might declare the following settings in your `application.properties`: + +[source,properties,indent=0] +---- + spring.data.mongodb.host=mongoserver + spring.data.mongodb.port=27017 +---- + +If you have defined your own `MongoClient`, it will be used to auto-configure a suitable +`MongoDbFactory`. Both `com.mongodb.MongoClient` and `com.mongodb.client.MongoClient` +are supported. + +NOTE: If you use the Mongo 3.0 Java driver, `spring.data.mongodb.host` and +`spring.data.mongodb.port` are not supported. In such cases, `spring.data.mongodb.uri` +should be used to provide all of the configuration. + +TIP: If `spring.data.mongodb.port` is not specified, the default of `27017` is used. You +could delete this line from the example shown earlier. + +TIP: If you do not use Spring Data Mongo, you can inject `com.mongodb.MongoClient` beans +instead of using `MongoDbFactory`. If you want to take complete control of establishing +the MongoDB connection, you can also declare your own `MongoDbFactory` or `MongoClient` +bean. + +NOTE: If you are using the reactive driver, Netty is required for SSL. The +auto-configuration configures this factory automatically if Netty is available and the +factory to use hasn't been customized already. + +[[boot-features-mongo-template]] +==== MongoTemplate +{spring-data-mongo}[Spring Data MongoDB] provides a +{spring-data-mongo-javadoc}/core/MongoTemplate.html[`MongoTemplate`] class that is very +similar in its design to Spring's `JdbcTemplate`. As with `JdbcTemplate`, Spring Boot +auto-configures a bean for you to inject the template, as follows: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.data.mongodb.core.MongoTemplate; + import org.springframework.stereotype.Component; + + @Component + public class MyBean { + + private final MongoTemplate mongoTemplate; + + @Autowired + public MyBean(MongoTemplate mongoTemplate) { + this.mongoTemplate = mongoTemplate; + } + + // ... + + } +---- + +See the +https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/MongoOperations.html[`MongoOperations` +Javadoc] for complete details. + + + +[[boot-features-spring-data-mongo-repositories]] +==== Spring Data MongoDB Repositories +Spring Data includes repository support for MongoDB. As with the JPA repositories +discussed earlier, the basic principle is that queries are constructed automatically, +based on method names. + +In fact, both Spring Data JPA and Spring Data MongoDB share the same common +infrastructure. You could take the JPA example from earlier and, assuming that `City` is +now a Mongo data class rather than a JPA `@Entity`, it works in the same way, as shown +in the following example: + +[source,java,indent=0] +---- + package com.example.myapp.domain; + + import org.springframework.data.domain.*; + import org.springframework.data.repository.*; + + public interface CityRepository extends Repository { + + Page findAll(Pageable pageable); + + City findByNameAndStateAllIgnoringCase(String name, String state); + + } +---- + +TIP: You can customize document scanning locations by using the `@EntityScan` annotation. + +TIP: For complete details of Spring Data MongoDB, including its rich object mapping +technologies, refer to its https://projects.spring.io/spring-data-mongodb/[reference +documentation]. + + + +[[boot-features-mongo-embedded]] +==== Embedded Mongo +Spring Boot offers auto-configuration for +https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo[Embedded Mongo]. To use it in +your Spring Boot application, add a dependency on +`de.flapdoodle.embed:de.flapdoodle.embed.mongo`. + +The port that Mongo listens on can be configured by setting the `spring.data.mongodb.port` +property. To use a randomly allocated free port, use a value of 0. The `MongoClient` +created by `MongoAutoConfiguration` is automatically configured to use the randomly +allocated port. + +NOTE: If you do not configure a custom port, the embedded support uses a random port +(rather than 27017) by default. + +If you have SLF4J on the classpath, the output produced by Mongo is automatically routed +to a logger named `org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo`. + +You can declare your own `IMongodConfig` and `IRuntimeConfig` beans to take control of +the Mongo instance's configuration and logging routing. The download configuration can be +customized by declaring a `DownloadConfigBuilderCustomizer` bean. + + + +[[boot-features-neo4j]] +=== Neo4j +https://neo4j.com/[Neo4j] is an open-source NoSQL graph database that uses a rich data +model of nodes connected by first class relationships, which is better suited for +connected big data than traditional RDBMS approaches. Spring Boot offers several +conveniences for working with Neo4j, including the `spring-boot-starter-data-neo4j` +"`Starter`". + + + +[[boot-features-connecting-to-neo4j]] +==== Connecting to a Neo4j Database +To access a Neo4j server, you can inject an auto-configured +`org.neo4j.ogm.session.Session`. By default, the instance tries to connect to a Neo4j +server at `localhost:7687` using the Bolt protocol. The following example shows how to +inject a Neo4j `Session`: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private final Session session; + + @Autowired + public MyBean(Session session) { + this.session = session; + } + + // ... + + } +---- + +You can configure the uri and credentials to use by setting the `spring.data.neo4j.*` +properties, as shown in the following example: + +[source,properties,indent=0] +---- + spring.data.neo4j.uri=bolt://my-server:7687 + spring.data.neo4j.username=neo4j + spring.data.neo4j.password=secret +---- + +You can take full control over the session creation by adding a +`org.neo4j.ogm.config.Configuration` `@Bean`. Also, adding a `@Bean` of type +`SessionFactory` disables the auto-configuration and gives you full control. + + + +[[boot-features-connecting-to-neo4j-embedded]] +==== Using the Embedded Mode +If you add `org.neo4j:neo4j-ogm-embedded-driver` to the dependencies of your application, +Spring Boot automatically configures an in-process embedded instance of Neo4j that does +not persist any data when your application shuts down. + +[NOTE] +==== +As the embedded Neo4j OGM driver does not provide the Neo4j kernel itself, you have +to declare `org.neo4j:neo4j` as dependency yourself. Refer to +https://neo4j.com/docs/ogm-manual/current/reference/#reference:getting-started[the +Neo4j OGM documentation] for a list of compatible versions. +==== + +The embedded driver takes precedence over the other drivers when there are multiple +drivers on the classpath. You can explicitly disable the embedded mode by setting +`spring.data.neo4j.embedded.enabled=false`. + +<> +automatically make use of an embedded Neo4j instance if the embedded driver and Neo4j +kernel are on the classpath as described above. + +[NOTE] +==== +You can enable persistence for the embedded mode by providing a path to a database file +in your configuration, e.g. `spring.data.neo4j.uri=file://var/tmp/graph.db`. +==== + + + +[[boot-features-neo4j-ogm-native-types]] +==== Using Native Types +Neo4j-OGM can map some types, like those in `java.time.*`, to `String`-based properties +or to one of the native types that Neo4j provides. For backwards compatibility reasons +the default for Neo4j-OGM is to use a `String`-based representation. To use native types, +add a dependency on either `org.neo4j:neo4j-ogm-bolt-native-types` or +`org.neo4j:neo4j-ogm-embedded-native-types`, and configure the +`spring.data.neo4j.use-native-types` property as shown in the following example: + +[source,properties,indent=0] +---- + spring.data.neo4j.use-native-types=true +---- + + + +[[boot-features-neo4j-ogm-session]] +==== Neo4jSession +By default, if you are running a web application, the session is bound to the thread for +the entire processing of the request (that is, it uses the "Open Session in View" +pattern). If you do not want this behavior, add the following line to your +`application.properties` file: + +[source,properties,indent=0] +---- + spring.data.neo4j.open-in-view=false +---- + + + +[[boot-features-spring-data-neo4j-repositories]] +==== Spring Data Neo4j Repositories +Spring Data includes repository support for Neo4j. + +Spring Data Neo4j shares the common infrastructure with Spring Data JPA as many other +Spring Data modules do. You could take the JPA example from earlier and define +`City` as Neo4j OGM `@NodeEntity` rather than JPA `@Entity` and the repository +abstraction works in the same way, as shown in the following example: + +[source,java,indent=0] +---- + package com.example.myapp.domain; + + import java.util.Optional; + + import org.springframework.data.neo4j.repository.*; + + public interface CityRepository extends Neo4jRepository { + + Optional findOneByNameAndState(String name, String state); + + } +---- + +The `spring-boot-starter-data-neo4j` "`Starter`" enables the repository support as well +as transaction management. You can customize the locations to look for repositories and +entities by using `@EnableNeo4jRepositories` and `@EntityScan` respectively on a +`@Configuration`-bean. + +TIP: For complete details of Spring Data Neo4j, including its object mapping +technologies, refer to the https://projects.spring.io/spring-data-neo4j/[reference +documentation]. + + + +[[boot-features-gemfire]] +=== Gemfire +https://github.com/spring-projects/spring-data-gemfire[Spring Data Gemfire] provides +convenient Spring-friendly tools for accessing the +https://pivotal.io/big-data/pivotal-gemfire#details[Pivotal Gemfire] data management +platform. There is a `spring-boot-starter-data-gemfire` "`Starter`" for collecting the +dependencies in a convenient way. There is currently no auto-configuration support for +Gemfire, but you can enable Spring Data Repositories with a +https://github.com/spring-projects/spring-data-gemfire/blob/master/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java[single annotation: `@EnableGemfireRepositories`]. + + + +[[boot-features-solr]] +=== Solr +https://lucene.apache.org/solr/[Apache Solr] is a search engine. Spring Boot offers basic +auto-configuration for the Solr 5 client library and the abstractions on top of it +provided by https://github.com/spring-projects/spring-data-solr[Spring Data Solr]. There +is a `spring-boot-starter-data-solr` "`Starter`" for collecting the dependencies in a +convenient way. + + +[[boot-features-connecting-to-solr]] +==== Connecting to Solr +You can inject an auto-configured `SolrClient` instance as you would any other Spring +bean. By default, the instance tries to connect to a server at +`http://localhost:8983/solr`. The following example shows how to inject a Solr bean: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private SolrClient solr; + + @Autowired + public MyBean(SolrClient solr) { + this.solr = solr; + } + + // ... + + } +---- + +If you add your own `@Bean` of type `SolrClient`, it replaces the default. + + + +[[boot-features-spring-data-solr-repositories]] +==== Spring Data Solr Repositories +Spring Data includes repository support for Apache Solr. As with the JPA repositories +discussed earlier, the basic principle is that queries are automatically constructed for \ +you based on method names. + +In fact, both Spring Data JPA and Spring Data Solr share the same common infrastructure. +You could take the JPA example from earlier and, assuming that `City` is now a +`@SolrDocument` class rather than a JPA `@Entity`, it works in the same way. + +TIP: For complete details of Spring Data Solr, refer to the +https://projects.spring.io/spring-data-solr/[reference documentation]. + + + +[[boot-features-elasticsearch]] +=== Elasticsearch +https://www.elastic.co/products/elasticsearch[Elasticsearch] is an open source, +distributed, RESTful search and analytics engine. Spring Boot offers basic +auto-configuration for Elasticsearch. + +Spring Boot supports several clients: + +* The official Java "Low Level" and "High Level" REST clients +* The `ReactiveElasticsearchClient` provided by Spring Data Elasticsearch + +The transport client is still available but its support has been deprecated in +https://github.com/spring-projects/spring-data-elasticsearch[Spring Data Elasticsearch] +and Elasticsearch itself. It will be removed in a future release. +Spring Boot provides a dedicated "`Starter`", `spring-boot-starter-data-elasticsearch`. + +The https://github.com/searchbox-io/Jest[Jest] client has been deprecated as well, since +both Elasticsearch and Spring Data Elasticsearch provide official support for REST clients. + +[[boot-features-connecting-to-elasticsearch-rest]] +==== Connecting to Elasticsearch using REST clients +Elasticsearch ships +https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html[two different REST clients] +that you can use to query a cluster: the "Low Level" client and the "High Level" client. + +If you have the `org.elasticsearch.client:elasticsearch-rest-client` dependency on the +classpath, Spring Boot will auto-configure and register a `RestClient` bean that +by default targets `http://localhost:9200`. +You can further tune how `RestClient` is configured, as shown in the following example: + +[source,properties,indent=0] +---- + spring.elasticsearch.rest.uris=https://search.example.com:9200 + spring.elasticsearch.rest.read-timeout=10s + spring.elasticsearch.rest.username=user + spring.elasticsearch.rest.password=secret +---- + +You can also register an arbitrary number of beans that implement +`RestClientBuilderCustomizer` for more advanced customizations. +To take full control over the registration, define a `RestClient` bean. + +If you have the `org.elasticsearch.client:elasticsearch-rest-high-level-client` dependency +on the classpath, Spring Boot will auto-configure a `RestHighLevelClient`, which wraps +any existing `RestClient` bean, reusing its HTTP configuration. + +[[boot-features-connecting-to-elasticsearch-reactive-rest]] +==== Connecting to Elasticsearch using Reactive REST clients +{spring-data-elasticsearch}[Spring Data Elasticsearch] ships `ReactiveElasticsearchClient` +for querying Elasticsearch instances in a reactive fashion. It is built on top of WebFlux's +`WebClient`, so both `spring-boot-starter-elasticsearch` and `spring-boot-starter-webflux` +dependencies are useful to enable this support. + +By default, Spring Boot will auto-configure and register a `ReactiveElasticsearchClient` +bean that targets `http://localhost:9200`. +You can further tune how it is configured, as shown in the following example: + +[source,properties,indent=0] +---- + spring.elasticsearch.reactive.endpoints=search.example.com:9200 + spring.elasticsearch.reactive.use-ssl=true + spring.elasticsearch.reactive.socket-timeout=10s + spring.elasticsearch.reactive.username=user + spring.elasticsearch.reactive.password=secret +---- + +If the configuration properties are not enough and you'd like to fully control the client +configuration, you can register a custom `ClientConfiguration` bean. + +[[boot-features-connecting-to-elasticsearch-jest]] +==== Connecting to Elasticsearch using Jest +Now that Spring Boot supports the official `RestHighLevelClient`, Jest support is +deprecated. + +If you have `Jest` on the classpath, you can inject an auto-configured `JestClient` that +by default targets `http://localhost:9200`. You can further tune how the client is +configured, as shown in the following example: + +[source,properties,indent=0] +---- + spring.elasticsearch.jest.uris=https://search.example.com:9200 + spring.elasticsearch.jest.read-timeout=10000 + spring.elasticsearch.jest.username=user + spring.elasticsearch.jest.password=secret +---- + +You can also register an arbitrary number of beans that implement +`HttpClientConfigBuilderCustomizer` for more advanced customizations. The following +example tunes additional HTTP settings: + +[source,java,indent=0] +---- +include::{code-examples}/elasticsearch/jest/JestClientCustomizationExample.java[tag=customizer] +---- + +To take full control over the registration, define a `JestClient` bean. + + + +[[boot-features-connecting-to-elasticsearch-spring-data]] +==== Connecting to Elasticsearch by Using Spring Data + +To connect to Elasticsearch, a `RestHighLevelClient` bean must be defined, +auto-configured by Spring Boot or manually provided by the application (see previous sections). +With this configuration in place, an +`ElasticsearchRestTemplate` can be injected like any other Spring bean, +as shown in the following example: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private final ElasticsearchRestTemplate template; + + public MyBean(ElasticsearchRestTemplate template) { + this.template = template; + } + + // ... + + } +---- + +In the presence of `spring-data-elasticsearch` and the required dependencies +for using a `WebClient` (typically `spring-boot-starter-webflux`), Spring Boot can also +auto-configure a +<> +and a `ReactiveElasticsearchTemplate` as beans. They are the reactive equivalent of the +other REST clients. + + +[[boot-features-spring-data-elasticsearch-repositories]] +==== Spring Data Elasticsearch Repositories +Spring Data includes repository support for Elasticsearch. As with the JPA repositories +discussed earlier, the basic principle is that queries are constructed for you +automatically based on method names. + +In fact, both Spring Data JPA and Spring Data Elasticsearch share the same common +infrastructure. You could take the JPA example from earlier and, assuming that `City` is +now an Elasticsearch `@Document` class rather than a JPA `@Entity`, it works in the same +way. + +TIP: For complete details of Spring Data Elasticsearch, refer to the +{spring-data-elasticsearch-reference}[reference documentation]. + +Spring Boot supports both classic and reactive Elasticsearch repositories, using the +`ElasticsearchRestTemplate` or `ReactiveElasticsearchTemplate` beans. Most likely those +beans are auto-configured by Spring Boot given the required dependencies are present. + +If you wish to use your own template for backing the Elasticsearch repositories, you can +add your own `ElasticsearchRestTemplate` or `ElasticsearchOperations` `@Bean`, +as long as it is named `"elasticsearchTemplate"`. Same applies to +`ReactiveElasticsearchTemplate` and `ReactiveElasticsearchOperations`, with the bean +name `"reactiveElasticsearchTemplate"`. + +You can choose to disable the repositories support with the following property: + +[source,properties,indent=0] +---- + spring.data.elasticsearch.repositories.enabled=false +---- + + +[[boot-features-cassandra]] +=== Cassandra +https://cassandra.apache.org/[Cassandra] is an open source, distributed database +management system designed to handle large amounts of data across many commodity servers. +Spring Boot offers auto-configuration for Cassandra and the abstractions on top of it +provided by https://github.com/spring-projects/spring-data-cassandra[Spring Data +Cassandra]. There is a `spring-boot-starter-data-cassandra` "`Starter`" for collecting +the dependencies in a convenient way. + + + +[[boot-features-connecting-to-cassandra]] +==== Connecting to Cassandra +You can inject an auto-configured `CassandraTemplate` or a Cassandra `Session` instance +as you would with any other Spring Bean. The `spring.data.cassandra.*` properties can be +used to customize the connection. Generally, you provide `keyspace-name` and +`contact-points` properties, as shown in the following example: + +[source,properties,indent=0] +---- + spring.data.cassandra.keyspace-name=mykeyspace + spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2 +---- + +You can also register an arbitrary number of beans that implement +`ClusterBuilderCustomizer` for more advanced customizations. + +The following code listing shows how to inject a Cassandra bean: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private CassandraTemplate template; + + @Autowired + public MyBean(CassandraTemplate template) { + this.template = template; + } + + // ... + + } +---- + +If you add your own `@Bean` of type `CassandraTemplate`, it replaces the default. + + + +[[boot-features-spring-data-cassandra-repositories]] +==== Spring Data Cassandra Repositories +Spring Data includes basic repository support for Cassandra. Currently, this is more +limited than the JPA repositories discussed earlier and needs to annotate finder methods +with `@Query`. + +TIP: For complete details of Spring Data Cassandra, refer to the +https://docs.spring.io/spring-data/cassandra/docs/[reference documentation]. + + + +[[boot-features-couchbase]] +=== Couchbase +https://www.couchbase.com/[Couchbase] is an open-source, distributed, multi-model NoSQL +document-oriented database that is optimized for interactive applications. Spring Boot +offers auto-configuration for Couchbase and the abstractions on top of it provided by +https://github.com/spring-projects/spring-data-couchbase[Spring Data Couchbase]. There are +`spring-boot-starter-data-couchbase` and `spring-boot-starter-data-couchbase-reactive` +"`Starters`" for collecting the dependencies in a convenient way. + + + +[[boot-features-connecting-to-couchbase]] +==== Connecting to Couchbase +You can get a `Bucket` and `Cluster` by adding the Couchbase SDK and some configuration. +The `spring.couchbase.*` properties can be used to customize the connection. Generally, +you provide the bootstrap hosts, bucket name, and password, as shown in the following +example: + +[source,properties,indent=0] +---- + spring.couchbase.bootstrap-hosts=my-host-1,192.168.1.123 + spring.couchbase.bucket.name=my-bucket + spring.couchbase.bucket.password=secret +---- + +[TIP] +==== +You need to provide _at least_ the bootstrap host(s), in which case the bucket name is +`default` and the password is an empty String. Alternatively, you can define your own +`org.springframework.data.couchbase.config.CouchbaseConfigurer` `@Bean` to take control +over the whole configuration. +==== + +It is also possible to customize some of the `CouchbaseEnvironment` settings. For +instance, the following configuration changes the timeout to use to open a new `Bucket` +and enables SSL support: + +[source,properties,indent=0] +---- + spring.couchbase.env.timeouts.connect=3000 + spring.couchbase.env.ssl.key-store=/location/of/keystore.jks + spring.couchbase.env.ssl.key-store-password=secret +---- + +Check the `spring.couchbase.env.*` properties for more details. + + + +[[boot-features-spring-data-couchbase-repositories]] +==== Spring Data Couchbase Repositories +Spring Data includes repository support for Couchbase. For complete details of Spring +Data Couchbase, refer to the +https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/[reference +documentation]. + +You can inject an auto-configured `CouchbaseTemplate` instance as you would with any +other Spring Bean, provided a _default_ `CouchbaseConfigurer` is available (which +happens when you enable Couchbase support, as explained earlier). + +The following examples shows how to inject a Couchbase bean: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private final CouchbaseTemplate template; + + @Autowired + public MyBean(CouchbaseTemplate template) { + this.template = template; + } + + // ... + + } +---- + +There are a few beans that you can define in your own configuration to override those +provided by the auto-configuration: + +* A `CouchbaseTemplate` `@Bean` with a name of `couchbaseTemplate`. +* An `IndexManager` `@Bean` with a name of `couchbaseIndexManager`. +* A `CustomConversions` `@Bean` with a name of `couchbaseCustomConversions`. + +To avoid hard-coding those names in your own config, you can reuse `BeanNames` provided +by Spring Data Couchbase. For instance, you can customize the converters to use, as +follows: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + public class SomeConfiguration { + + @Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS) + public CustomConversions myCustomConversions() { + return new CustomConversions(...); + } + + // ... + + } +---- + +TIP: If you want to fully bypass the auto-configuration for Spring Data Couchbase, +provide your own implementation of +`org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration`. + + + +[[boot-features-ldap]] +=== LDAP +https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol[LDAP] (Lightweight +Directory Access Protocol) is an open, vendor-neutral, industry standard application +protocol for accessing and maintaining distributed directory information services over an +IP network. Spring Boot offers auto-configuration for any compliant LDAP server as well +as support for the embedded in-memory LDAP server from +https://www.ldap.com/unboundid-ldap-sdk-for-java[UnboundID]. + +LDAP abstractions are provided by +https://github.com/spring-projects/spring-data-ldap[Spring Data LDAP]. +There is a `spring-boot-starter-data-ldap` "`Starter`" for collecting the dependencies in +a convenient way. + + + +[[boot-features-ldap-connecting]] +==== Connecting to an LDAP Server +To connect to an LDAP server, make sure you declare a dependency on the +`spring-boot-starter-data-ldap` "`Starter`" or `spring-ldap-core` and then declare the +URLs of your server in your application.properties, as shown in the following example: + +[source,properties,indent=0] +---- + spring.ldap.urls=ldap://myserver:1235 + spring.ldap.username=admin + spring.ldap.password=secret +---- + +If you need to customize connection settings, you can use the `spring.ldap.base` and +`spring.ldap.base-environment` properties. + +An `LdapContextSource` is auto-configured based on these settings. If you need to customize +it, for instance to use a `PooledContextSource`, you can still inject the auto-configured +`LdapContextSource`. Make sure to flag your customized `ContextSource` as `@Primary` so +that the auto-configured `LdapTemplate` uses it. + + + +[[boot-features-ldap-spring-data-repositories]] +==== Spring Data LDAP Repositories +Spring Data includes repository support for LDAP. For complete details of Spring +Data LDAP, refer to the +https://docs.spring.io/spring-data/ldap/docs/1.0.x/reference/html/[reference +documentation]. + +You can also inject an auto-configured `LdapTemplate` instance as you would with any +other Spring Bean, as shown in the following example: + + +[source,java,indent=0] +---- + @Component + public class MyBean { + + private final LdapTemplate template; + + @Autowired + public MyBean(LdapTemplate template) { + this.template = template; + } + + // ... + + } +---- + + + +[[boot-features-ldap-embedded]] +==== Embedded In-memory LDAP Server +For testing purposes, Spring Boot supports auto-configuration of an in-memory LDAP server +from https://www.ldap.com/unboundid-ldap-sdk-for-java[UnboundID]. To configure the server, +add a dependency to `com.unboundid:unboundid-ldapsdk` and declare a `base-dn` property, as +follows: + +[source,properties,indent=0] +---- + spring.ldap.embedded.base-dn=dc=spring,dc=io +---- + +[NOTE] +==== +It is possible to define multiple base-dn values, however, since distinguished names +usually contain commas, they must be defined using the correct notation. + +In yaml files, you can use the yaml list notation: + +[source,yaml,indent=0] +---- + spring.ldap.embedded.base-dn: + - dc=spring,dc=io + - dc=pivotal,dc=io +---- + +In properties files, you must include the index as part of the property name: + +[source,properties,indent=0] +---- + spring.ldap.embedded.base-dn[0]=dc=spring,dc=io + spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io +---- + +==== + +By default, the server starts on a random port and triggers the regular LDAP support. +There is no need to specify a `spring.ldap.urls` property. + +If there is a `schema.ldif` file on your classpath, it is used to initialize the server. +If you want to load the initialization script from a different resource, you can also use +the `spring.ldap.embedded.ldif` property. + +By default, a standard schema is used to validate `LDIF` files. You can turn off +validation altogether by setting the `spring.ldap.embedded.validation.enabled` property. +If you have custom attributes, you can use `spring.ldap.embedded.validation.schema` to +define your custom attribute types or object classes. + + + +[[boot-features-influxdb]] +=== InfluxDB +https://www.influxdata.com/[InfluxDB] is an open-source time series database optimized +for fast, high-availability storage and retrieval of time series data in fields such as +operations monitoring, application metrics, Internet-of-Things sensor data, and real-time +analytics. + + + +[[boot-features-connecting-to-influxdb]] +==== Connecting to InfluxDB +Spring Boot auto-configures an `InfluxDB` instance, provided the `influxdb-java` client +is on the classpath and the URL of the database is set, as shown in the following +example: + +[source,properties,indent=0] +---- + spring.influx.url=https://172.0.0.1:8086 +---- + +If the connection to InfluxDB requires a user and password, you can set the +`spring.influx.user` and `spring.influx.password` properties accordingly. + +InfluxDB relies on OkHttp. If you need to tune the http client `InfluxDB` uses behind the +scenes, you can register an `InfluxDbOkHttpClientBuilderProvider` bean. + + + +[[boot-features-caching]] +== Caching +The Spring Framework provides support for transparently adding caching to an application. +At its core, the abstraction applies caching to methods, thus reducing the number of +executions based on the information available in the cache. The caching logic is applied +transparently, without any interference to the invoker. Spring Boot auto-configures the +cache infrastructure as long as caching support is enabled via the `@EnableCaching` +annotation. + +NOTE: Check the {spring-reference}integration.html#cache[relevant section] of the Spring +Framework reference for more details. + +In a nutshell, adding caching to an operation of your service is as easy as adding the +relevant annotation to its method, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.cache.annotation.Cacheable; + import org.springframework.stereotype.Component; + + @Component + public class MathService { + + @Cacheable("piDecimals") + public int computePiDecimal(int i) { + // ... + } + + } +---- + +This example demonstrates the use of caching on a potentially costly operation. Before +invoking `computePiDecimal`, the abstraction looks for an entry in the `piDecimals` cache +that matches the `i` argument. If an entry is found, the content in the cache is +immediately returned to the caller, and the method is not invoked. Otherwise, the method +is invoked, and the cache is updated before returning the value. + +CAUTION: You can also use the standard JSR-107 (JCache) annotations (such as +`@CacheResult`) transparently. However, we strongly advise you to not mix and match the +Spring Cache and JCache annotations. + +If you do not add any specific cache library, Spring Boot auto-configures a +<> that uses concurrent maps in +memory. When a cache is required (such as `piDecimals` in the preceding example), this +provider creates it for you. The simple provider is not really recommended for +production usage, but it is great for getting started and making sure that you understand +the features. When you have made up your mind about the cache provider to use, please +make sure to read its documentation to figure out how to configure the caches that your +application uses. Nearly all providers require you to explicitly configure every cache +that you use in the application. Some offer a way to customize the default caches defined +by the `spring.cache.cache-names` property. + +TIP: It is also possible to transparently +{spring-reference}integration.html#cache-annotations-put[update] or +{spring-reference}integration.html#cache-annotations-evict[evict] data from the cache. + + + +[[boot-features-caching-provider]] +=== Supported Cache Providers +The cache abstraction does not provide an actual store and relies on abstraction +materialized by the `org.springframework.cache.Cache` and +`org.springframework.cache.CacheManager` interfaces. + +If you have not defined a bean of type `CacheManager` or a `CacheResolver` named +`cacheResolver` (see +{spring-javadoc}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`]), +Spring Boot tries to detect the following providers (in the indicated order): + +. <> +. <> (EhCache 3, Hazelcast, + Infinispan, and others) +. <> +. <> +. <> +. <> +. <> +. <> +. <> + +TIP: It is also possible to _force_ a particular cache provider by setting the +`spring.cache.type` property. Use this property if you need to +<> in certain environment +(such as tests). + +TIP: Use the `spring-boot-starter-cache` "`Starter`" to quickly add basic caching +dependencies. The starter brings in `spring-context-support`. If you add dependencies +manually, you must include `spring-context-support` in order to use the JCache, +EhCache 2.x, or Caffeine support. + +If the `CacheManager` is auto-configured by Spring Boot, you can further tune its +configuration before it is fully initialized by exposing a bean that implements the +`CacheManagerCustomizer` interface. The following example sets a flag to say that null +values should be passed down to the underlying map: + +[source,java,indent=0] +---- + @Bean + public CacheManagerCustomizer cacheManagerCustomizer() { + return new CacheManagerCustomizer() { + @Override + public void customize(ConcurrentMapCacheManager cacheManager) { + cacheManager.setAllowNullValues(false); + } + }; + } +---- + +[NOTE] +==== +In the preceding example, an auto-configured `ConcurrentMapCacheManager` is expected. If +that is not the case (either you provided your own config or a different cache provider +was auto-configured), the customizer is not invoked at all. You can have as many +customizers as you want, and you can also order them by using `@Order` or `Ordered`. +==== + + + +[[boot-features-caching-provider-generic]] +==== Generic +Generic caching is used if the context defines _at least_ one +`org.springframework.cache.Cache` bean. A `CacheManager` wrapping all beans of that type +is created. + + + +[[boot-features-caching-provider-jcache]] +==== JCache (JSR-107) +https://jcp.org/en/jsr/detail?id=107[JCache] is bootstrapped through the presence of a +`javax.cache.spi.CachingProvider` on the classpath (that is, a JSR-107 compliant caching +library exists on the classpath), and the `JCacheCacheManager` is provided by the +`spring-boot-starter-cache` "`Starter`". Various compliant libraries are available, and +Spring Boot provides dependency management for Ehcache 3, Hazelcast, and Infinispan. Any +other compliant library can be added as well. + +It might happen that more than one provider is present, in which case the provider must +be explicitly specified. Even if the JSR-107 standard does not enforce a standardized way +to define the location of the configuration file, Spring Boot does its best to +accommodate setting a cache with implementation details, as shown in the following +example: + +[source,properties,indent=0] +---- + # Only necessary if more than one provider is present + spring.cache.jcache.provider=com.acme.MyCachingProvider + spring.cache.jcache.config=classpath:acme.xml +---- + +NOTE: When a cache library offers both a native implementation and JSR-107 support, +Spring Boot prefers the JSR-107 support, so that the same features are available if you +switch to a different JSR-107 implementation. + +TIP: Spring Boot has <>. If a +single `HazelcastInstance` is available, it is automatically reused for the +`CacheManager` as well, unless the `spring.cache.jcache.config` property is specified. + +There are two ways to customize the underlying `javax.cache.cacheManager`: + +* Caches can be created on startup by setting the `spring.cache.cache-names` property. If +a custom `javax.cache.configuration.Configuration` bean is defined, it is used to +customize them. +* `org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer` beans are +invoked with the reference of the `CacheManager` for full customization. + +TIP: If a standard `javax.cache.CacheManager` bean is defined, it is wrapped +automatically in an `org.springframework.cache.CacheManager` implementation that the +abstraction expects. No further customization is applied to it. + + + +[[boot-features-caching-provider-ehcache2]] +==== EhCache 2.x +https://www.ehcache.org/[EhCache] 2.x is used if a file named `ehcache.xml` can be found at +the root of the classpath. If EhCache 2.x is found, the `EhCacheCacheManager` provided by +the `spring-boot-starter-cache` "`Starter`" is used to bootstrap the cache manager. An +alternate configuration file can be provided as well, as shown in the following example: + +[source,properties,indent=0] +---- + spring.cache.ehcache.config=classpath:config/another-config.xml +---- + + + +[[boot-features-caching-provider-hazelcast]] +==== Hazelcast + +Spring Boot has <>. If a +`HazelcastInstance` has been auto-configured, it is automatically wrapped in a +`CacheManager`. + + + +[[boot-features-caching-provider-infinispan]] +==== Infinispan +https://infinispan.org/[Infinispan] has no default configuration file location, so it must +be specified explicitly. Otherwise, the default bootstrap is used. + +[source,properties,indent=0] +---- + spring.cache.infinispan.config=infinispan.xml +---- + +Caches can be created on startup by setting the `spring.cache.cache-names` property. If a +custom `ConfigurationBuilder` bean is defined, it is used to customize the caches. + +[NOTE] +==== +The support of Infinispan in Spring Boot is restricted to the embedded mode and is quite +basic. If you want more options, you should use the official Infinispan Spring Boot +starter instead. See +https://github.com/infinispan/infinispan-spring-boot[Infinispan's documentation] for more +details. +==== + + +[[boot-features-caching-provider-couchbase]] +==== Couchbase +If the https://www.couchbase.com/[Couchbase] Java client and the `couchbase-spring-cache` +implementation are available and Couchbase is <>, a +`CouchbaseCacheManager` is auto-configured. It is also possible to create additional +caches on startup by setting the `spring.cache.cache-names` property. These caches +operate on the `Bucket` that was auto-configured. You can _also_ create additional caches +on another `Bucket` by using the customizer. Assume you need two caches (`cache1` and +`cache2`) on the "main" `Bucket` and one (`cache3`) cache with a custom time to live of 2 +seconds on the "`another`" `Bucket`. You can create the first two caches through +configuration, as follows: + +[source,properties,indent=0] +---- + spring.cache.cache-names=cache1,cache2 +---- + +Then you can define a `@Configuration` class to configure the extra `Bucket` and the +`cache3` cache, as follows: + + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + public class CouchbaseCacheConfiguration { + + private final Cluster cluster; + + public CouchbaseCacheConfiguration(Cluster cluster) { + this.cluster = cluster; + } + + @Bean + public Bucket anotherBucket() { + return this.cluster.openBucket("another", "secret"); + } + + @Bean + public CacheManagerCustomizer cacheManagerCustomizer() { + return c -> { + c.prepareCache("cache3", CacheBuilder.newInstance(anotherBucket()) + .withExpiration(2)); + }; + } + + } +---- + +This sample configuration reuses the `Cluster` that was created through +auto-configuration. + + + +[[boot-features-caching-provider-redis]] +==== Redis +If https://redis.io/[Redis] is available and configured, a `RedisCacheManager` is +auto-configured. It is possible to create additional caches on startup by setting the +`spring.cache.cache-names` property and cache defaults can be configured by using +`spring.cache.redis.*` properties. For instance, the following configuration creates +`cache1` and `cache2` caches with a _time to live_ of 10 minutes: + +[source,properties,indent=0] +---- + spring.cache.cache-names=cache1,cache2 + spring.cache.redis.time-to-live=600000 +---- + +[NOTE] +==== +By default, a key prefix is added so that, if two separate caches use the same +key, Redis does not have overlapping keys and cannot return invalid values. We strongly +recommend keeping this setting enabled if you create your own `RedisCacheManager`. +==== + +TIP: You can take full control of the configuration by adding a `RedisCacheConfiguration` +`@Bean` of your own. This can be useful if you're looking for customizing the +serialization strategy. + + + +[[boot-features-caching-provider-caffeine]] +==== Caffeine +https://github.com/ben-manes/caffeine[Caffeine] is a Java 8 rewrite of Guava's cache that +supersedes support for Guava. If Caffeine is present, a `CaffeineCacheManager` (provided +by the `spring-boot-starter-cache` "`Starter`") is auto-configured. Caches can be created +on startup by setting the `spring.cache.cache-names` property and can be customized by one +of the following (in the indicated order): + +. A cache spec defined by `spring.cache.caffeine.spec` +. A `com.github.benmanes.caffeine.cache.CaffeineSpec` bean is defined +. A `com.github.benmanes.caffeine.cache.Caffeine` bean is defined + +For instance, the following configuration creates `cache1` and `cache2` caches with a +maximum size of 500 and a _time to live_ of 10 minutes + +[source,properties,indent=0] +---- + spring.cache.cache-names=cache1,cache2 + spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s +---- + +If a `com.github.benmanes.caffeine.cache.CacheLoader` bean is defined, it is +automatically associated to the `CaffeineCacheManager`. Since the `CacheLoader` is going +to be associated with _all_ caches managed by the cache manager, it must be defined as +`CacheLoader`. The auto-configuration ignores any other generic type. + + + +[[boot-features-caching-provider-simple]] +==== Simple +If none of the other providers can be found, a simple implementation using a +`ConcurrentHashMap` as the cache store is configured. This is the default if no caching +library is present in your application. By default, caches are created as needed, but you +can restrict the list of available caches by setting the `cache-names` property. For +instance, if you want only `cache1` and `cache2` caches, set the `cache-names` property +as follows: + +[source,properties,indent=0] +---- + spring.cache.cache-names=cache1,cache2 +---- + +If you do so and your application uses a cache not listed, then it fails at runtime when +the cache is needed, but not on startup. This is similar to the way the "real" cache +providers behave if you use an undeclared cache. + + +[[boot-features-caching-provider-none]] +==== None +When `@EnableCaching` is present in your configuration, a suitable cache configuration is +expected as well. If you need to disable caching altogether in certain environments, +force the cache type to `none` to use a no-op implementation, as shown in the following +example: + +[source,properties,indent=0] +---- + spring.cache.type=none +---- + + + +[[boot-features-messaging]] +== Messaging +The Spring Framework provides extensive support for integrating with messaging systems, +from simplified use of the JMS API using `JmsTemplate` to a complete infrastructure to +receive messages asynchronously. Spring AMQP provides a similar feature set for the +Advanced Message Queuing Protocol. Spring Boot also provides auto-configuration +options for `RabbitTemplate` and RabbitMQ. Spring WebSocket natively includes support for +STOMP messaging, and Spring Boot has support for that through starters and a small amount +of auto-configuration. Spring Boot also has support for Apache Kafka. + + + +[[boot-features-jms]] +=== JMS +The `javax.jms.ConnectionFactory` interface provides a standard method of creating a +`javax.jms.Connection` for interacting with a JMS broker. Although Spring needs a +`ConnectionFactory` to work with JMS, you generally need not use it directly yourself and +can instead rely on higher level messaging abstractions. (See the +{spring-reference}integration.html#jms[relevant section] of the Spring Framework +reference documentation for details.) Spring Boot also auto-configures the necessary +infrastructure to send and receive messages. + + + +[[boot-features-activemq]] +==== ActiveMQ Support +When https://activemq.apache.org/[ActiveMQ] is available on the classpath, Spring Boot can +also configure a `ConnectionFactory`. If the broker is present, an embedded broker is +automatically started and configured (provided no broker URL is specified through +configuration). + +NOTE: If you use `spring-boot-starter-activemq`, the necessary dependencies to connect or +embed an ActiveMQ instance are provided, as is the Spring infrastructure to integrate with +JMS. + +ActiveMQ configuration is controlled by external configuration properties in +`+spring.activemq.*+`. For example, you might declare the following section in +`application.properties`: + +[source,properties,indent=0] +---- + spring.activemq.broker-url=tcp://192.168.1.210:9876 + spring.activemq.user=admin + spring.activemq.password=secret +---- + +By default, a `CachingConnectionFactory` wraps the native `ConnectionFactory` with +sensible settings that you can control by external configuration properties in +`+spring.jms.*+`: + +[source,properties,indent=0] +---- + spring.jms.cache.session-cache-size=5 +---- + +If you'd rather use native pooling, you can do so by adding a dependency to +`org.messaginghub:pooled-jms` and configuring the `JmsPoolConnectionFactory` accordingly, +as shown in the following example: + +[source,properties,indent=0] +---- + spring.activemq.pool.enabled=true + spring.activemq.pool.max-connections=50 +---- + +TIP: See +{sc-spring-boot-autoconfigure}/jms/activemq/ActiveMQProperties.{sc-ext}[`ActiveMQProperties`] +for more of the supported options. You can also register an arbitrary number of beans +that implement `ActiveMQConnectionFactoryCustomizer` for more advanced customizations. + +By default, ActiveMQ creates a destination if it does not yet exist so that destinations +are resolved against their provided names. + + + +[[boot-features-artemis]] +==== Artemis Support +Spring Boot can auto-configure a `ConnectionFactory` when it detects that +https://activemq.apache.org/artemis/[Artemis] is available on the classpath. If the broker +is present, an embedded broker is automatically started and configured (unless the mode +property has been explicitly set). The supported modes are `embedded` (to make explicit +that an embedded broker is required and that an error should occur if the broker is not +available on the classpath) and `native` (to connect to a broker using the `netty` +transport protocol). When the latter is configured, Spring Boot configures a +`ConnectionFactory` that connects to a broker running on the local machine with the +default settings. + +NOTE: If you use `spring-boot-starter-artemis`, the necessary dependencies to +connect to an existing Artemis instance are provided, as well as the Spring +infrastructure to integrate with JMS. Adding `org.apache.activemq:artemis-jms-server` to +your application lets you use embedded mode. + +Artemis configuration is controlled by external configuration properties in +`+spring.artemis.*+`. For example, you might declare the following section in +`application.properties`: + +[source,properties,indent=0] +---- + spring.artemis.mode=native + spring.artemis.host=192.168.1.210 + spring.artemis.port=9876 + spring.artemis.user=admin + spring.artemis.password=secret +---- + +When embedding the broker, you can choose if you want to enable persistence and list the +destinations that should be made available. These can be specified as a comma-separated +list to create them with the default options, or you can define bean(s) of type +`org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration` or +`org.apache.activemq.artemis.jms.server.config.TopicConfiguration`, for advanced queue +and topic configurations, respectively. + +By default, a `CachingConnectionFactory` wraps the native `ConnectionFactory` with +sensible settings that you can control by external configuration properties in +`+spring.jms.*+`: + +[source,properties,indent=0] +---- + spring.jms.cache.session-cache-size=5 +---- + +If you'd rather use native pooling, you can do so by adding a dependency to +`org.messaginghub:pooled-jms` and configuring the `JmsPoolConnectionFactory` accordingly, +as shown in the following example: + +[source,properties,indent=0] +---- + spring.artemis.pool.enabled=true + spring.artemis.pool.max-connections=50 +---- + +See +{sc-spring-boot-autoconfigure}/jms/artemis/ArtemisProperties.{sc-ext}[`ArtemisProperties`] +for more supported options. + +No JNDI lookup is involved, and destinations are resolved against their names, using +either the `name` attribute in the Artemis configuration or the names provided through +configuration. + + + +[[boot-features-jms-jndi]] +==== Using a JNDI ConnectionFactory +If you are running your application in an application server, Spring Boot tries to +locate a JMS `ConnectionFactory` by using JNDI. By default, the `java:/JmsXA` and +`java:/XAConnectionFactory` location are checked. You can use the `spring.jms.jndi-name` +property if you need to specify an alternative location, as shown in the following +example: + +[source,properties,indent=0] +---- + spring.jms.jndi-name=java:/MyConnectionFactory +---- + + + +[[boot-features-using-jms-sending]] +==== Sending a Message +Spring's `JmsTemplate` is auto-configured, and you can autowire it directly into your own +beans, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.jms.core.JmsTemplate; + import org.springframework.stereotype.Component; + + @Component + public class MyBean { + + private final JmsTemplate jmsTemplate; + + @Autowired + public MyBean(JmsTemplate jmsTemplate) { + this.jmsTemplate = jmsTemplate; + } + + // ... + + } +---- + +NOTE: {spring-javadoc}/jms/core/JmsMessagingTemplate.{dc-ext}[`JmsMessagingTemplate`] can +be injected in a similar manner. If a `DestinationResolver` or a `MessageConverter` bean +is defined, it is associated automatically to the auto-configured `JmsTemplate`. + + +[[boot-features-using-jms-receiving]] +==== Receiving a Message +When the JMS infrastructure is present, any bean can be annotated with `@JmsListener` to +create a listener endpoint. If no `JmsListenerContainerFactory` has been defined, a +default one is configured automatically. If a `DestinationResolver` or a +`MessageConverter` beans is defined, it is associated automatically to the default +factory. + +By default, the default factory is transactional. If you run in an infrastructure where a +`JtaTransactionManager` is present, it is associated to the listener container by default. +If not, the `sessionTransacted` flag is enabled. In that latter scenario, you can +associate your local data store transaction to the processing of an incoming message by +adding `@Transactional` on your listener method (or a delegate thereof). This ensures that +the incoming message is acknowledged, once the local transaction has completed. This also +includes sending response messages that have been performed on the same JMS session. + +The following component creates a listener endpoint on the `someQueue` destination: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + @JmsListener(destination = "someQueue") + public void processMessage(String content) { + // ... + } + + } +---- + +TIP: See {spring-javadoc}/jms/annotation/EnableJms.{dc-ext}[the Javadoc of `@EnableJms`] +for more details. + +If you need to create more `JmsListenerContainerFactory` instances or if you want to +override the default, Spring Boot provides a +`DefaultJmsListenerContainerFactoryConfigurer` that you can use to initialize a +`DefaultJmsListenerContainerFactory` with the same settings as the one that is +auto-configured. + +For instance, the following example exposes another factory that uses a specific +`MessageConverter`: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + static class JmsConfiguration { + + @Bean + public DefaultJmsListenerContainerFactory myFactory( + DefaultJmsListenerContainerFactoryConfigurer configurer) { + DefaultJmsListenerContainerFactory factory = + new DefaultJmsListenerContainerFactory(); + configurer.configure(factory, connectionFactory()); + factory.setMessageConverter(myMessageConverter()); + return factory; + } + + } +---- + +Then you can use the factory in any `@JmsListener`-annotated method as follows: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + @Component + public class MyBean { + + @JmsListener(destination = "someQueue", **containerFactory="myFactory"**) + public void processMessage(String content) { + // ... + } + + } +---- + + +[[boot-features-amqp]] +=== AMQP +The Advanced Message Queuing Protocol (AMQP) is a platform-neutral, wire-level protocol +for message-oriented middleware. The Spring AMQP project applies core Spring concepts to +the development of AMQP-based messaging solutions. Spring Boot offers several conveniences +for working with AMQP through RabbitMQ, including the `spring-boot-starter-amqp` +"`Starter`". + + + +[[boot-features-rabbitmq]] +==== RabbitMQ support +https://www.rabbitmq.com/[RabbitMQ] is a lightweight, reliable, scalable, and portable +message broker based on the AMQP protocol. Spring uses `RabbitMQ` to communicate through +the AMQP protocol. + +RabbitMQ configuration is controlled by external configuration properties in +`+spring.rabbitmq.*+`. For example, you might declare the following section in +`application.properties`: + +[source,properties,indent=0] +---- + spring.rabbitmq.host=localhost + spring.rabbitmq.port=5672 + spring.rabbitmq.username=admin + spring.rabbitmq.password=secret +---- + +If a `ConnectionNameStrategy` bean exists in the context, it will be automatically used to +name connections created by the auto-configured `ConnectionFactory`. See +{sc-spring-boot-autoconfigure}/amqp/RabbitProperties.{sc-ext}[`RabbitProperties`] for more +of the supported options. + +TIP: See +https://spring.io/blog/2010/06/14/understanding-amqp-the-protocol-used-by-rabbitmq/[Understanding +AMQP, the protocol used by RabbitMQ] for more details. + + + +[[boot-features-using-amqp-sending]] +==== Sending a Message +Spring's `AmqpTemplate` and `AmqpAdmin` are auto-configured, and you can autowire them +directly into your own beans, as shown in the following example: + +[source,java,indent=0] +---- + import org.springframework.amqp.core.AmqpAdmin; + import org.springframework.amqp.core.AmqpTemplate; + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.stereotype.Component; + + @Component + public class MyBean { + + private final AmqpAdmin amqpAdmin; + private final AmqpTemplate amqpTemplate; + + @Autowired + public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) { + this.amqpAdmin = amqpAdmin; + this.amqpTemplate = amqpTemplate; + } + + // ... + + } +---- + +NOTE: {spring-amqp-javadoc}/rabbit/core/RabbitMessagingTemplate.{dc-ext}[`RabbitMessagingTemplate`] +can be injected in a similar manner. If a `MessageConverter` bean is defined, it is +associated automatically to the auto-configured `AmqpTemplate`. + +If necessary, any `org.springframework.amqp.core.Queue` that is defined as a bean is +automatically used to declare a corresponding queue on the RabbitMQ instance. + +To retry operations, you can enable retries on the `AmqpTemplate` (for example, in the +event that the broker connection is lost): + +[source,properties,indent=0] +---- + spring.rabbitmq.template.retry.enabled=true + spring.rabbitmq.template.retry.initial-interval=2s +---- + +Retries are disabled by default. You can also customize the `RetryTemplate` +programmatically by declaring a `RabbitRetryTemplateCustomizer` bean. + + + +[[boot-features-using-amqp-receiving]] +==== Receiving a Message +When the Rabbit infrastructure is present, any bean can be annotated with +`@RabbitListener` to create a listener endpoint. If no `RabbitListenerContainerFactory` +has been defined, a default `SimpleRabbitListenerContainerFactory` is automatically +configured and you can switch to a direct container using the +`spring.rabbitmq.listener.type` property. If a `MessageConverter` or a `MessageRecoverer` +bean is defined, it is automatically associated with the default factory. + +The following sample component creates a listener endpoint on the `someQueue` queue: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + @RabbitListener(queues = "someQueue") + public void processMessage(String content) { + // ... + } + + } +---- + +TIP: See {spring-amqp-javadoc}/rabbit/annotation/EnableRabbit.{dc-ext}[the Javadoc of +`@EnableRabbit`] for more details. + +If you need to create more `RabbitListenerContainerFactory` instances or if you want to +override the default, Spring Boot provides a +`SimpleRabbitListenerContainerFactoryConfigurer` and a +`DirectRabbitListenerContainerFactoryConfigurer` that you can use to initialize a +`SimpleRabbitListenerContainerFactory` and a `DirectRabbitListenerContainerFactory` with +the same settings as the factories used by the auto-configuration. + +TIP: It does not matter which container type you chose. Those two beans are exposed by +the auto-configuration. + +For instance, the following configuration class exposes another factory that uses a +specific `MessageConverter`: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + static class RabbitConfiguration { + + @Bean + public SimpleRabbitListenerContainerFactory myFactory( + SimpleRabbitListenerContainerFactoryConfigurer configurer) { + SimpleRabbitListenerContainerFactory factory = + new SimpleRabbitListenerContainerFactory(); + configurer.configure(factory, connectionFactory); + factory.setMessageConverter(myMessageConverter()); + return factory; + } + + } +---- + +Then you can use the factory in any `@RabbitListener`-annotated method, as follows: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + @Component + public class MyBean { + + @RabbitListener(queues = "someQueue", **containerFactory="myFactory"**) + public void processMessage(String content) { + // ... + } + + } +---- + +You can enable retries to handle situations where your listener throws an exception. By +default, `RejectAndDontRequeueRecoverer` is used, but you can define a `MessageRecoverer` +of your own. When retries are exhausted, the message is rejected and either dropped or +routed to a dead-letter exchange if the broker is configured to do so. By default, +retries are disabled. You can also customize the `RetryTemplate` programmatically by +declaring a `RabbitRetryTemplateCustomizer` bean. + +IMPORTANT: By default, if retries are disabled and the listener throws an exception, the +delivery is retried indefinitely. You can modify this behavior in two ways: Set the +`defaultRequeueRejected` property to `false` so that zero re-deliveries are attempted or +throw an `AmqpRejectAndDontRequeueException` to signal the message should be rejected. +The latter is the mechanism used when retries are enabled and the maximum number of +delivery attempts is reached. + + + +[[boot-features-kafka]] +=== Apache Kafka Support +https://kafka.apache.org/[Apache Kafka] is supported by providing auto-configuration of +the `spring-kafka` project. + +Kafka configuration is controlled by external configuration properties in +`spring.kafka.*`. For example, you might declare the following section in +`application.properties`: + +[source,properties,indent=0] +---- + spring.kafka.bootstrap-servers=localhost:9092 + spring.kafka.consumer.group-id=myGroup +---- + +TIP: To create a topic on startup, add a bean of type `NewTopic`. If the topic already +exists, the bean is ignored. + +See {sc-spring-boot-autoconfigure}/kafka/KafkaProperties.{sc-ext}[`KafkaProperties`] +for more supported options. + + + +[[boot-features-kafka-sending-a-message]] +==== Sending a Message +Spring's `KafkaTemplate` is auto-configured, and you can autowire it directly in your own +beans, as shown in the following example: + +[source,java,indent=0] +---- +@Component +public class MyBean { + + private final KafkaTemplate kafkaTemplate; + + @Autowired + public MyBean(KafkaTemplate kafkaTemplate) { + this.kafkaTemplate = kafkaTemplate; + } + + // ... + +} +---- + +NOTE: If the property `spring.kafka.producer.transaction-id-prefix` is defined, a +`KafkaTransactionManager` is automatically configured. Also, if a `RecordMessageConverter` +bean is defined, it is automatically associated to the auto-configured `KafkaTemplate`. + + +[[boot-features-kafka-receiving-a-message]] +==== Receiving a Message +When the Apache Kafka infrastructure is present, any bean can be annotated with +`@KafkaListener` to create a listener endpoint. If no `KafkaListenerContainerFactory` has +been defined, a default one is automatically configured with keys defined in +`spring.kafka.listener.*`. + +The following component creates a listener endpoint on the `someTopic` topic: + +[source,java,indent=0] +---- + @Component + public class MyBean { + + @KafkaListener(topics = "someTopic") + public void processMessage(String content) { + // ... + } + + } +---- + +If a `KafkaTransactionManager` bean is defined, it is automatically associated to the +container factory. Similarly, if a `ErrorHandler`, `AfterRollbackProcessor` or +`ConsumerAwareRebalanceListener` bean is defined, it is automatically associated to the +default factory. + +Depending on the listener type, a `RecordMessageConverter` or `BatchMessageConverter` bean +is associated to the default factory. If only a `RecordMessageConverter` bean is present +for a batch listener, it is wrapped in a `BatchMessageConverter`. + +TIP: A custom `ChainedKafkaTransactionManager` must be marked `@Primary` as it usually +references the auto-configured `KafkaTransactionManager` bean. + + + +[[boot-features-kafka-streams]] +==== Kafka Streams +Spring for Apache Kafka provides a factory bean to create a `StreamsBuilder` object and +manage the lifecycle of its streams. Spring Boot auto-configures the required +`KafkaStreamsConfiguration` bean as long as `kafka-streams` is on the classpath and Kafka +Streams is enabled via the `@EnableKafkaStreams` annotation. + +Enabling Kafka Streams means that the application id and bootstrap servers must be set. +The former can be configured using `spring.kafka.streams.application-id`, defaulting to +`spring.application.name` if not set. The latter can be set globally or +specifically overridden just for streams. + +Several additional properties are available using dedicated properties; other arbitrary +Kafka properties can be set using the `spring.kafka.streams.properties` namespace. See +also <> for more information. + +To use the factory bean, simply wire `StreamsBuilder` into your `@Bean` as shown in the +following example: + +[source,java,indent=0] +---- +include::{code-examples}/kafka/KafkaStreamsBeanExample.java[tag=configuration] +---- + +By default, the streams managed by the `StreamBuilder` object it creates are started +automatically. You can customize this behaviour using the +`spring.kafka.streams.auto-startup` property. + + + +[[boot-features-kafka-extra-props]] +==== Additional Kafka Properties +The properties supported by auto configuration are shown in +<>. Note that, for the most part, these properties +(hyphenated or camelCase) map directly to the Apache Kafka dotted properties. Refer to the +Apache Kafka documentation for details. + +The first few of these properties apply to all components (producers, consumers, admins, +and streams) but can be +specified at the component level if you wish to use different values. +Apache Kafka designates properties with an importance of HIGH, MEDIUM, or LOW. Spring Boot +auto-configuration supports all HIGH importance properties, some selected MEDIUM and LOW +properties, and any properties that do not have a default value. + +Only a subset of the properties supported by Kafka are available directly through the +`KafkaProperties` class. If you wish to configure the producer or consumer with additional +properties that are not directly supported, use the following properties: + +[source,properties,indent=0] +---- + spring.kafka.properties.prop.one=first + spring.kafka.admin.properties.prop.two=second + spring.kafka.consumer.properties.prop.three=third + spring.kafka.producer.properties.prop.four=fourth + spring.kafka.streams.properties.prop.five=fifth +---- + +This sets the common `prop.one` Kafka property to `first` (applies to producers, +consumers and admins), the `prop.two` admin property to `second`, the `prop.three` +consumer property to `third`, the `prop.four` producer property to `fourth` and the +`prop.five` streams property to `fifth`. + +You can also configure the Spring Kafka `JsonDeserializer` as follows: + +[source,properties,indent=0] +---- +spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer +spring.kafka.consumer.properties.spring.json.value.default.type=com.example.Invoice +spring.kafka.consumer.properties.spring.json.trusted.packages=com.example,org.acme +---- + +Similarly, you can disable the `JsonSerializer` default behavior of sending type +information in headers: + +[source,properties,indent=0] +---- +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer +spring.kafka.producer.properties.spring.json.add.type.headers=false +---- + +IMPORTANT: Properties set in this way override any configuration item that Spring Boot +explicitly supports. + +[[boot-features-resttemplate]] +== Calling REST Services with `RestTemplate` +If you need to call remote REST services from your application, you can use the Spring +Framework's {spring-javadoc}/web/client/RestTemplate.html[`RestTemplate`] class. Since +`RestTemplate` instances often need to be customized before being used, Spring Boot does +not provide any single auto-configured `RestTemplate` bean. It does, however, +auto-configure a `RestTemplateBuilder`, which can be used to create `RestTemplate` +instances when needed. The auto-configured `RestTemplateBuilder` ensures that sensible +`HttpMessageConverters` are applied to `RestTemplate` instances. + +The following code shows a typical example: + +[source,java,indent=0] +---- + @Service + public class MyService { + + private final RestTemplate restTemplate; + + public MyService(RestTemplateBuilder restTemplateBuilder) { + this.restTemplate = restTemplateBuilder.build(); + } + + public Details someRestCall(String name) { + return this.restTemplate.getForObject("/{name}/details", Details.class, name); + } + + } +---- + +TIP: `RestTemplateBuilder` includes a number of useful methods that can be used to +quickly configure a `RestTemplate`. For example, to add BASIC auth support, you can use +`builder.basicAuthentication("user", "password").build()`. + + + +[[boot-features-resttemplate-customization]] +=== RestTemplate Customization +There are three main approaches to `RestTemplate` customization, depending on how broadly +you want the customizations to apply. + +To make the scope of any customizations as narrow as possible, inject the auto-configured +`RestTemplateBuilder` and then call its methods as required. Each method call returns a +new `RestTemplateBuilder` instance, so the customizations only affect this use of the +builder. + +To make an application-wide, additive customization, use a `RestTemplateCustomizer` bean. +All such beans are automatically registered with the auto-configured `RestTemplateBuilder` +and are applied to any templates that are built with it. + +The following example shows a customizer that configures the use of a proxy for all hosts +except `192.168.0.5`: + +[source,java,indent=0] +---- +include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[tag=customizer] +---- + +Finally, the most extreme (and rarely used) option is to create your own +`RestTemplateBuilder` bean. Doing so switches off the auto-configuration of a +`RestTemplateBuilder` and prevents any `RestTemplateCustomizer` beans from being used. + + + +[[boot-features-webclient]] +== Calling REST Services with `WebClient` +If you have Spring WebFlux on your classpath, you can also choose to use `WebClient` to +call remote REST services. Compared to `RestTemplate`, this client has a more functional +feel and is fully reactive. You can learn more about the `WebClient` in the dedicated +{spring-reference}web-reactive.html#webflux-client[section in the Spring Framework docs]. + +Spring Boot creates and pre-configures a `WebClient.Builder` for you; it is strongly +advised to inject it in your components and use it to create `WebClient` instances. +Spring Boot is configuring that builder to share HTTP resources, reflect codecs +setup in the same fashion as the server ones (see +<>), and more. + +The following code shows a typical example: + +[source,java,indent=0] +---- + @Service + public class MyService { + + private final WebClient webClient; + + public MyService(WebClient.Builder webClientBuilder) { + this.webClient = webClientBuilder.baseUrl("https://example.org").build(); + } + + public Mono
someRestCall(String name) { + return this.webClient.get().uri("/{name}/details", name) + .retrieve().bodyToMono(Details.class); + } + + } +---- + + + +[[boot-features-webclient-runtime]] +=== WebClient Runtime +Spring Boot will auto-detect which `ClientHttpConnector` to use to drive `WebClient`, +depending on the libraries available on the application classpath. For now, Reactor +Netty and Jetty RS client are supported. + +The `spring-boot-starter-webflux` starter depends on `io.projectreactor.netty:reactor-netty` +by default, which brings both server and client implementations. If you choose to use Jetty +as a reactive server instead, you should add a dependency on the Jetty Reactive HTTP +client library, `org.eclipse.jetty:jetty-reactive-httpclient`. Using the same technology +for server and client has it advantages, as it will automatically share HTTP resources +between client and server. + +Developers can override the resource configuration for Jetty and Reactor Netty by providing +a custom `ReactorResourceFactory` or `JettyResourceFactory` bean - this will be applied to +both clients and servers. + +If you wish to override that choice for the client, you can define your own +`ClientHttpConnector` bean and have full control over the client configuration. + +You can learn more about the +{spring-reference}web-reactive.html#webflux-client-builder[`WebClient` configuration +options in the Spring Framework reference documentation]. + + + +[[boot-features-webclient-customization]] +=== WebClient Customization +There are three main approaches to `WebClient` customization, depending on how broadly you +want the customizations to apply. + +To make the scope of any customizations as narrow as possible, inject the auto-configured +`WebClient.Builder` and then call its methods as required. `WebClient.Builder` instances +are stateful: Any change on the builder is reflected in all clients subsequently created +with it. If you want to create several clients with the same builder, you can also +consider cloning the builder with `WebClient.Builder other = builder.clone();`. + +To make an application-wide, additive customization to all `WebClient.Builder` instances, +you can declare `WebClientCustomizer` beans and change the `WebClient.Builder` locally at +the point of injection. + +Finally, you can fall back to the original API and use `WebClient.create()`. In that case, +no auto-configuration or `WebClientCustomizer` is applied. + + + +[[boot-features-validation]] +== Validation +The method validation feature supported by Bean Validation 1.1 is automatically enabled +as long as a JSR-303 implementation (such as Hibernate validator) is on the classpath. +This lets bean methods be annotated with `javax.validation` constraints on their +parameters and/or on their return value. Target classes with such annotated methods need +to be annotated with the `@Validated` annotation at the type level for their methods to +be searched for inline constraint annotations. + +For instance, the following service triggers the validation of the first argument, making +sure its size is between 8 and 10: + +[source,java,indent=0] +---- + @Service + @Validated + public class MyBean { + + public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code, + Author author) { + ... + } + + } +---- + + + +[[boot-features-email]] +== Sending Email +The Spring Framework provides an easy abstraction for sending email by using the +`JavaMailSender` interface, and Spring Boot provides auto-configuration for it as well as +a starter module. + +TIP: See the {spring-reference}integration.html#mail[reference documentation] for a +detailed explanation of how you can use `JavaMailSender`. + +If `spring.mail.host` and the relevant libraries (as defined by +`spring-boot-starter-mail`) are available, a default `JavaMailSender` is created if none +exists. The sender can be further customized by configuration items from the +`spring.mail` namespace. See +{sc-spring-boot-autoconfigure}/mail/MailProperties.{sc-ext}[`MailProperties`] for more +details. + +In particular, certain default timeout values are infinite, and you may want to change +that to avoid having a thread blocked by an unresponsive mail server, as shown in the +following example: + +[source,properties,indent=0] +---- + spring.mail.properties.mail.smtp.connectiontimeout=5000 + spring.mail.properties.mail.smtp.timeout=3000 + spring.mail.properties.mail.smtp.writetimeout=5000 +---- + +It is also possible to configure a `JavaMailSender` with an existing `Session` from JNDI: + +[source,properties,indent=0] +---- + spring.mail.jndi-name=mail/Session +---- + +When a `jndi-name` is set, it takes precedence over all other Session-related settings. + + + +[[boot-features-jta]] +== Distributed Transactions with JTA +Spring Boot supports distributed JTA transactions across multiple XA resources by using +either an https://www.atomikos.com/[Atomikos] or https://github.com/bitronix/btm[Bitronix] +embedded transaction manager. JTA transactions are also supported when deploying to a +suitable Java EE Application Server. + +When a JTA environment is detected, Spring's `JtaTransactionManager` is used to manage +transactions. Auto-configured JMS, DataSource, and JPA beans are upgraded to support XA +transactions. You can use standard Spring idioms, such as `@Transactional`, to participate +in a distributed transaction. If you are within a JTA environment and still want to use +local transactions, you can set the `spring.jta.enabled` property to `false` to disable +the JTA auto-configuration. + + + +[[boot-features-jta-atomikos]] +=== Using an Atomikos Transaction Manager +https://www.atomikos.com/[Atomikos] is a popular open source transaction manager which can +be embedded into your Spring Boot application. You can use the +`spring-boot-starter-jta-atomikos` Starter to pull in the appropriate Atomikos libraries. +Spring Boot auto-configures Atomikos and ensures that appropriate `depends-on` settings +are applied to your Spring beans for correct startup and shutdown ordering. + +By default, Atomikos transaction logs are written to a `transaction-logs` directory in +your application's home directory (the directory in which your application jar file +resides). You can customize the location of this directory by setting a +`spring.jta.log-dir` property in your `application.properties` file. Properties starting +with `spring.jta.atomikos.properties` can also be used to customize the Atomikos +`UserTransactionServiceImp`. See the +{dc-spring-boot}/jta/atomikos/AtomikosProperties.{dc-ext}[`AtomikosProperties` Javadoc] +for complete details. + +NOTE: To ensure that multiple transaction managers can safely coordinate the same +resource managers, each Atomikos instance must be configured with a unique ID. By default, +this ID is the IP address of the machine on which Atomikos is running. To ensure +uniqueness in production, you should configure the `spring.jta.transaction-manager-id` +property with a different value for each instance of your application. + + + +[[boot-features-jta-bitronix]] +=== Using a Bitronix Transaction Manager +https://github.com/bitronix/btm[Bitronix] is a popular open-source JTA transaction +manager implementation. You can use the `spring-boot-starter-jta-bitronix` starter to add +the appropriate Bitronix dependencies to your project. As with Atomikos, Spring Boot +automatically configures Bitronix and post-processes your beans to ensure that startup and +shutdown ordering is correct. + +By default, Bitronix transaction log files (`part1.btm` and `part2.btm`) are written to +a `transaction-logs` directory in your application home directory. You can customize the +location of this directory by setting the `spring.jta.log-dir` property. Properties +starting with `spring.jta.bitronix.properties` are also bound to the +`bitronix.tm.Configuration` bean, allowing for complete customization. See the +https://github.com/bitronix/btm/wiki/Transaction-manager-configuration[Bitronix +documentation] for details. + +NOTE: To ensure that multiple transaction managers can safely coordinate the same +resource managers, each Bitronix instance must be configured with a unique ID. By default, +this ID is the IP address of the machine on which Bitronix is running. To ensure +uniqueness in production, you should configure the `spring.jta.transaction-manager-id` +property with a different value for each instance of your application. + + + +[[boot-features-jta-javaee]] +=== Using a Java EE Managed Transaction Manager +If you package your Spring Boot application as a `war` or `ear` file and deploy it to a +Java EE application server, you can use your application server's built-in transaction +manager. Spring Boot tries to auto-configure a transaction manager by looking at common +JNDI locations (`java:comp/UserTransaction`, `java:comp/TransactionManager`, and so on). +If you use a transaction service provided by your application server, you generally also +want to ensure that all resources are managed by the server and exposed over JNDI. Spring +Boot tries to auto-configure JMS by looking for a `ConnectionFactory` at the JNDI path +(`java:/JmsXA` or `java:/XAConnectionFactory`), and you can use the +<> +to configure your `DataSource`. + + + +[[boot-features-jta-mixed-jms]] +=== Mixing XA and Non-XA JMS Connections +When using JTA, the primary JMS `ConnectionFactory` bean is XA-aware and participates +in distributed transactions. In some situations, you might want to process certain JMS +messages by using a non-XA `ConnectionFactory`. For example, your JMS processing logic +might take longer than the XA timeout. + +If you want to use a non-XA `ConnectionFactory`, you can inject the +`nonXaJmsConnectionFactory` bean rather than the `@Primary` `jmsConnectionFactory` bean. +For consistency, the `jmsConnectionFactory` bean is also provided by using the bean alias +`xaJmsConnectionFactory`. + +The following example shows how to inject `ConnectionFactory` instances: + +[source,java,indent=0,subs="verbatim,quotes,attributes"] +---- + // Inject the primary (XA aware) ConnectionFactory + @Autowired + private ConnectionFactory defaultConnectionFactory; + + // Inject the XA aware ConnectionFactory (uses the alias and injects the same as above) + @Autowired + @Qualifier("xaJmsConnectionFactory") + private ConnectionFactory xaConnectionFactory; + + // Inject the non-XA aware ConnectionFactory + @Autowired + @Qualifier("nonXaJmsConnectionFactory") + private ConnectionFactory nonXaConnectionFactory; +---- + + + +[[boot-features-jta-supporting-alternative-embedded]] +=== Supporting an Alternative Embedded Transaction Manager +The {sc-spring-boot}/jms/XAConnectionFactoryWrapper.{sc-ext}[`XAConnectionFactoryWrapper`] +and {sc-spring-boot}/jdbc/XADataSourceWrapper.{sc-ext}[`XADataSourceWrapper`] interfaces +can be used to support alternative embedded transaction managers. The interfaces are +responsible for wrapping `XAConnectionFactory` and `XADataSource` beans and exposing them +as regular `ConnectionFactory` and `DataSource` beans, which transparently enroll in the +distributed transaction. DataSource and JMS auto-configuration use JTA variants, provided +you have a `JtaTransactionManager` bean and appropriate XA wrapper beans registered +within your `ApplicationContext`. + +The {sc-spring-boot}/jta/bitronix/BitronixXAConnectionFactoryWrapper.{sc-ext}[BitronixXAConnectionFactoryWrapper] +and {sc-spring-boot}/jta/bitronix/BitronixXADataSourceWrapper.{sc-ext}[BitronixXADataSourceWrapper] +provide good examples of how to write XA wrappers. + + + +[[boot-features-hazelcast]] +== Hazelcast + +If https://hazelcast.com/[Hazelcast] is on the classpath and a suitable configuration is +found, Spring Boot auto-configures a `HazelcastInstance` that you can inject in your +application. + +If you define a `com.hazelcast.config.Config` bean, Spring Boot uses that. If your +configuration defines an instance name, Spring Boot tries to locate an existing instance +rather than creating a new one. + +You could also specify the Hazelcast configuration file to use through configuration, as +shown in the following example: + +[source,properties,indent=0] +---- + spring.hazelcast.config=classpath:config/my-hazelcast.xml +---- + +Otherwise, Spring Boot tries to find the Hazelcast configuration from the default +locations: `hazelcast.xml` in the working directory or at the root of the classpath, or +a `.yaml` counterpart in the same locations. We also check if the `hazelcast.config` +system property is set. See the +https://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for +more details. + +If `hazelcast-client` is present on the classpath, Spring Boot first attempts to create a +client by checking the following configuration options: + +* The presence of a `com.hazelcast.client.config.ClientConfig` bean. +* A configuration file defined by the `spring.hazelcast.config` property. +* The presence of the `hazelcast.client.config` system property. +* A `hazelcast-client.xml` in the working directory or at the root of the classpath. +* A `hazelcast-client.yaml` in the working directory or at the root of the classpath. + +NOTE: Spring Boot also has +<>. If +caching is enabled, the `HazelcastInstance` is automatically wrapped in a `CacheManager` +implementation. + + + +[[boot-features-quartz]] +== Quartz Scheduler +Spring Boot offers several conveniences for working with the +https://www.quartz-scheduler.org/[Quartz scheduler], including the +`spring-boot-starter-quartz` "`Starter`". If Quartz is available, a `Scheduler` is +auto-configured (through the `SchedulerFactoryBean` abstraction). + +Beans of the following types are automatically picked up and associated with the +`Scheduler`: + +* `JobDetail`: defines a particular Job. `JobDetail` instances can be built with the +`JobBuilder` API. +* `Calendar`. +* `Trigger`: defines when a particular job is triggered. + +By default, an in-memory `JobStore` is used. However, it is possible to configure a +JDBC-based store if a `DataSource` bean is available in your application and if the +`spring.quartz.job-store-type` property is configured accordingly, as shown in the +following example: + +[source,properties,indent=0] +---- + spring.quartz.job-store-type=jdbc +---- + +When the JDBC store is used, the schema can be initialized on startup, as shown in the +following example: + +[source,properties,indent=0] +---- + spring.quartz.jdbc.initialize-schema=always +---- + +WARNING: By default, the database is detected and initialized by using the standard scripts +provided with the Quartz library. These scripts drop existing tables, deleting all triggers +on every restart. It is also possible to provide a custom script by setting the +`spring.quartz.jdbc.schema` property. + +To have Quartz use a `DataSource` other than the application's main `DataSource`, declare +a `DataSource` bean, annotating its `@Bean` method with `@QuartzDataSource`. Doing so +ensures that the Quartz-specific `DataSource` is used by both the `SchedulerFactoryBean` +and for schema initialization. + +By default, jobs created by configuration will not overwrite already registered jobs that +have been read from a persistent job store. To enable overwriting existing job definitions +set the `spring.quartz.overwrite-existing-jobs` property. + +Quartz Scheduler configuration can be customized using `spring.quartz` properties and +`SchedulerFactoryBeanCustomizer` beans, which allow programmatic `SchedulerFactoryBean` +customization. Advanced Quartz configuration properties can be customized using +`spring.quartz.properties.*`. + +NOTE: In particular, an `Executor` bean is not associated with the scheduler as Quartz +offers a way to configure the scheduler via `spring.quartz.properties`. If you need +to customize the task executor, consider implementing `SchedulerFactoryBeanCustomizer`. + +Jobs can define setters to inject data map properties. Regular beans can also be injected +in a similar manner, as shown in the following example: + +[source,java,indent=0] +---- + public class SampleJob extends QuartzJobBean { + + private MyService myService; + + private String name; + + // Inject "MyService" bean + public void setMyService(MyService myService) { ... } + + // Inject the "name" job data property + public void setName(String name) { ... } + + @Override + protected void executeInternal(JobExecutionContext context) + throws JobExecutionException { + ... + } + + } +---- + + + +[[boot-features-task-execution-scheduling]] +== Task Execution and Scheduling +In the absence of an `Executor` bean in the context, Spring Boot auto-configures a +`ThreadPoolTaskExecutor` with sensible defaults that can be automatically associated to +asynchronous task execution (`@EnableAsync`) and Spring MVC asynchronous request +processing. + +[TIP] +==== +If you have defined a custom `Executor` in the context, regular task execution (i.e. +`@EnableAsync`) will use it transparently but the Spring MVC support will not be +configured as it requires an `AsyncTaskExecutor` implementation (named +`applicationTaskExecutor`). Depending on your target arrangement, you could change your +`Executor` into a `ThreadPoolTaskExecutor` or define both a `ThreadPoolTaskExecutor` and +an `AsyncConfigurer` wrapping your custom `Executor`. + +The auto-configured `TaskExecutorBuilder` allows you to easily create instances that +reproduce what the auto-configuration does by default. +==== + +The thread pool uses 8 core threads that can grow and shrink according to the load. Those +default settings can be fine-tuned using the `spring.task.execution` namespace as shown in +the following example: + +[source,properties,indent=0] +---- + spring.task.execution.pool.max-threads=16 + spring.task.execution.pool.queue-capacity=100 + spring.task.execution.pool.keep-alive=10s +---- + +This changes the thread pool to use a bounded queue so that when the queue is full (100 +tasks), the thread pool increases to maximum 16 threads. Shrinking of the pool is more +aggressive as threads are reclaimed when they are idle for 10 seconds (rather than +60 seconds by default). + +A `ThreadPoolTaskScheduler` can also be auto-configured if need to be associated to +scheduled task execution (`@EnableScheduling`). The thread pool uses one thread by default +and those settings can be fine-tuned using the `spring.task.scheduling` namespace. + +Both a `TaskExecutorBuilder` bean and a `TaskSchedulerBuilder` bean are made available in +the context if a custom executor or scheduler needs to be created. + + + +[[boot-features-integration]] +== Spring Integration +Spring Boot offers several conveniences for working with {spring-integration}[Spring +Integration], including the `spring-boot-starter-integration` "`Starter`". Spring +Integration provides abstractions over messaging and also other transports such as HTTP, +TCP, and others. If Spring Integration is available on your classpath, it is initialized +through the `@EnableIntegration` annotation. + +Spring Boot also configures some features that are triggered by the presence of additional +Spring Integration modules. If `spring-integration-jmx` is also on the classpath, +message processing statistics are published over JMX . If `spring-integration-jdbc` is +available, the default database schema can be created on startup, as shown in the +following line: + +[source,properties,indent=0] +---- + spring.integration.jdbc.initialize-schema=always +---- + +See the +{sc-spring-boot-autoconfigure}/integration/IntegrationAutoConfiguration.{sc-ext}[`IntegrationAutoConfiguration`] +and {sc-spring-boot-autoconfigure}/integration/IntegrationProperties.{sc-ext}[`IntegrationProperties`] +classes for more details. + +By default, if a Micrometer `meterRegistry` bean is present, Spring Integration metrics +will be managed by Micrometer. If you wish to use legacy Spring Integration metrics, add +a `DefaultMetricsFactory` bean to the application context. + + + +[[boot-features-session]] +== Spring Session +Spring Boot provides {spring-session}[Spring Session] auto-configuration for a wide range +of data stores. When building a Servlet web application, the following stores can be +auto-configured: + +* JDBC +* Redis +* Hazelcast +* MongoDB + +When building a reactive web application, the following stores can be auto-configured: + +* Redis +* MongoDB + +If a single Spring Session module is present on the classpath, Spring Boot uses that store +implementation automatically. If you have more than one implementation, you must choose +the {sc-spring-boot-autoconfigure}/session/StoreType.{sc-ext}[`StoreType`] that you wish +to use to store the sessions. For instance, to use JDBC as the back-end store, you can +configure your application as follows: + +[source,properties,indent=0] +---- + spring.session.store-type=jdbc +---- + +TIP: You can disable Spring Session by setting the `store-type` to `none`. + +Each store has specific additional settings. For instance, it is possible to customize +the name of the table for the JDBC store, as shown in the following example: + +[source,properties,indent=0] +---- + spring.session.jdbc.table-name=SESSIONS +---- + +For setting the timeout of the session you can use the `spring.session.timeout` property. +If that property is not set, the auto-configuration falls back to the value of +`server.servlet.session.timeout`. + +[[boot-features-jmx]] +== Monitoring and Management over JMX +Java Management Extensions (JMX) provide a standard mechanism to monitor and manage +applications. Spring Boot exposes the most suitable `MBeanServer` as a bean with an ID of +`mbeanServer`. Any of your beans that are annotated with Spring JMX annotations ( +`@ManagedResource`, `@ManagedAttribute`, or `@ManagedOperation`) are exposed to it. + +If your platform provides a standard `MBeanServer`, Spring Boot will use that and default +to the VM `MBeanServer` if necessary. If all that fails, a new `MBeanServer` will be +created. + +See the +{sc-spring-boot-autoconfigure}/jmx/JmxAutoConfiguration.{sc-ext}[`JmxAutoConfiguration`] +class for more details. + + + +[[boot-features-testing]] +== Testing +Spring Boot provides a number of utilities and annotations to help when testing your +application. Test support is provided by two modules: `spring-boot-test` contains core +items, and `spring-boot-test-autoconfigure` supports auto-configuration for tests. + +Most developers use the `spring-boot-starter-test` "`Starter`", which imports both Spring +Boot test modules as well as JUnit Jupiter, AssertJ, Hamcrest, and a number of other +useful libraries. + +[TIP] +==== +The starter also brings the vintage engine so that you can run both JUnit 4 and JUnit 5 +tests. If you have migrated your tests to JUnit 5, you should exclude JUnit 4 support, as +shown in the following example: + +[source,xml,indent=0,subs="verbatim,quotes,attributes"] +---- + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + +---- +==== + + + +[[boot-features-test-scope-dependencies]] +=== Test Scope Dependencies +The `spring-boot-starter-test` "`Starter`" (in the `test` `scope`) contains +the following provided libraries: + +* https://junit.org/junit5[JUnit 5] (including the vintage engine for backward +compatibility with JUnit 4: The de-facto standard for unit testing Java applications. +* {spring-reference}testing.html#integration-testing[Spring Test] & Spring Boot Test: +Utilities and integration test support for Spring Boot applications. +* https://joel-costigliola.github.io/assertj/[AssertJ]: A fluent assertion library. +* https://github.com/hamcrest/JavaHamcrest[Hamcrest]: A library of matcher objects (also +known as constraints or predicates). +* https://mockito.github.io[Mockito]: A Java mocking framework. +* https://github.com/skyscreamer/JSONassert[JSONassert]: An assertion library for JSON. +* https://github.com/jayway/JsonPath[JsonPath]: XPath for JSON. + +We generally find these common libraries to be useful when writing tests. If these +libraries do not suit your needs, you can add additional test dependencies of your own. + + + +[[boot-features-testing-spring-applications]] +=== Testing Spring Applications +One of the major advantages of dependency injection is that it should make your code +easier to unit test. You can instantiate objects by using the `new` operator without +even involving Spring. You can also use _mock objects_ instead of real dependencies. + +Often, you need to move beyond unit testing and start integration testing (with +a Spring `ApplicationContext`). It is useful to be able to perform integration testing +without requiring deployment of your application or needing to connect to other +infrastructure. + +The Spring Framework includes a dedicated test module for such integration testing. You +can declare a dependency directly to `org.springframework:spring-test` or use the +`spring-boot-starter-test` "`Starter`" to pull it in transitively. + +If you have not used the `spring-test` module before, you should start by reading the +{spring-reference}testing.html#testing[relevant section] of the Spring Framework +reference documentation. + + + +[[boot-features-testing-spring-boot-applications]] +=== Testing Spring Boot Applications +A Spring Boot application is a Spring `ApplicationContext`, so nothing very special has +to be done to test it beyond what you would normally do with a vanilla Spring context. + +NOTE: External properties, logging, and other features of Spring Boot are installed in the +context by default only if you use `SpringApplication` to create it. + +Spring Boot provides a `@SpringBootTest` annotation, which can be used as an alternative +to the standard `spring-test` `@ContextConfiguration` annotation when you need Spring +Boot features. The annotation works by +<>. In addition to +`@SpringBootTest` a number of other annotations are also provided for +<> of an application. + +TIP: If you are using JUnit 4, don't forget to also add `@RunWith(SpringRunner.class)` to +your test, otherwise the annotations will be ignored. If you are using JUnit 5, there's no +need to add the equivalent `@RunWith(SpringExtension.class)` as `@SpringBootTest` and +the other `@…Test` annotations are already annotated with it. + +By default, `@SpringBootTest` will not start a server. You can use the `webEnvironment` +attribute of `@SpringBootTest` to further refine how your tests run: + +* `MOCK`(Default) : Loads a web `ApplicationContext` and provides a mock web +environment. Embedded servers are not started when using this annotation. If a web +environment is not available on your classpath, this mode transparently falls back to +creating a regular non-web `ApplicationContext`. It can be used in conjunction with +<> for mock-based testing of your +web application. +* `RANDOM_PORT`: Loads a `WebServerApplicationContext` and provides a real web +environment. Embedded servers are started and listen on a random port. +* `DEFINED_PORT`: Loads a `WebServerApplicationContext` and provides a real web +environment. Embedded servers are started and listen on a defined port (from your +`application.properties`) or on the default port of `8080`. +* `NONE`: Loads an `ApplicationContext` by using `SpringApplication` but does not provide +_any_ web environment (mock or otherwise). + +NOTE: If your test is `@Transactional`, it rolls back the transaction at the end of each +test method by default. However, as using this arrangement with either `RANDOM_PORT` or +`DEFINED_PORT` implicitly provides a real servlet environment, the HTTP client and server +run in separate threads and, thus, in separate transactions. Any transaction initiated on +the server does not roll back in this case. + +NOTE: `@SpringBootTest` with `webEnvironment = WebEnvironment.RANDOM_PORT` will also +start the management server on a separate random port if your application uses a different +port for the management server. + + + +[[boot-features-testing-spring-boot-applications-detecting-web-app-type]] +==== Detecting Web Application Type +If Spring MVC is available, a regular MVC-based application context is configured. If you +have only Spring WebFlux, we'll detect that and configure a WebFlux-based application +context instead. + +If both are present, Spring MVC takes precedence. If you want to test a reactive web +application in this scenario, you must set the `spring.main.web-application-type` +property: + +[source,java,indent=0] +---- + @SpringBootTest(properties = "spring.main.web-application-type=reactive") + class MyWebFluxTests { ... } +---- + + + +[[boot-features-testing-spring-boot-applications-detecting-config]] +==== Detecting Test Configuration +If you are familiar with the Spring Test Framework, you may be used to using +`@ContextConfiguration(classes=...)` in order to specify which Spring `@Configuration` to +load. Alternatively, you might have often used nested `@Configuration` classes within +your test. + +When testing Spring Boot applications, this is often not required. Spring Boot's `@*Test` +annotations search for your primary configuration automatically whenever you do not +explicitly define one. + +The search algorithm works up from the package that contains the test until it finds a +class annotated with `@SpringBootApplication` or `@SpringBootConfiguration`. As long as +you <> in a sensible way, your +main configuration is usually found. + +[NOTE] +==== +If you use a +<>, you should avoid adding +configuration settings that are specific to a particular area on the +<>. + +The underlying component scan configuration of `@SpringBootApplication` defines exclude +filters that are used to make sure slicing works as expected. If you are using an explicit +`@ComponentScan` directive on your `@SpringBootApplication`-annotated class, be aware that +those filters will be disabled. If you are using slicing, you should define them again. +==== + +If you want to customize the primary configuration, you can use a nested +`@TestConfiguration` class. Unlike a nested `@Configuration` class, which would be used +instead of your application's primary configuration, a nested `@TestConfiguration` class +is used in addition to your application's primary configuration. + +NOTE: Spring's test framework caches application contexts between tests. Therefore, as +long as your tests share the same configuration (no matter how it is discovered), the +potentially time-consuming process of loading the context happens only once. + + + +[[boot-features-testing-spring-boot-applications-excluding-config]] +==== Excluding Test Configuration +If your application uses component scanning (for example, if you use +`@SpringBootApplication` or `@ComponentScan`), you may find top-level configuration +classes that you created only for specific tests accidentally get picked up everywhere. + +As we <>, `@TestConfiguration` can be used on an inner class of a test to customize the +primary configuration. When placed on a top-level class, `@TestConfiguration` indicates +that classes in `src/test/java` should not be picked up by scanning. You can then import +that class explicitly where it is required, as shown in the following example: + +[source,java,indent=0] +---- + @SpringBootTest + @Import(MyTestsConfiguration.class) + class MyTests { + + @Test + void exampleTest() { + ... + } + + } +---- + +NOTE: If you directly use `@ComponentScan` (that is, not through +`@SpringBootApplication`) you need to register the `TypeExcludeFilter` with it. See +{dc-spring-boot}/context/TypeExcludeFilter.{dc-ext}[the Javadoc] for details. + + + +[[boot-features-testing-spring-boot-application-arguments]] +==== Using Application Arguments +If your application expects <>, you can +have `@SpringBootTest` inject them using the `args` attribute. + +[source,java,indent=0] +---- +include::{code-examples}/test/context/ApplicationArgumentsExampleTests.java[tag=example] +---- + + + +[[boot-features-testing-spring-boot-applications-testing-with-mock-environment]] +==== Testing with a mock environment +By default, `@SpringBootTest` does not start the server. If you have web endpoints that +you want to test against this mock environment, you can additionally configure +{spring-reference}/testing.html#spring-mvc-test-framework[`MockMvc`] as shown in the +following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/web/MockMvcExampleTests.java[tag=test-mock-mvc] +---- + +TIP: If you want to focus only on the web layer and not start a complete +`ApplicationContext`, consider +<>. + +Alternatively, you can configure a +{spring-reference}testing.html#webtestclient-tests[`WebTestClient`] as shown in the +following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/web/MockWebTestClientExampleTests.java[tag=test-mock-web-test-client] +---- + + + +[[boot-features-testing-spring-boot-applications-testing-with-running-server]] +==== Testing with a running server +If you need to start a full running server, we recommend that you use random ports. +If you use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)`, an +available port is picked at random each time your test runs. + +The `@LocalServerPort` annotation can be used to +<> into your test. +For convenience, tests that need to make REST calls to the started server can +additionally `@Autowire` a +{spring-reference}testing.html#webtestclient-tests[`WebTestClient`], which resolves +relative links to the running server and comes with a dedicated API for verifying +responses, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/web/RandomPortWebTestClientExampleTests.java[tag=test-random-port] +---- + +This setup requires `spring-webflux` on the classpath. If you can't or won't add webflux, +Spring Boot also provides a `TestRestTemplate` facility: + +[source,java,indent=0] +---- +include::{code-examples}/test/web/RandomPortTestRestTemplateExampleTests.java[tag=test-random-port] +---- + + + +[[boot-features-testing-spring-boot-applications-jmx]] +==== Using JMX +As the test context framework caches context, JMX is disabled by default to prevent +identical components to register on the same domain. If such test needs access to an +`MBeanServer`, consider marking it dirty as well: + +[source,java,indent=0] +---- +include::{test-examples}/jmx/SampleJmxTests.java[tag=test] +---- + + + +[[boot-features-testing-spring-boot-applications-mocking-beans]] +==== Mocking and Spying Beans +When running tests, it is sometimes necessary to mock certain components within your +application context. For example, you may have a facade over some remote service that is +unavailable during development. Mocking can also be useful when you want to simulate +failures that might be hard to trigger in a real environment. + +Spring Boot includes a `@MockBean` annotation that can be used to define a Mockito mock +for a bean inside your `ApplicationContext`. You can use the annotation to add new beans +or replace a single existing bean definition. The annotation can be used directly on test +classes, on fields within your test, or on `@Configuration` classes and fields. When used +on a field, the instance of the created mock is also injected. Mock beans are +automatically reset after each test method. + +[NOTE] +==== +If your test uses one of Spring Boot's test annotations (such as `@SpringBootTest`), this +feature is automatically enabled. To use this feature with a different +arrangement, a listener must be explicitly added, as shown in the following example: + +[source,java,indent=0] +---- + @TestExecutionListeners(MockitoTestExecutionListener.class) +---- + +==== + +The following example replaces an existing `RemoteService` bean with a mock +implementation: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + import org.springframework.beans.factory.annotation.*; + import org.springframework.boot.test.context.*; + import org.springframework.boot.test.mock.mockito.*; + + import static org.assertj.core.api.Assertions.*; + import static org.mockito.BDDMockito.*; + + @SpringBootTest + class MyTests { + + @MockBean + private RemoteService remoteService; + + @Autowired + private Reverser reverser; + + @Test + void exampleTest() { + // RemoteService has been injected into the reverser bean + given(this.remoteService.someCall()).willReturn("mock"); + String reverse = reverser.reverseSomeCall(); + assertThat(reverse).isEqualTo("kcom"); + } + + } +---- + +NOTE: `@MockBean` cannot be used to mock the behavior of a bean that's exercised during +application context refresh. By the time the test is executed, the application context refresh +has completed and it is too late to configure the mocked behavior. We recommend using a `@Bean` +method to create and configure the mock in this situation. + +Additionally, you can use `@SpyBean` to wrap any existing bean with a Mockito `spy`. See +the {dc-spring-boot-test}/mock/mockito/SpyBean.{dc-ext}[Javadoc] for full details. + +NOTE: While Spring's test framework caches application contexts between tests and reuses +a context for tests sharing the same configuration, the use of `@MockBean` or `@SpyBean` +influences the cache key, which will most likely increase the number of contexts. + +TIP: If you are using `@SpyBean` to spy on a bean with `@Cacheable` methods that refer +to parameters by name, your application must be compiled with `-parameters`. This +ensures that the parameter names are available to the caching infrastructure once the +bean has been spied upon. + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-tests]] +==== Auto-configured Tests +Spring Boot's auto-configuration system works well for applications but can sometimes be +a little too much for tests. It often helps to load only the parts of the configuration +that are required to test a "`slice`" of your application. For example, you might want to +test that Spring MVC controllers are mapping URLs correctly, and you do not want to +involve database calls in those tests, or you might want to test JPA entities, and you +are not interested in the web layer when those tests run. + +The `spring-boot-test-autoconfigure` module includes a number of annotations that can be +used to automatically configure such "`slices`". Each of them works in a similar way, +providing a `@...Test` annotation that loads the `ApplicationContext` and one or +more `@AutoConfigure...` annotations that can be used to customize auto-configuration +settings. + +NOTE: Each slice restricts component scan to appropriate components and loads a very +restricted set of auto-configuration classes. If you need to exclude one of them, +most `@...Test` annotations provide an `excludeAutoConfiguration` attribute. +Alternatively, you can use `@ImportAutoConfiguration#exclude`. + +NOTE: Including multiple "`slices`" by using several `@...Test` annotations in one test is +not supported. If you need multiple "`slices`", pick one of the `@...Test` annotations +and include the `@AutoConfigure...` annotations of the other "`slices`" by hand. + +TIP: It is also possible to use the `@AutoConfigure...` annotations with the standard +`@SpringBootTest` annotation. You can use this combination if you are not interested in +"`slicing`" your application but you want some of the auto-configured test beans. + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-json-tests]] +==== Auto-configured JSON Tests +To test that object JSON serialization and deserialization is working as expected, you can +use the `@JsonTest` annotation. `@JsonTest` auto-configures the available supported JSON +mapper, which can be one of the following libraries: + +* Jackson `ObjectMapper`, any `@JsonComponent` beans and any Jackson ``Module``s +* `Gson` +* `Jsonb` + +TIP: A list of the auto-configurations that are enabled by `@JsonTest` can be +<>. + +If you need to configure elements of the auto-configuration, you can use the +`@AutoConfigureJsonTesters` annotation. + +Spring Boot includes AssertJ-based helpers that work with the JSONAssert and JsonPath +libraries to check that JSON appears as expected. The `JacksonTester`, `GsonTester`, +`JsonbTester`, and `BasicJsonTester` classes can be used for Jackson, Gson, Jsonb, and +Strings respectively. Any helper fields on the test class can be `@Autowired` when using +`@JsonTest`. The following example shows a test class for Jackson: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + import org.springframework.beans.factory.annotation.*; + import org.springframework.boot.test.autoconfigure.json.*; + import org.springframework.boot.test.context.*; + import org.springframework.boot.test.json.*; + + import static org.assertj.core.api.Assertions.*; + + @JsonTest + class MyJsonTests { + + @Autowired + private JacksonTester json; + + @Test + void testSerialize() throws Exception { + VehicleDetails details = new VehicleDetails("Honda", "Civic"); + // Assert against a `.json` file in the same package as the test + assertThat(this.json.write(details)).isEqualToJson("expected.json"); + // Or use JSON path based assertions + assertThat(this.json.write(details)).hasJsonPathStringValue("@.make"); + assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make") + .isEqualTo("Honda"); + } + + @Test + void testDeserialize() throws Exception { + String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}"; + assertThat(this.json.parse(content)) + .isEqualTo(new VehicleDetails("Ford", "Focus")); + assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford"); + } + + } +---- + +NOTE: JSON helper classes can also be used directly in standard unit tests. To do so, +call the `initFields` method of the helper in your `@Before` method if you do not use +`@JsonTest`. + +If you're using Spring Boot's AssertJ-based helpers to assert on a number value +at a given JSON path, you might not be able to use `isEqualTo` depending on the type. +Instead, you can use AssertJ's `satisfies` to assert that the value matches the given +condition. For instance, the following example asserts that the actual number is a float +value close to `0.15` within an offset of `0.01`. + +[source,java,indent=0] +---- +assertThat(json.write(message)) + .extractingJsonPathNumberValue("@.test.numberValue") + .satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f))); +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests]] +==== Auto-configured Spring MVC Tests +To test whether Spring MVC controllers are working as expected, use the `@WebMvcTest` +annotation. `@WebMvcTest` auto-configures the Spring MVC infrastructure and limits +scanned beans to `@Controller`, `@ControllerAdvice`, `@JsonComponent`, `Converter`, +`GenericConverter`, `Filter`, `WebMvcConfigurer`, and `HandlerMethodArgumentResolver`. +Regular `@Component` beans are not scanned when using this annotation. + +TIP: A list of the auto-configuration settings that are enabled by `@WebMvcTest` can be +<>. + +TIP: If you need to register extra components, such as the Jackson `Module`, you can +import additional configuration classes by using `@Import` on your test. + +Often, `@WebMvcTest` is limited to a single controller and is used in combination with +`@MockBean` to provide mock implementations for required collaborators. + +`@WebMvcTest` also auto-configures `MockMvc`. Mock MVC offers a powerful way to quickly +test MVC controllers without needing to start a full HTTP server. + +TIP: You can also auto-configure `MockMvc` in a non-`@WebMvcTest` (such as +`@SpringBootTest`) by annotating it with `@AutoConfigureMockMvc`. The following example +uses `MockMvc`: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.*; + import org.springframework.beans.factory.annotation.*; + import org.springframework.boot.test.autoconfigure.web.servlet.*; + import org.springframework.boot.test.mock.mockito.*; + + import static org.assertj.core.api.Assertions.*; + import static org.mockito.BDDMockito.*; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + + @WebMvcTest(UserVehicleController.class) + class MyControllerTests { + + @Autowired + private MockMvc mvc; + + @MockBean + private UserVehicleService userVehicleService; + + @Test + void testExample() throws Exception { + given(this.userVehicleService.getVehicleDetails("sboot")) + .willReturn(new VehicleDetails("Honda", "Civic")); + this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)) + .andExpect(status().isOk()).andExpect(content().string("Honda Civic")); + } + + } +---- + +TIP: If you need to configure elements of the auto-configuration (for example, when +servlet filters should be applied) you can use attributes in the `@AutoConfigureMockMvc` +annotation. + +If you use HtmlUnit or Selenium, auto-configuration also provides an HTMLUnit `WebClient` +bean and/or a `WebDriver` bean. The following example uses HtmlUnit: + + +[source,java,indent=0] +---- + import com.gargoylesoftware.htmlunit.*; + import org.junit.jupiter.api.*; + import org.springframework.beans.factory.annotation.*; + import org.springframework.boot.test.autoconfigure.web.servlet.*; + import org.springframework.boot.test.mock.mockito.*; + + import static org.assertj.core.api.Assertions.*; + import static org.mockito.BDDMockito.*; + + @WebMvcTest(UserVehicleController.class) + class MyHtmlUnitTests { + + @Autowired + private WebClient webClient; + + @MockBean + private UserVehicleService userVehicleService; + + @Test + void testExample() throws Exception { + given(this.userVehicleService.getVehicleDetails("sboot")) + .willReturn(new VehicleDetails("Honda", "Civic")); + HtmlPage page = this.webClient.getPage("/sboot/vehicle.html"); + assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic"); + } + + } +---- + +NOTE: By default, Spring Boot puts `WebDriver` beans in a special "`scope`" to ensure +that the driver exits after each test and that a new instance is injected. If you do +not want this behavior, you can add `@Scope("singleton")` to your `WebDriver` `@Bean` +definition. + +WARNING: The `webDriver` scope created by Spring Boot will replace any user defined scope +of the same name. If you define your own `webDriver` scope you may find it stops working +when you use `@WebMvcTest`. + +If you have Spring Security on the classpath, `@WebMvcTest` will also scan `WebSecurityConfigurer` +beans. Instead of disabling security completely for such tests, you can use Spring Security's test support. +More details on how to use Spring Security's `MockMvc` support can be found in +this _<>_ how-to section. + +TIP: Sometimes writing Spring MVC tests is not enough; Spring Boot can help you run +<>. + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-webflux-tests]] +==== Auto-configured Spring WebFlux Tests +To test that {spring-reference}/web-reactive.html[Spring WebFlux] controllers are +working as expected, you can use the `@WebFluxTest` annotation. `@WebFluxTest` +auto-configures the Spring WebFlux infrastructure and limits scanned beans to +`@Controller`, `@ControllerAdvice`, `@JsonComponent`, `Converter`, `GenericConverter`, and +`WebFluxConfigurer`. Regular `@Component` beans are not scanned when the `@WebFluxTest` +annotation is used. + +TIP: A list of the auto-configurations that are enabled by `@WebFluxTest` can be +<>. + +TIP: If you need to register extra components, such as Jackson `Module`, you can import +additional configuration classes using `@Import` on your test. + +Often, `@WebFluxTest` is limited to a single controller and used in combination with the +`@MockBean` annotation to provide mock implementations for required collaborators. + +`@WebFluxTest` also auto-configures +{spring-reference}testing.html#webtestclient[`WebTestClient`], which offers +a powerful way to quickly test WebFlux controllers without needing to start a full HTTP +server. + +TIP: You can also auto-configure `WebTestClient` in a non-`@WebFluxTest` (such as +`@SpringBootTest`) by annotating it with `@AutoConfigureWebTestClient`. The following +example shows a class that uses both `@WebFluxTest` and a `WebTestClient`: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; + import org.springframework.http.MediaType; + import org.springframework.test.web.reactive.server.WebTestClient; + + @WebFluxTest(UserVehicleController.class) + class MyControllerTests { + + @Autowired + private WebTestClient webClient; + + @MockBean + private UserVehicleService userVehicleService; + + @Test + void testExample() throws Exception { + given(this.userVehicleService.getVehicleDetails("sboot")) + .willReturn(new VehicleDetails("Honda", "Civic")); + this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).isEqualTo("Honda Civic"); + } + + } +---- + +TIP: This setup is only supported by WebFlux applications as using `WebTestClient` in a +mocked web application only works with WebFlux at the moment. + +NOTE: `@WebFluxTest` cannot detect routes registered via the functional web framework. For +testing `RouterFunction` beans in the context, consider importing your `RouterFunction` +yourself via `@Import` or using `@SpringBootTest`. + +NOTE: `@WebFluxTest` cannot detect custom security configuration registered via a `@Bean` +of type `SecurityWebFilterChain`. To include that in your test, you will need to import +the configuration that registers the bean via `@Import` or use `@SpringBootTest`. + +TIP: Sometimes writing Spring WebFlux tests is not enough; Spring Boot can help you run +<>. + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test]] +==== Auto-configured Data JPA Tests +You can use the `@DataJpaTest` annotation to test JPA applications. By default, it scans +for `@Entity` classes and configures Spring Data JPA repositories. If an embedded database +is available on the classpath, it configures one as well. Regular `@Component` beans are +not loaded into the `ApplicationContext`. + +TIP: A list of the auto-configuration settings that are enabled by `@DataJpaTest` can be +<>. + +By default, data JPA tests are transactional and roll back at the end of each test. See +the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section] +in the Spring Framework Reference Documentation for more details. If that is not what you +want, you can disable transaction management for a test or for the whole class as +follows: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + import org.springframework.transaction.annotation.Propagation; + import org.springframework.transaction.annotation.Transactional; + + @DataJpaTest + @Transactional(propagation = Propagation.NOT_SUPPORTED) + class ExampleNonTransactionalTests { + + } +---- + +Data JPA tests may also inject a +{sc-spring-boot-test-autoconfigure}/orm/jpa/TestEntityManager.{sc-ext}[`TestEntityManager`] +bean, which provides an alternative to the standard JPA `EntityManager` that is +specifically designed for tests. If you want to use `TestEntityManager` outside of +`@DataJpaTest` instances, you can also use the `@AutoConfigureTestEntityManager` +annotation. A `JdbcTemplate` is also available if you need that. The following example +shows the `@DataJpaTest` annotation in use: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + import org.springframework.boot.test.autoconfigure.orm.jpa.*; + + import static org.assertj.core.api.Assertions.*; + + @DataJpaTest + class ExampleRepositoryTests { + + @Autowired + private TestEntityManager entityManager; + + @Autowired + private UserRepository repository; + + @Test + void testExample() throws Exception { + this.entityManager.persist(new User("sboot", "1234")); + User user = this.repository.findByUsername("sboot"); + assertThat(user.getUsername()).isEqualTo("sboot"); + assertThat(user.getVin()).isEqualTo("1234"); + } + + } +---- + +In-memory embedded databases generally work well for tests, since they are fast and do +not require any installation. If, however, you prefer to run tests against a real +database you can use the `@AutoConfigureTestDatabase` annotation, as shown in the +following example: + +[source,java,indent=0] +---- + @DataJpaTest + @AutoConfigureTestDatabase(replace=Replace.NONE) + class ExampleRepositoryTests { + + // ... + + } +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test]] +==== Auto-configured JDBC Tests +`@JdbcTest` is similar to `@DataJpaTest` but is for tests that only require a +`DataSource` and do not use Spring Data JDBC. By default, it configures an in-memory +embedded database and a `JdbcTemplate`. Regular `@Component` beans are not loaded into +the `ApplicationContext`. + +TIP: A list of the auto-configurations that are enabled by `@JdbcTest` can be +<>. + +By default, JDBC tests are transactional and roll back at the end of each test. See the +{spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section] in +the Spring Framework Reference Documentation for more details. If that is not what you +want, you can disable transaction management for a test or for the whole class, as +follows: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; + import org.springframework.transaction.annotation.Propagation; + import org.springframework.transaction.annotation.Transactional; + + @JdbcTest + @Transactional(propagation = Propagation.NOT_SUPPORTED) + class ExampleNonTransactionalTests { + + } +---- + +If you prefer your test to run against a real database, you can use the +`@AutoConfigureTestDatabase` annotation in the same way as for `DataJpaTest`. (See +"<>".) + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-data-jdbc-test]] +==== Auto-configured Data JDBC Tests +`@DataJdbcTest` is similar to `@JdbcTest` but is for tests that use Spring Data JDBC +repositories. By default, it configures an in-memory embedded database, a `JdbcTemplate`, +and Spring Data JDBC repositories. Regular `@Component` beans are not loaded into +the `ApplicationContext`. + +TIP: A list of the auto-configurations that are enabled by `@DataJdbcTest` can be +<>. + +By default, Data JDBC tests are transactional and roll back at the end of each test. See +the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section] +in the Spring Framework Reference Documentation for more details. If that is not what you +want, you can disable transaction management for a test or for the whole test class as +<>. + +If you prefer your test to run against a real database, you can use the +`@AutoConfigureTestDatabase` annotation in the same way as for `DataJpaTest`. (See +"<>".) + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jooq-test]] +==== Auto-configured jOOQ Tests +You can use `@JooqTest` in a similar fashion as `@JdbcTest` but for jOOQ-related tests. +As jOOQ relies heavily on a Java-based schema that corresponds with the database schema, +the existing `DataSource` is used. If you want to replace it with an in-memory database, +you can use `@AutoConfigureTestDatabase` to override those settings. (For more about using +jOOQ with Spring Boot, see "<>", earlier in this chapter.) Regular +`@Component` beans are not loaded into the `ApplicationContext`. + +TIP: A list of the auto-configurations that are enabled by `@JooqTest` can be +<>. + +`@JooqTest` configures a `DSLContext`. Regular `@Component` beans are not loaded into the +`ApplicationContext`. The following example shows the `@JooqTest` annotation in use: + +[source,java,indent=0] +---- + import org.jooq.DSLContext; + import org.junit.jupiter.api.Test; + import org.springframework.boot.test.autoconfigure.jooq.JooqTest; + + @JooqTest + class ExampleJooqTests { + + @Autowired + private DSLContext dslContext; + } +---- + +JOOQ tests are transactional and roll back at the end of each test by default. If that is +not what you want, you can disable transaction management for a test or for the whole +test class as +<>. + + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-mongo-test]] +==== Auto-configured Data MongoDB Tests +You can use `@DataMongoTest` to test MongoDB applications. By default, it configures an +in-memory embedded MongoDB (if available), configures a `MongoTemplate`, scans for +`@Document` classes, and configures Spring Data MongoDB repositories. Regular +`@Component` beans are not loaded into the `ApplicationContext`. (For more about using +MongoDB with Spring Boot, see "<>", earlier in this chapter.) + +TIP: A list of the auto-configuration settings that are enabled by `@DataMongoTest` can be +<>. + +The following class shows the `@DataMongoTest` annotation in use: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; + import org.springframework.data.mongodb.core.MongoTemplate; + + @DataMongoTest + class ExampleDataMongoTests { + + @Autowired + private MongoTemplate mongoTemplate; + + // + } +---- + +In-memory embedded MongoDB generally works well for tests, since it is fast and does not +require any developer installation. If, however, you prefer to run tests against a real +MongoDB server, you should exclude the embedded MongoDB auto-configuration, as shown in +the following example: + +[source,java,indent=0] +---- + import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; + import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; + + @DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class) + class ExampleDataMongoNonEmbeddedTests { + + } +---- + + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-neo4j-test]] +==== Auto-configured Data Neo4j Tests +You can use `@DataNeo4jTest` to test Neo4j applications. By default, it uses an in-memory +embedded Neo4j (if the embedded driver is available), scans for `@NodeEntity` classes, and +configures Spring Data Neo4j repositories. Regular `@Component` beans are not loaded into +the `ApplicationContext`. (For more about using Neo4J with Spring Boot, see +"<>", earlier in this chapter.) + +TIP: A list of the auto-configuration settings that are enabled by `@DataNeo4jTest` can be +<>. + +The following example shows a typical setup for using Neo4J tests in Spring Boot: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; + + @DataNeo4jTest + class ExampleDataNeo4jTests { + + @Autowired + private YourRepository repository; + + // + } +---- + +By default, Data Neo4j tests are transactional and roll back at the end of each test. +See the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant +section] in the Spring Framework Reference Documentation for more details. If that is not +what you want, you can disable transaction management for a test or for the whole class, +as follows: + +[source,java,indent=0] +---- + import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; + import org.springframework.transaction.annotation.Propagation; + import org.springframework.transaction.annotation.Transactional; + + @DataNeo4jTest + @Transactional(propagation = Propagation.NOT_SUPPORTED) + class ExampleNonTransactionalTests { + + } +---- + + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-redis-test]] +==== Auto-configured Data Redis Tests +You can use `@DataRedisTest` to test Redis applications. By default, it scans for +`@RedisHash` classes and configures Spring Data Redis repositories. Regular `@Component` +beans are not loaded into the `ApplicationContext`. (For more about using Redis with +Spring Boot, see "<>", earlier in this chapter.) + +TIP: A list of the auto-configuration settings that are enabled by `@DataRedisTest` can be +<>. + +The following example shows the `@DataRedisTest` annotation in use: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest; + + @DataRedisTest + class ExampleDataRedisTests { + + @Autowired + private YourRepository repository; + + // + } +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-ldap-test]] +==== Auto-configured Data LDAP Tests +You can use `@DataLdapTest` to test LDAP applications. By default, it configures an +in-memory embedded LDAP (if available), configures an `LdapTemplate`, scans for `@Entry` +classes, and configures Spring Data LDAP repositories. Regular `@Component` beans are not +loaded into the `ApplicationContext`. (For more about using LDAP with +Spring Boot, see "<>", earlier in this chapter.) + +TIP: A list of the auto-configuration settings that are enabled by `@DataLdapTest` can be +<>. + +The following example shows the `@DataLdapTest` annotation in use: + +[source,java,indent=0] +---- + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest; + import org.springframework.ldap.core.LdapTemplate; + + @DataLdapTest + class ExampleDataLdapTests { + + @Autowired + private LdapTemplate ldapTemplate; + + // + } +---- + +In-memory embedded LDAP generally works well for tests, since it is fast and does not +require any developer installation. If, however, you prefer to run tests against a real +LDAP server, you should exclude the embedded LDAP auto-configuration, as shown in the +following example: + +[source,java,indent=0] +---- + import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration; + import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest; + + @DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class) + class ExampleDataLdapNonEmbeddedTests { + + } +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-client]] +==== Auto-configured REST Clients +You can use the `@RestClientTest` annotation to test REST clients. By default, it +auto-configures Jackson, GSON, and Jsonb support, configures a `RestTemplateBuilder`, and +adds support for `MockRestServiceServer`. Regular `@Component` beans are not loaded into +the `ApplicationContext`. + +TIP: A list of the auto-configuration settings that are enabled by `@RestClientTest` can +be <>. + +The specific beans that you want to test should be specified by using the `value` or +`components` attribute of `@RestClientTest`, as shown in the following example: + +[source,java,indent=0] +---- + @RestClientTest(RemoteVehicleDetailsService.class) + class ExampleRestClientTest { + + @Autowired + private RemoteVehicleDetailsService service; + + @Autowired + private MockRestServiceServer server; + + @Test + void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() + throws Exception { + this.server.expect(requestTo("/greet/details")) + .andRespond(withSuccess("hello", MediaType.TEXT_PLAIN)); + String greeting = this.service.callRestService(); + assertThat(greeting).isEqualTo("hello"); + } + + } +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs]] +==== Auto-configured Spring REST Docs Tests +You can use the `@AutoConfigureRestDocs` annotation to use {spring-rest-docs}[Spring REST +Docs] in your tests with Mock MVC, REST Assured, or WebTestClient. It removes the need for +the JUnit extension in Spring REST Docs. + +`@AutoConfigureRestDocs` can be used to override the default output directory +(`target/generated-snippets` if you are using Maven or `build/generated-snippets` if you +are using Gradle). It can also be used to configure the host, scheme, and port that +appears in any documented URIs. + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-mock-mvc]] +===== Auto-configured Spring REST Docs Tests with Mock MVC +`@AutoConfigureRestDocs` customizes the `MockMvc` bean to use Spring REST Docs. You can +inject it by using `@Autowired` and use it in your tests as you normally would when using +Mock MVC and Spring REST Docs, as shown in the following example: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; + import org.springframework.http.MediaType; + import org.springframework.test.web.servlet.MockMvc; + + import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; + import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + + @WebMvcTest(UserController.class) + @AutoConfigureRestDocs + class UserDocumentationTests { + + @Autowired + private MockMvc mvc; + + @Test + void listUsers() throws Exception { + this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN)) + .andExpect(status().isOk()) + .andDo(document("list-users")); + } + + } +---- + +If you require more control over Spring REST Docs configuration than offered by the +attributes of `@AutoConfigureRestDocs`, you can use a +`RestDocsMockMvcConfigurationCustomizer` bean, as shown in the following example: + +[source,java,indent=0] +---- + @TestConfiguration + static class CustomizationConfiguration + implements RestDocsMockMvcConfigurationCustomizer { + + @Override + public void customize(MockMvcRestDocumentationConfigurer configurer) { + configurer.snippets().withTemplateFormat(TemplateFormats.markdown()); + } + + } +---- + +If you want to make use of Spring REST Docs support for a parameterized output directory, +you can create a `RestDocumentationResultHandler` bean. The auto-configuration calls +`alwaysDo` with this result handler, thereby causing each `MockMvc` call to automatically +generate the default snippets. The following example shows a +`RestDocumentationResultHandler` being defined: + +[source,java,indent=0] +---- + @TestConfiguration + static class ResultHandlerConfiguration { + + @Bean + public RestDocumentationResultHandler restDocumentation() { + return MockMvcRestDocumentation.document("{method-name}"); + } + + } +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-web-test-client]] +===== Auto-configured Spring REST Docs Tests with WebTestClient +`@AutoConfigureRestDocs` can also be used with `WebTestClient`. You can inject it by using +`@Autowired` and use it in your tests as you normally would when using `@WebFluxTest` and +Spring REST Docs, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/autoconfigure/restdocs/webclient/UsersDocumentationTests.java[tag=source] +---- + +If you require more control over Spring REST Docs configuration than offered by the +attributes of `@AutoConfigureRestDocs`, you can use a +`RestDocsWebTestClientConfigurationCustomizer` bean, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/autoconfigure/restdocs/webclient/AdvancedConfigurationExample.java[tag=configuration] +---- + + + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-rest-assured]] +===== Auto-configured Spring REST Docs Tests with REST Assured +`@AutoConfigureRestDocs` makes a `RequestSpecification` bean, preconfigured to use Spring +REST Docs, available to your tests. You can inject it by using `@Autowired` and use it in +your tests as you normally would when using REST Assured and Spring REST Docs, as shown +in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java[tag=source] +---- + +If you require more control over Spring REST Docs configuration than offered by the +attributes of `@AutoConfigureRestDocs`, a `RestDocsRestAssuredConfigurationCustomizer` +bean can be used, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java[tag=configuration] +---- + + + +[[boot-features-testing-spring-boot-applications-testing-auto-configured-additional-auto-config]] +==== Additional Auto-configuration and Slicing +Each slice provides one or more `@AutoConfigure...` annotations that namely defines the +auto-configurations that should be included as part of a slice. Additional +auto-configurations can be added by creating a custom `@AutoConfigure...` annotation or +simply by adding `@ImportAutoConfiguration` to the test as shown in the following example: + +[source,java,indent=0] +---- + @JdbcTest + @ImportAutoConfiguration(IntegrationAutoConfiguration.class) + class ExampleJdbcTests { + + } +---- + +NOTE: Make sure to not use the regular `@Import` annotation to import auto-configurations +as they are handled in a specific way by Spring Boot. + + + +[[boot-features-testing-spring-boot-applications-testing-user-configuration]] +==== User Configuration and Slicing +If you <> in a sensible way, your +`@SpringBootApplication` class is +<> as +the configuration of your tests. + +It then becomes important not to litter the application's main class with configuration +settings that are specific to a particular area of its functionality. + +Assume that you are using Spring Batch and you rely on the auto-configuration for it. +You could define your `@SpringBootApplication` as follows: + +[source,java,indent=0] +---- + @SpringBootApplication + @EnableBatchProcessing + public class SampleApplication { ... } +---- + +Because this class is the source configuration for the test, any slice test actually +tries to start Spring Batch, which is definitely not what you want to do. A recommended +approach is to move that area-specific configuration to a separate `@Configuration` class +at the same level as your application, as shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + @EnableBatchProcessing + public class BatchConfiguration { ... } +---- + +NOTE: Depending on the complexity of your application, you may either have a single +`@Configuration` class for your customizations or one class per domain area. The latter +approach lets you enable it in one of your tests, if necessary, with the `@Import` +annotation. + +Test slices exclude `@Configuration` classes from scanning. For example, for a `@WebMvcTest`, +the following configuration will not include the given `WebMvcConfigurer` bean in the application +context loaded by the test slice: + +[source,java,indent=0] +---- + @Configuration + public class WebConfiguration { + @Bean + public WebMvcConfigurer testConfigurer() { + return new WebMvcConfigurer() { + ... + }; + } + } +---- + +The configuration below will, however, cause the custom `WebMvcConfigurer` to be loaded +by the test slice. + +[source,java,indent=0] +---- + @Component + public class TestWebMvcConfigurer implements WebMvcConfigurer { + ... + } +---- + +Another source of confusion is classpath scanning. Assume that, while you structured your +code in a sensible way, you need to scan an additional package. Your application may +resemble the following code: + +[source,java,indent=0] +---- + @SpringBootApplication + @ComponentScan({ "com.example.app", "org.acme.another" }) + public class SampleApplication { ... } +---- + +Doing so effectively overrides the default component scan directive with the side effect +of scanning those two packages regardless of the slice that you chose. For instance, a +`@DataJpaTest` seems to suddenly scan components and user configurations of your +application. Again, moving the custom directive to a separate class is a good way to fix +this issue. + +TIP: If this is not an option for you, you can create a `@SpringBootConfiguration` +somewhere in the hierarchy of your test so that it is used instead. Alternatively, you +can specify a source for your test, which disables the behavior of finding a default one. + + + +[[boot-features-testing-spring-boot-applications-with-spock]] +==== Using Spock to Test Spring Boot Applications +If you wish to use Spock to test a Spring Boot application, you should add a dependency +on Spock's `spock-spring` module to your application's build. `spock-spring` integrates +Spring's test framework into Spock. It is recommended that you use Spock 1.2 or later to +benefit from a number of improvements to Spock's Spring Framework and Spring Boot +integration. See http://spockframework.org/spock/docs/1.2/modules.html#_spring_module[the +documentation for Spock's Spring module] for further details. + + + +[[boot-features-test-utilities]] +=== Test Utilities +A few test utility classes that are generally useful when testing your application are +packaged as part of `spring-boot`. + + + +[[boot-features-configfileapplicationcontextinitializer-test-utility]] +==== ConfigFileApplicationContextInitializer +`ConfigFileApplicationContextInitializer` is an `ApplicationContextInitializer` that you +can apply to your tests to load Spring Boot `application.properties` files. You can use +it when you do not need the full set of features provided by `@SpringBootTest`, as shown +in the following example: + +[source,java,indent=0] +---- + @ContextConfiguration(classes = Config.class, + initializers = ConfigFileApplicationContextInitializer.class) +---- + +NOTE: Using `ConfigFileApplicationContextInitializer` alone does not provide support for +`@Value("${...}")` injection. Its only job is to ensure that `application.properties` +files are loaded into Spring's `Environment`. For `@Value` support, you need to either +additionally configure a `PropertySourcesPlaceholderConfigurer` or use `@SpringBootTest`, +which auto-configures one for you. + + + +[[boot-features-test-property-values]] +==== TestPropertyValues +`TestPropertyValues` lets you quickly add properties to a +`ConfigurableEnvironment` or `ConfigurableApplicationContext`. You can call it with +`key=value` strings, as follows: + +[source,java,indent=0] +---- + TestPropertyValues.of("org=Spring", "name=Boot").applyTo(env); +---- + + + +[[boot-features-output-capture-test-utility]] +==== OutputCapture +`OutputCapture` is a JUnit `Extension` that you can use to capture `System.out` and +`System.err` output. To use with {@link ExtendWith @ExtendWith}, you can inject +`CapturedOutput` as an argument to your test class constructor or test method as follows: + +[source,java,indent=0] +---- + import org.junit.jupiter.api.Test; + import org.junit.jupiter.api.extension.ExtendWith; + + import org.springframework.boot.test.system.CapturedOutput; + import org.springframework.boot.test.system.OutputCaptureExtension; + + import static org.assertj.core.api.Assertions.assertThat; + + @ExtendWith(OutputCaptureExtension.class) + class MyTest { + + @Test + void testName(CapturedOutput output) { + System.out.println("Hello World!"); + assertThat(output).contains("World")); + } + + } +---- + +[[boot-features-rest-templates-test-utility]] +==== TestRestTemplate + +TIP: Spring Framework 5.0 provides a new `WebTestClient` that works for +<> and both +<>. It provides a fluent API for assertions, +unlike `TestRestTemplate`. + + +`TestRestTemplate` is a convenience alternative to Spring's `RestTemplate` that is useful +in integration tests. You can get a vanilla template or one that sends Basic HTTP +authentication (with a username and password). In either case, the template behaves in a +test-friendly way by not throwing exceptions on server-side errors. It is recommended, +but not mandatory, to use the Apache HTTP Client (version 4.3.2 or better). If you have +that on your classpath, the `TestRestTemplate` responds by configuring the client +appropriately. If you do use Apache's HTTP client, some additional test-friendly features +are enabled: + +* Redirects are not followed (so you can assert the response location). +* Cookies are ignored (so the template is stateless). + +`TestRestTemplate` can be instantiated directly in your integration tests, as shown in +the following example: + +[source,java,indent=0] +---- + public class MyTest { + + private TestRestTemplate template = new TestRestTemplate(); + + @Test + public void testRequest() throws Exception { + HttpHeaders headers = this.template.getForEntity( + "https://myhost.example.com/example", String.class).getHeaders(); + assertThat(headers.getLocation()).hasHost("other.example.com"); + } + + } +---- + +Alternatively, if you use the `@SpringBootTest` annotation with +`WebEnvironment.RANDOM_PORT` or `WebEnvironment.DEFINED_PORT`, you can inject a +fully configured `TestRestTemplate` and start using it. If necessary, additional +customizations can be applied through the `RestTemplateBuilder` bean. Any URLs that do +not specify a host and port automatically connect to the embedded server, as shown in the +following example: + +[source,java,indent=0] +---- +include::{test-examples}/web/client/SampleWebClientTests.java[tag=test] +---- + + + +[[boot-features-websockets]] +== WebSockets +Spring Boot provides WebSockets auto-configuration for embedded Tomcat, Jetty, and +Undertow. If you deploy a war file to a standalone container, Spring Boot assumes that the +container is responsible for the configuration of its WebSocket support. + +Spring Framework provides {spring-reference}web.html#websocket[rich WebSocket support] +for MVC web applications that can be easily accessed through the +`spring-boot-starter-websocket` module. + +WebSocket support is also available for +{spring-reference}web-reactive.html#webflux-websocket[reactive web applications] and +requires to include the WebSocket API alongside `spring-boot-starter-webflux`: + +[source,xml,indent=0,subs="verbatim,quotes,attributes"] +---- + + javax.websocket + javax.websocket-api + +---- + + + +[[boot-features-webservices]] +== Web Services +Spring Boot provides Web Services auto-configuration so that all you must do is define +your `Endpoints`. + +The {spring-webservices-reference}[Spring Web Services features] can be easily accessed +with the `spring-boot-starter-webservices` module. + +`SimpleWsdl11Definition` and `SimpleXsdSchema` beans can be automatically created for +your WSDLs and XSDs respectively. To do so, configure their location, as shown in the +following example: + + +[source,properties,indent=0] +---- + spring.webservices.wsdl-locations=classpath:/wsdl +---- + + + +[[boot-features-webservices-template]] +=== Calling Web Services with `WebServiceTemplate` +If you need to call remote Web services from your application, you can use the +{spring-webservices-reference}#client-web-service-template[`WebServiceTemplate`] class. +Since `WebServiceTemplate` instances often need to be customized before being used, Spring +Boot does not provide any single auto-configured `WebServiceTemplate` bean. It does, +however, auto-configure a `WebServiceTemplateBuilder`, which can be used to create +`WebServiceTemplate` instances when needed. + +The following code shows a typical example: + +[source,java,indent=0] +---- + @Service + public class MyService { + + private final WebServiceTemplate webServiceTemplate; + + public MyService(WebServiceTemplateBuilder webServiceTemplateBuilder) { + this.webServiceTemplate = webServiceTemplateBuilder.build(); + } + + public DetailsResp someWsCall(DetailsReq detailsReq) { + return (DetailsResp) this.webServiceTemplate.marshalSendAndReceive(detailsReq, new SoapActionCallback(ACTION)); + + } + + } +---- + +By default, `WebServiceTemplateBuilder` detects a suitable HTTP-based +`WebServiceMessageSender` using the available HTTP client libraries on the classpath. You +can also customize read and connection timeouts as follows: + +[source,java,indent=0] +---- + @Bean + public WebServiceTemplate webServiceTemplate(WebServiceTemplateBuilder builder) { + return builder.messageSenders(new HttpWebServiceMessageSenderBuilder() + .setConnectTimeout(5000).setReadTimeout(2000).build()).build(); + } +---- + + + +[[boot-features-developing-auto-configuration]] +== Creating Your Own Auto-configuration +If you work in a company that develops shared libraries, or if you work on an open-source +or commercial library, you might want to develop your own auto-configuration. +Auto-configuration classes can be bundled in external jars and still be picked-up by +Spring Boot. + +Auto-configuration can be associated to a "`starter`" that provides the auto-configuration +code as well as the typical libraries that you would use with it. We first cover what +you need to know to build your own auto-configuration and then we move on to the +<>. + +TIP: A https://github.com/snicoll-demos/spring-boot-master-auto-configuration[demo +project] is available to showcase how you can create a starter step-by-step. + + + +[[boot-features-understanding-auto-configured-beans]] +=== Understanding Auto-configured Beans +Under the hood, auto-configuration is implemented with standard `@Configuration` classes. +Additional `@Conditional` annotations are used to constrain when the auto-configuration +should apply. Usually, auto-configuration classes use `@ConditionalOnClass` and +`@ConditionalOnMissingBean` annotations. This ensures that auto-configuration applies +only when relevant classes are found and when you have not declared your own +`@Configuration`. + +You can browse the source code of {sc-spring-boot-autoconfigure}[`spring-boot-autoconfigure`] +to see the `@Configuration` classes that Spring provides (see the +{github-code}/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories[`META-INF/spring.factories`] +file). + + + +[[boot-features-locating-auto-configuration-candidates]] +=== Locating Auto-configuration Candidates +Spring Boot checks for the presence of a `META-INF/spring.factories` file within your +published jar. The file should list your configuration classes under the +`EnableAutoConfiguration` key, as shown in the following example: + +[indent=0] +---- + org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\ + com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration +---- + +[NOTE] +==== +Auto-configurations must be loaded that way _only_. Make sure that they are defined in +a specific package space and that they are never the target of component scanning. +Furthermore, auto-configuration classes should not enable component scanning to find +additional components. Specific ``@Import``s should be used instead. +==== + +You can use the +{sc-spring-boot-autoconfigure}/AutoConfigureAfter.{sc-ext}[`@AutoConfigureAfter`] or +{sc-spring-boot-autoconfigure}/AutoConfigureBefore.{sc-ext}[`@AutoConfigureBefore`] +annotations if your configuration needs to be applied in a specific order. For example, +if you provide web-specific configuration, your class may need to be applied after +`WebMvcAutoConfiguration`. + +If you want to order certain auto-configurations that should not have any direct +knowledge of each other, you can also use `@AutoConfigureOrder`. That annotation has the +same semantic as the regular `@Order` annotation but provides a dedicated order for +auto-configuration classes. + + + +[[boot-features-condition-annotations]] +=== Condition Annotations +You almost always want to include one or more `@Conditional` annotations on your +auto-configuration class. The `@ConditionalOnMissingBean` annotation is one common +example that is used to allow developers to override auto-configuration if they are +not happy with your defaults. + +Spring Boot includes a number of `@Conditional` annotations that you can reuse in your +own code by annotating `@Configuration` classes or individual `@Bean` methods. These +annotations include: + +* <> +* <> +* <> +* <> +* <> +* <> + + +[[boot-features-class-conditions]] +==== Class Conditions +The `@ConditionalOnClass` and `@ConditionalOnMissingClass` annotations let +`@Configuration` classes be included based on the presence or absence of specific classes. +Due to the fact that annotation metadata is parsed by using https://asm.ow2.org/[ASM], you +can use the `value` attribute to refer to the real class, even though that class might not +actually appear on the running application classpath. You can also use the `name` +attribute if you prefer to specify the class name by using a `String` value. + +This mechanism does not apply the same way to `@Bean` methods where typically the return +type is the target of the condition: before the condition on the method applies, the JVM +will have loaded the class and potentially processed method references which will fail if +the class is not present. + +To handle this scenario, a separate `@Configuration` class can be used to isolate the +condition, as shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + // Some conditions + public class MyAutoConfiguration { + + // Auto-configured beans + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(EmbeddedAcmeService.class) + static class EmbeddedConfiguration { + + @Bean + @ConditionalOnMissingBean + public EmbeddedAcmeService embeddedAcmeService() { ... } + + } + + } +---- + +[TIP] +==== +If you use `@ConditionalOnClass` or `@ConditionalOnMissingClass` as a part of a +meta-annotation to compose your own composed annotations, you must use `name` as referring +to the class in such a case is not handled. +==== + + + +[[boot-features-bean-conditions]] +==== Bean Conditions +The `@ConditionalOnBean` and `@ConditionalOnMissingBean` annotations let a bean be +included based on the presence or absence of specific beans. You can use the `value` +attribute to specify beans by type or `name` to specify beans by name. The `search` +attribute lets you limit the `ApplicationContext` hierarchy that should be considered +when searching for beans. + +When placed on a `@Bean` method, the target type defaults to the return type of the +method, as shown in the following example: + +[source,java,indent=0] +---- + @Configuration(proxyBeanMethods = false) + public class MyAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public MyService myService() { ... } + + } +---- + +In the preceding example, the `myService` bean is going to be created if no bean of type +`MyService` is already contained in the `ApplicationContext`. + +TIP: You need to be very careful about the order in which bean definitions are added, as +these conditions are evaluated based on what has been processed so far. For this reason, +we recommend using only `@ConditionalOnBean` and `@ConditionalOnMissingBean` annotations +on auto-configuration classes (since these are guaranteed to load after any user-defined +bean definitions have been added). + +NOTE: `@ConditionalOnBean` and `@ConditionalOnMissingBean` do not prevent `@Configuration` +classes from being created. The only difference between using these conditions at the class level +and marking each contained `@Bean` method with the annotation is that the former prevents +registration of the `@Configuration` class as a bean if the condition does not match. + + + +[[boot-features-property-conditions]] +==== Property Conditions +The `@ConditionalOnProperty` annotation lets configuration be included based on a Spring +Environment property. Use the `prefix` and `name` attributes to specify the property that +should be checked. By default, any property that exists and is not equal to `false` is +matched. You can also create more advanced checks by using the `havingValue` and +`matchIfMissing` attributes. + + + +[[boot-features-resource-conditions]] +==== Resource Conditions +The `@ConditionalOnResource` annotation lets configuration be included only when a +specific resource is present. Resources can be specified by using the usual Spring +conventions, as shown in the following example: `file:/home/user/test.dat`. + + + +[[boot-features-web-application-conditions]] +==== Web Application Conditions +The `@ConditionalOnWebApplication` and `@ConditionalOnNotWebApplication` annotations let +configuration be included depending on whether the application is a "`web application`". +A web application is any application that uses a Spring `WebApplicationContext`, +defines a `session` scope, or has a `StandardServletEnvironment`. + + + +[[boot-features-spel-conditions]] +==== SpEL Expression Conditions +The `@ConditionalOnExpression` annotation lets configuration be included based on the +result of a {spring-reference}core.html#expressions[SpEL expression]. + + + +[[boot-features-test-autoconfig]] +=== Testing your Auto-configuration +An auto-configuration can be affected by many factors: user configuration (`@Bean` +definition and `Environment` customization), condition evaluation (presence of a +particular library), and others. Concretely, each test should create a well defined +`ApplicationContext` that represents a combination of those customizations. +`ApplicationContextRunner` provides a great way to achieve that. + +`ApplicationContextRunner` is usually defined as a field of the test class to gather the +base, common configuration. The following example makes sure that +`UserServiceAutoConfiguration` is always invoked: + +[source,java,indent=0] +---- +include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=runner] +---- + +TIP: If multiple auto-configurations have to be defined, there is no need to order their +declarations as they are invoked in the exact same order as when running the +application. + +Each test can use the runner to represent a particular use case. For instance, the sample +below invokes a user configuration (`UserConfiguration`) and checks that the +auto-configuration backs off properly. Invoking `run` provides a callback context that can +be used with `Assert4J`. + +[source,java,indent=0] +---- +include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-user-config] +---- + +It is also possible to easily customize the `Environment`, as shown in the following +example: + +[source,java,indent=0] +---- +include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-env] +---- + +The runner can also be used to display the `ConditionEvaluationReport`. The report can be printed +at `INFO` or `DEBUG` level. The following example shows how to use the `ConditionEvaluationReportLoggingListener` +to print the report in auto-configuration tests. + +[source,java,indent=0] +---- + @Test + public void autoConfigTest { + ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener( + LogLevel.INFO); + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withInitializer(initializer).run((context) -> { + // Do something... + }); + } +---- + + + +==== Simulating a Web Context +If you need to test an auto-configuration that only operates in a Servlet or Reactive web +application context, use the `WebApplicationContextRunner` or +`ReactiveWebApplicationContextRunner` respectively. + + + +==== Overriding the Classpath +It is also possible to test what happens when a particular class and/or package is not +present at runtime. Spring Boot ships with a `FilteredClassLoader` that can easily be used +by the runner. In the following example, we assert that if `UserService` is not present, the +auto-configuration is properly disabled: + +[source,java,indent=0] +---- +include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-classloader] +---- + + + +[[boot-features-custom-starter]] +=== Creating Your Own Starter +A full Spring Boot starter for a library may contain the following components: + +* The `autoconfigure` module that contains the auto-configuration code. +* The `starter` module that provides a dependency to the `autoconfigure` module as well +as the library and any additional dependencies that are typically useful. In a nutshell, +adding the starter should provide everything needed to start using that library. + +TIP: You may combine the auto-configuration code and the dependency management in a +single module if you do not need to separate those two concerns. + + + +[[boot-features-custom-starter-naming]] +==== Naming +You should make sure to provide a proper namespace for your starter. Do not start your +module names with `spring-boot`, even if you use a different Maven `groupId`. We may +offer official support for the thing you auto-configure in the future. + +As a rule of thumb, you should name a combined module after the starter. For example, +assume that you are creating a starter for "acme" and that you name the auto-configure +module `acme-spring-boot-autoconfigure` and the starter `acme-spring-boot-starter`. If +you only have one module that combines the two, name it `acme-spring-boot-starter`. + +Also, if your starter provides configuration keys, use a unique namespace for them. In +particular, do not include your keys in the namespaces that Spring Boot uses (such as +`server`, `management`, `spring`, and so on). If you use the same namespace, we may modify +these namespaces in the future in ways that break your modules. + +Make sure to +<> so that IDE assistance is available for your keys as well. You may want to +review the generated meta-data (`META-INF/spring-configuration-metadata.json`) to make +sure your keys are properly documented. + + + +[[boot-features-custom-starter-module-autoconfigure]] +==== `autoconfigure` Module +The `autoconfigure` module contains everything that is necessary to get started with the +library. It may also contain configuration key definitions (such as +`@ConfigurationProperties`) and any callback interface that can be used to further +customize how the components are initialized. + +TIP: You should mark the dependencies to the library as optional so that you can include +the `autoconfigure` module in your projects more easily. If you do it that way, the +library is not provided and, by default, Spring Boot backs off. + +Spring Boot uses an annotation processor to collect the conditions on auto-configurations +in a metadata file (`META-INF/spring-autoconfigure-metadata.properties`). If that file is +present, it is used to eagerly filter auto-configurations that do not match, which will +improve startup time. It is recommended to add the following dependency in a module that +contains auto-configurations: + +[source,xml,indent=0,subs="verbatim,quotes,attributes"] +---- + + org.springframework.boot + spring-boot-autoconfigure-processor + true + +---- + +With Gradle 4.5 and earlier, the dependency should be declared in the `compileOnly` +configuration, as shown in the following example: + +[source,groovy,indent=0,subs="verbatim,quotes,attributes"] +---- + dependencies { + compileOnly "org.springframework.boot:spring-boot-autoconfigure-processor" + } +---- + +With Gradle 4.6 and later, the dependency should be declared in the `annotationProcessor` +configuration, as shown in the following example: + +[source,groovy,indent=0,subs="verbatim,quotes,attributes"] +---- + dependencies { + annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor" + } +---- + + + +[[boot-features-custom-starter-module-starter]] +==== Starter Module +The starter is really an empty jar. Its only purpose is to provide the necessary +dependencies to work with the library. You can think of it as an opinionated view of what +is required to get started. + +Do not make assumptions about the project in which your starter is added. If the library +you are auto-configuring typically requires other starters, mention them as well. +Providing a proper set of _default_ dependencies may be hard if the number of optional +dependencies is high, as you should avoid including dependencies that are unnecessary for +a typical usage of the library. In other words, you should not include optional +dependencies. + +NOTE: Either way, your starter must reference the core Spring Boot starter +(`spring-boot-starter`) directly or indirectly (i.e. no need to add it if your starter +relies on another starter). If a project is created with only your custom starter, Spring +Boot's core features will be honoured by the presence of the core starter. + + + +[[boot-features-kotlin]] +== Kotlin support +https://kotlinlang.org[Kotlin] is a statically-typed language targeting the JVM (and other +platforms) which allows writing concise and elegant code while providing +{kotlin-documentation}java-interop.html[interoperability] with existing libraries written +in Java. + +Spring Boot provides Kotlin support by leveraging the support in other Spring projects +such as Spring Framework, Spring Data, and Reactor. See the +{spring-reference}languages.html#kotlin[Spring Framework Kotlin support documentation] +for more information. + +The easiest way to start with Spring Boot and Kotlin is to follow +https://spring.io/guides/tutorials/spring-boot-kotlin/[this comprehensive tutorial]. You +can create new Kotlin projects via +https://start.spring.io/#!language=kotlin[start.spring.io]. Feel free to join the #spring +channel of https://slack.kotlinlang.org/[Kotlin Slack] or ask a question with the `spring` +and `kotlin` tags on https://stackoverflow.com/questions/tagged/spring+kotlin[Stack +Overflow] if you need support. + + + +[[boot-features-kotlin-requirements]] +=== Requirements +Spring Boot supports Kotlin 1.3.x. To use Kotlin, `org.jetbrains.kotlin:kotlin-stdlib` and +`org.jetbrains.kotlin:kotlin-reflect` must be present on the classpath. The +`kotlin-stdlib` variants `kotlin-stdlib-jdk7` and `kotlin-stdlib-jdk8` can also be used. + +Since https://discuss.kotlinlang.org/t/classes-final-by-default/166[Kotlin classes are +final by default], you are likely to want to configure +{kotlin-documentation}compiler-plugins.html#spring-support[kotlin-spring] +plugin in order to automatically open Spring-annotated classes so that they can be +proxied. + +https://github.com/FasterXML/jackson-module-kotlin[Jackson's Kotlin module] is required +for serializing / deserializing JSON data in Kotlin. It is automatically registered when +found on the classpath. A warning message is logged if Jackson and Kotlin are present but +the Jackson Kotlin module is not. + +TIP: These dependencies and plugins are provided by default if one bootstraps a Kotlin +project on https://start.spring.io/#!language=kotlin[start.spring.io]. + + + +[[boot-features-kotlin-null-safety]] +=== Null-safety +One of Kotlin's key features is {kotlin-documentation}null-safety.html[null-safety]. It +deals with `null` values at compile time rather than deferring the problem to runtime and +encountering a `NullPointerException`. This helps to eliminate a common source of bugs +without paying the cost of wrappers like `Optional`. Kotlin also allows using functional +constructs with nullable values as described in this +https://www.baeldung.com/kotlin-null-safety[comprehensive guide to null-safety in Kotlin]. + +Although Java does not allow one to express null-safety in its type system, Spring +Framework, Spring Data, and Reactor now provide null-safety of their API via +tooling-friendly annotations. By default, types from Java APIs used in Kotlin are +recognized as +{kotlin-documentation}java-interop.html#null-safety-and-platform-types[platform types] +for which null-checks are relaxed. +{kotlin-documentation}java-interop.html#jsr-305-support[Kotlin's support for JSR 305 +annotations] combined with nullability annotations provide null-safety for the related +Spring API in Kotlin. + +The JSR 305 checks can be configured by adding the `-Xjsr305` compiler flag with the +following options: `-Xjsr305={strict|warn|ignore}`. The default behavior is the same as +`-Xjsr305=warn`. The `strict` value is required to have null-safety taken in account in +Kotlin types inferred from Spring API but should be used with the knowledge that Spring +API nullability declaration could evolve even between minor releases and more checks may +be added in the future). + +WARNING: Generic type arguments, varargs and array elements nullability are not yet +supported. See https://jira.spring.io/browse/SPR-15942[SPR-15942] for up-to-date +information. Also be aware that Spring Boot's own API is {github-issues}10712[not yet +annotated]. + + + +[[boot-features-kotlin-api]] +=== Kotlin API + + + +[[boot-features-kotlin-api-runapplication]] +==== runApplication +Spring Boot provides an idiomatic way to run an application with +`runApplication(*args)` as shown in the following example: + +[source,kotlin,indent=0] +---- +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +class MyApplication + +fun main(args: Array) { + runApplication(*args) +} +---- + +This is a drop-in replacement for +`SpringApplication.run(MyApplication::class.java, *args)`. It also allows customization +of the application as shown in the following example: + +[source,kotlin,indent=0] +---- +runApplication(*args) { + setBannerMode(OFF) +} +---- + + + +[[boot-features-kotlin-api-extensions]] +==== Extensions +Kotlin {kotlin-documentation}extensions.html[extensions] provide the ability +to extend existing classes with additional functionality. The Spring Boot Kotlin API makes +use of these extensions to add new Kotlin specific conveniences to existing APIs. + +`TestRestTemplate` extensions, similar to those provided by Spring Framework for +`RestOperations` in Spring Framework, are provided. Among other things, the extensions +make it possible to take advantage of Kotlin reified type parameters. + + + +[[boot-features-kotlin-dependency-management]] +=== Dependency management +In order to avoid mixing different versions of Kotlin dependencies on the classpath, +Spring Boot imports the Kotlin BOM. + +With Maven, the Kotlin version can be customized via the `kotlin.version` property and +plugin management is provided for `kotlin-maven-plugin`. With Gradle, the Spring Boot +plugin automatically aligns the `kotlin.version` with the version of the Kotlin plugin. + + + +[[boot-features-kotlin-configuration-properties]] +=== `@ConfigurationProperties` +`@ConfigurationProperties` supports classes with immutable `val` properties as shown in +the following example: + +[source,kotlin,indent=0] +---- +@ConfigurationProperties("example.kotlin") +data class KotlinExampleProperties( + val name: String, + val description: String, + val myService: MyService +) + +data class MyService( + val apiToken: String, + val uri: URI +) +---- + +TIP: To generate <> using the annotation processor, {kotlin-documentation}kapt.html[`kapt` should +be configured] with the `spring-boot-configuration-processor` dependency. Note that some +features (such as detecting the default value or deperecated items) are not working due +to limitations in the model kapt provides. + + +[[boot-features-kotlin-testing]] +=== Testing +While it is possible to use JUnit 4 to test Kotlin code, JUnit 5 is recommended. JUnit 5 +enables a test class to be instantiated once and reused for all of the class's tests. This +makes it possible to use `@BeforeClass` and `@AfterClass` annotations on non-static +methods, which is a good fit for Kotlin. + +JUnit 5 is the default and the vintage engine is provided for backward compatibility with +JUnit 4. If you don't use it, exclude `org.junit.vintange:junit-vintage-engine`. See the +{junit5-documentation}/#dependency-metadata-junit-jupiter-samples[JUnit 5 documentation] +for more details. You also need to +{junit5-documentation}/#writing-tests-test-instance-lifecycle-changing-default[switch test +instance lifecycle to "per-class"]. + +To mock Kotlin classes, https://mockk.io/[MockK] is recommended. If you need the `Mockk` +equivalent of the Mockito specific +<>, you can use https://github.com/Ninja-Squad/springmockk[SpringMockK] which +provides similar `@MockkBean` and `@SpykBean` annotations. + + + +[[boot-features-kotlin-resources]] +=== Resources + + + +[[boot-features-kotlin-resources-further-reading]] +==== Further reading +* {kotlin-documentation}[Kotlin language reference] +* https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel) +* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow with `spring` and `kotlin` tags] +* https://try.kotlinlang.org/[Try Kotlin in your browser] +* https://blog.jetbrains.com/kotlin/[Kotlin blog] +* https://kotlin.link/[Awesome Kotlin] +* https://spring.io/guides/tutorials/spring-boot-kotlin/[Tutorial: building web applications with Spring Boot and Kotlin] +* https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin[Developing Spring Boot applications with Kotlin] +* https://spring.io/blog/2016/03/20/a-geospatial-messenger-with-kotlin-spring-boot-and-postgresql[A Geospatial Messenger with Kotlin, Spring Boot and PostgreSQL] +* https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0[Introducing Kotlin support in Spring Framework 5.0] +* https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way] + + + +[[boot-features-kotlin-resources-examples]] +==== Examples + +* https://github.com/sdeleuze/spring-boot-kotlin-demo[spring-boot-kotlin-demo]: regular Spring Boot + Spring Data JPA project +* https://github.com/mixitconf/mixit[mixit]: Spring Boot 2 + WebFlux + Reactive Spring Data MongoDB +* https://github.com/sdeleuze/spring-kotlin-fullstack[spring-kotlin-fullstack]: WebFlux Kotlin fullstack example with Kotlin2js for frontend instead of JavaScript or TypeScript +* https://github.com/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application +* https://github.com/sdeleuze/spring-kotlin-deepdive[spring-kotlin-deepdive]: a step by step migration for Boot 1.0 + Java to Boot 2.0 + Kotlin + + + +[[boot-features-whats-next]] +== What to Read Next +If you want to learn more about any of the classes discussed in this section, you can +check out the {dc-root}[Spring Boot API documentation] or you can browse the +{github-code}[source code directly]. If you have specific questions, take a look at the +<> section. + +If you are comfortable with Spring Boot's core features, you can continue on and read +about <>.