From 2595258494fe58108568ac2b88573af3f577577c Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 6 Oct 2020 18:49:03 -0700 Subject: [PATCH] Provide both properties and YAML examples in docs Update all configuration examples in the docs to YAML and make use of the new `configblocks` spring-asciidoctor-extensions feature to automatically create both "Properties" and "Yaml" versions. Closes gh-23515 --- .../spring-boot-docs/build.gradle | 1 + .../src/docs/asciidoc/howto.adoc | 296 +++-- .../asciidoc/production-ready-features.adoc | 575 +++++++--- .../docs/asciidoc/spring-boot-features.adoc | 1021 +++++++++++------ .../src/docs/asciidoc/using-spring-boot.adoc | 49 +- 5 files changed, 1287 insertions(+), 655 deletions(-) diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index b98212df48..bf2861e22a 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -46,6 +46,7 @@ plugins.withType(EclipsePlugin) { dependencies { actuatorApiDocumentation(project(path: ":spring-boot-project:spring-boot-actuator-autoconfigure", configuration: "documentation")) + asciidoctorExtensions("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch") asciidoctorExtensions("io.spring.asciidoctor:spring-asciidoctor-extensions-spring-boot") asciidoctorExtensions(project(path: ":spring-boot-project:spring-boot-actuator-autoconfigure")) asciidoctorExtensions(project(path: ":spring-boot-project:spring-boot-autoconfigure")) diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc index ba5e739b82..2a4f621a9b 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc @@ -85,7 +85,7 @@ See "`< ---- -You also need to add `logging.file.name` to your `application.properties`, as shown in the following example: +You also need to add `logging.file.name` to your `application.properties` or `application.yaml`, as shown in the following example: -[source,properties,indent=0,subs="verbatim,quotes,attributes",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - logging.file.name=myapplication.log + logging: + file: + name: "myapplication.log" ---- @@ -1492,11 +1539,13 @@ The following example shows how to define a data source in a bean: The following example shows how to define a data source by setting properties: -[source,properties,indent=0] +[source,yaml,indent=0,configblocks] ---- - app.datasource.url=jdbc:h2:mem:mydb - app.datasource.username=sa - app.datasource.pool-size=30 + app: + datasource: + url: "jdbc:h2:mem:mydb" + username: "sa" + pool-size: 30 ---- Assuming that your `FancyDataSource` has regular JavaBean properties for the URL, the username, and the pool size, these settings are bound automatically before the `DataSource` is made available to other components. @@ -1519,12 +1568,14 @@ Check the implementation that is going to be used at runtime for more details. The following example shows how to define a JDBC data source by setting properties: -[source,properties,indent=0] +[source,yaml,indent=0,configblocks] ---- - app.datasource.url=jdbc:mysql://localhost/test - app.datasource.username=dbuser - app.datasource.password=dbpass - app.datasource.pool-size=30 + app: + datasource: + url: "jdbc:mysql://localhost/test" + username: "dbuser" + password: "dbpass" + pool-size: 30 ---- However, there is a catch. @@ -1532,12 +1583,14 @@ Because the actual type of the connection pool is not exposed, no keys are gener Also, if you happen to have Hikari on the classpath, this basic setup does not work, because Hikari has no `url` property (but does have a `jdbcUrl` property). In that case, you must rewrite your configuration as follows: -[source,properties,indent=0] +[source,yaml,indent=0,configblocks] ---- - app.datasource.jdbc-url=jdbc:mysql://localhost/test - app.datasource.username=dbuser - app.datasource.password=dbpass - app.datasource.maximum-pool-size=30 + app: + datasource: + jdbc-url: "jdbc:mysql://localhost/test" + username: "dbuser" + password: "dbpass" + pool-size: 30 ---- You can fix that by forcing the connection pool to use and return a dedicated implementation rather than `DataSource`. @@ -1563,12 +1616,15 @@ include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configurati This setup puts you _in sync_ with what Spring Boot does for you by default, except that a dedicated connection pool is chosen (in code) and its settings are exposed in the `app.datasource.configuration` sub namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl` translation for you, you can configure it as follows: -[source,properties,indent=0] +[source,yaml,indent=0,configblocks] ---- - app.datasource.url=jdbc:mysql://localhost/test - app.datasource.username=dbuser - app.datasource.password=dbpass - app.datasource.configuration.maximum-pool-size=30 + app: + datasource: + url: "jdbc:mysql://localhost/test" + username: "dbuser" + password: "dbpass" + configuration: + maximum-pool-size: 30 ---- TIP: Spring Boot will expose Hikari-specific settings to `spring.datasource.hikari`. @@ -1599,17 +1655,22 @@ TIP: `firstDataSourceProperties` has to be flagged as `@Primary` so that the dat Both data sources are also bound for advanced customizations. For instance, you could configure them as follows: -[source,properties,indent=0] +[source,yaml,indent=0,configblocks] ---- - app.datasource.first.url=jdbc:mysql://localhost/first - app.datasource.first.username=dbuser - app.datasource.first.password=dbpass - app.datasource.first.configuration.maximum-pool-size=30 + app: + datasource: + first: + url: "jdbc:mysql://localhost/first" + username: "dbuser" + password: "dbpass" + configuration: + maximum-pool-size: 30 - app.datasource.second.url=jdbc:mysql://localhost/second - app.datasource.second.username=dbuser - app.datasource.second.password=dbpass - app.datasource.second.max-total=30 + second: + url: "jdbc:mysql://localhost/second" + username: "dbuser" + password: "dbpass" + max-total: 30 ---- You can apply the same concept to the secondary `DataSource` as well, as shown in the following example: @@ -1673,10 +1734,14 @@ If you prefer to set the dialect yourself, set the configprop:spring.jpa.databas The most common options to set are shown in the following example: -[indent=0,subs="verbatim,quotes,attributes"] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy - spring.jpa.show-sql=true + spring: + jpa: + hibernate: + naming: + physical-strategy: "com.example.MyPhysicalNamingStrategy" + show-sql: true ---- In addition, all properties in `+spring.jpa.properties.*+` are passed through as normal JPA properties (with the prefix stripped) when the local `EntityManagerFactory` is created. @@ -1993,12 +2058,14 @@ Spring Boot can detect your database type and execute those scripts on startup. If you use an embedded database, this happens by default. You can also enable it for any database type, as shown in the following example: -[indent=0,subs="verbatim,quotes,attributes"] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.batch.initialize-schema=always + spring: + batch: + initialize-schema: "always" ---- -You can also switch off the initialization explicitly by setting `spring.batch.initialize-schema=never`. +You can also switch off the initialization explicitly by setting `spring.batch.initialize-schema` to `never`. @@ -2017,17 +2084,21 @@ By default, they are in a directory called `classpath:db/migration`, but you can This is a comma-separated list of one or more `classpath:` or `filesystem:` locations. For example, the following configuration would search for scripts in both the default classpath location and the `/opt/migration` directory: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration + spring: + flyway: + locations: "classpath:db/migration,filesystem:/opt/migration" ---- You can also add a special `\{vendor}` placeholder to use vendor-specific scripts. Assume the following: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.flyway.locations=classpath:db/migration/{vendor} + spring: + flyway: + locations: "classpath:db/migration/{vendor}" ---- Rather than using `db/migration`, the preceding configuration sets the directory to use according to the type of the database (such as `db/migration/mysql` for MySQL). @@ -2061,9 +2132,11 @@ For example, you can place test-specific migrations in `src/test/resources` and Also, you can use profile-specific configuration to customize `spring.flyway.locations` so that certain migrations run only when a particular profile is active. For example, in `application-dev.properties`, you might specify the following setting: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration + spring: + flyway: + locations: "classpath:/db/migration,classpath:/dev/db/migration" ---- With that setup, migrations in `dev/db/migration` run only when the `dev` profile is active. @@ -2287,10 +2360,13 @@ If you use Tomcat as a servlet container, then Spring Boot adds Tomcat's own `Re The standard behavior is determined by the presence or absence of certain request headers (`x-forwarded-for` and `x-forwarded-proto`), whose names are conventional, so it should work with most front-end proxies. You can switch on the valve by adding some entries to `application.properties`, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - server.tomcat.remoteip.remote-ip-header=x-forwarded-for - server.tomcat.remoteip.protocol-header=x-forwarded-proto + server: + tomcat: + remoteip: + remote-ip-header: "x-forwarded-for" + protocol-header: "x-forwarded-proto" ---- (The presence of either of those properties switches on the valve. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/production-ready-features.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/production-ready-features.adoc index f2684b6e4f..9d1d7989a0 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/production-ready-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/production-ready-features.adoc @@ -161,18 +161,25 @@ By default, all endpoints except for `shutdown` are enabled. To configure the enablement of an endpoint, use its `management.endpoint..enabled` property. The following example enables the `shutdown` endpoint: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.shutdown.enabled=true + management: + endpoint: + shutdown: + enabled: true ---- If you prefer endpoint enablement to be opt-in rather than opt-out, set the configprop:management.endpoints.enabled-by-default[] property to `false` and use individual endpoint `enabled` properties to opt back in. The following example enables the `info` endpoint and disables all other endpoints: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.enabled-by-default=false - management.endpoint.info.enabled=true + management: + endpoints: + enabled-by-default: false + endpoint: + info: + enabled: true ---- NOTE: Disabled endpoints are removed entirely from the application context. @@ -312,33 +319,29 @@ Both `include` and `exclude` properties can be configured with a list of endpoin For example, to stop exposing all endpoints over JMX and only expose the `health` and `info` endpoints, use the following property: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.jmx.exposure.include=health,info + management: + endpoints: + jmx: + exposure: + include: "health,info" ---- `*` can be used to select all endpoints. For example, to expose everything over HTTP except the `env` and `beans` endpoints, use the following properties: -[source,properties,indent=0,configprops] ----- - management.endpoints.web.exposure.include=* - management.endpoints.web.exposure.exclude=env,beans ----- - -[NOTE] -==== -`*` has a special meaning in YAML, so be sure to add quotes if you want to include (or exclude) all endpoints, as shown in the following example: - -[source,yaml,indent=0] +[source,yaml,indent=0,configprops,configblocks] ---- management: endpoints: web: exposure: include: "*" + exclude: "env,beans" ---- -==== + +NOTE: `*` has a special meaning in YAML, so be sure to add quotes if you want to include (or exclude) all endpoints. NOTE: If your application is exposed publicly, we strongly recommend that you also <>. @@ -377,9 +380,13 @@ If you deploy applications behind a firewall, you may prefer that all your actua You can do so by changing the configprop:management.endpoints.web.exposure.include[] property, as follows: .application.properties -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.web.exposure.include=* + management: + endpoints: + web: + exposure: + include: "*" ---- Additionally, if Spring Security is present, you would need to add custom security configuration that allows unauthenticated access to the endpoints as shown in the following example: @@ -407,9 +414,13 @@ To configure the amount of time for which an endpoint will cache a response, use The following example sets the time-to-live of the `beans` endpoint's cache to 10 seconds: .application.properties -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.beans.cache.time-to-live=10s + management: + endpoint: + beans: + cache: + time-to-live: "10s" ---- NOTE: The prefix `management.endpoint.` is used to uniquely identify the endpoint that is being configured. @@ -435,10 +446,14 @@ If you use Spring MVC or Spring WebFlux, Actuator's web endpoints can be configu CORS support is disabled by default and is only enabled once the configprop:management.endpoints.web.cors.allowed-origins[] property has been set. The following configuration permits `GET` and `POST` calls from the `example.com` domain: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.web.cors.allowed-origins=https://example.com - management.endpoints.web.cors.allowed-methods=GET,POST + management: + endpoints: + web: + cors: + allowed-origins: "https://example.com" + allowed-methods: "GET,POST" ---- TIP: See {spring-boot-actuator-autoconfigure-module-code}/endpoint/web/CorsEndpointProperties.java[CorsEndpointProperties] for a complete list of options. @@ -798,9 +813,13 @@ In such cases, a custom implementation of the {spring-boot-actuator-module-code} For example, assume a new `Status` with code `FATAL` is being used in one of your `HealthIndicator` implementations. To configure the severity order, add the following property to your application properties: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up + management: + endpoint: + health: + status: + order: "fatal,down,out-of-service,unknown,up" ---- The HTTP status code in the response reflects the overall health status. @@ -811,11 +830,16 @@ Configuring a custom mapping disables the defaults mappings for `DOWN` and `OUT_ If you want to retain the default mappings they must be configured explicitly alongside any custom mappings. For example, the following property maps `FATAL` to 503 (service unavailable) and retains the default mappings for `DOWN` and `OUT_OF_SERVICE`: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.health.status.http-mapping.down=503 - management.endpoint.health.status.http-mapping.fatal=503 - management.endpoint.health.status.http-mapping.out-of-service=503 + management: + endpoint: + health: + status: + http-mapping: + down: 503 + fatal: 503 + out-of-service: 503 ---- TIP: If you need more control, you can define your own `HttpCodeStatusMapper` bean. @@ -908,30 +932,47 @@ It's sometimes useful to organize health indicators into groups that can be used To create a health indicator group you can use the `management.endpoint.health.group.` property and specify a list of health indicator IDs to `include` or `exclude`. For example, to create a group that includes only database indicators you can define the following: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.health.group.custom.include=db + management: + endpoint: + health: + group: + custom: + include: "db" ---- You can then check the result by hitting `http://localhost:8080/actuator/health/custom`. Similarly, to create a group that excludes the database indicators from the group and includes all the other indicators, you can define the following: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.health.group.custom.exclude=db + management: + endpoint: + health: + group: + custom: + exclude: "db" ---- By default groups will inherit the same `StatusAggregator` and `HttpCodeStatusMapper` settings as the system health, however, these can also be defined on a per-group basis. It's also possible to override the `show-details` and `roles` properties if required: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.health.group.custom.show-details=when-authorized - management.endpoint.health.group.custom.roles=admin - management.endpoint.health.group.custom.status.order=fatal,up - management.endpoint.health.group.custom.status.http-mapping.fatal=500 - management.endpoint.health.group.custom.status.http-mapping.out-of-service=500 + management: + endpoint: + health: + group: + custom: + show-details: "when-authorized" + roles: "admin" + status: + order: "fatal,up" + http-mapping: + fatal: 500 + out-of-service: 500 ---- TIP: You can use `@Qualifier("groupname")` if you need to register custom `StatusAggregator` or `HttpCodeStatusMapper` beans for use with the group. @@ -986,9 +1027,14 @@ In this case, a probe check could be successful even if the main application doe Actuator configures the "liveness" and "readiness" probes as Health Groups; this means that all the <> are available for them. You can, for example, configure additional Health Indicators: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.health.group.readiness.include=readinessState,customCheck + management: + endpoint: + health: + group: + readiness: + include: "readinessState,customCheck" ---- By default, Spring Boot does not add other Health Indicators to these groups. @@ -1101,11 +1147,14 @@ You can customize the data exposed by the `info` endpoint by setting `+info.*+` All `Environment` properties under the `info` key are automatically exposed. For example, you could add the following settings to your `application.properties` file: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - info.app.encoding=UTF-8 - info.app.java.source=1.8 - info.app.java.target=1.8 + info: + app: + encoding: "UTF-8" + java: + source: "11" + target: "11" ---- [TIP] @@ -1114,11 +1163,14 @@ Rather than hardcoding those values, you could also <>" for more details. If you want to display the full git information (that is, the full content of `git.properties`), use the configprop:management.info.git.mode[] property, as follows: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.info.git.mode=full + management: + info: + git: + mode: "full" ---- @@ -1209,9 +1264,12 @@ Sometimes, it is useful to customize the prefix for the management endpoints. For example, your application might already use `/actuator` for another purpose. You can use the configprop:management.endpoints.web.base-path[] property to change the prefix for your management endpoint, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.web.base-path=/manage + management: + endpoints: + web: + base-path: "/manage" ---- The preceding `application.properties` example changes the endpoint from `/actuator/\{id}` to `/manage/\{id}` (for example, `/manage/info`). @@ -1224,10 +1282,14 @@ If you want to map endpoints to a different path, you can use the configprop:man The following example remaps `/actuator/health` to `/healthcheck`: .application.properties -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.web.base-path=/ - management.endpoints.web.path-mapping.health=healthcheck + management: + endpoints: + web: + base-path: "/" + path-mapping: + health: "healthcheck" ---- @@ -1239,9 +1301,11 @@ If, however, your application runs inside your own data center, you may prefer t You can set the configprop:management.server.port[] property to change the HTTP port, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.server.port=8081 + management: + server: + port: 8081 ---- NOTE: On Cloud Foundry, applications only receive requests on port 8080 for both HTTP and TCP routing, by default. @@ -1254,28 +1318,38 @@ If you want to use a custom management port on Cloud Foundry, you will need to e When configured to use a custom port, the management server can also be configured with its own SSL by using the various `management.server.ssl.*` properties. For example, doing so lets a management server be available over HTTP while the main application uses HTTPS, as shown in the following property settings: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - server.port=8443 - server.ssl.enabled=true - server.ssl.key-store=classpath:store.jks - server.ssl.key-password=secret - management.server.port=8080 - management.server.ssl.enabled=false + server: + port: 8443 + ssl: + enabled: true + key-store: "classpath:store.jks" + key-password: secret + management: + server: + port: 8080 + ssl: + enabled: false ---- Alternatively, both the main server and the management server can use SSL but with different key stores, as follows: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - server.port=8443 - server.ssl.enabled=true - server.ssl.key-store=classpath:main.jks - server.ssl.key-password=secret - management.server.port=8080 - management.server.ssl.enabled=true - management.server.ssl.key-store=classpath:management.jks - management.server.ssl.key-password=secret + server: + port: 8443 + ssl: + enabled: true + key-store: "classpath:main.jks" + key-password: "secret" + management: + server: + port: 8080 + ssl: + enabled: true + key-store: "classpath:management.jks" + key-password: "secret" ---- @@ -1289,10 +1363,12 @@ NOTE: You can listen on a different address only when the port differs from the The following example `application.properties` does not allow remote management connections: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.server.port=8081 - management.server.address=127.0.0.1 + management: + server: + port: 8081 + address: "127.0.0.1" ---- @@ -1301,16 +1377,22 @@ The following example `application.properties` does not allow remote management === Disabling HTTP Endpoints If you do not want to expose endpoints over HTTP, you can set the management port to `-1`, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.server.port=-1 + management: + server: + port: -1 ---- This can be achieved using the configprop:management.endpoints.web.exposure.exclude[] property as well, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.web.exposure.exclude=* + management: + endpoints: + web: + exposure: + exclude: "*" ---- @@ -1334,10 +1416,15 @@ To solve this problem, you can set the configprop:spring.jmx.unique-names[] prop You can also customize the JMX domain under which endpoints are exposed. The following settings show an example of doing so in `application.properties`: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.jmx.unique-names=true - management.endpoints.jmx.domain=com.example.myapp + spring: + jmx: + unique-names: true + management: + endpoints: + jmx: + domain: "com.example.myapp" ---- @@ -1346,9 +1433,13 @@ The following settings show an example of doing so in `application.properties`: === Disabling JMX Endpoints If you do not want to expose endpoints over JMX, you can set the configprop:management.endpoints.jmx.exposure.exclude[] property to `*`, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoints.jmx.exposure.exclude=* + management: + endpoints: + jmx: + exposure: + exclude: "*" ---- @@ -1382,9 +1473,13 @@ Jolokia has a number of settings that you would traditionally configure by setti With Spring Boot, you can use your `application.properties` file. To do so, prefix the parameter with `management.endpoint.jolokia.config.`, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.jolokia.config.debug=true + management: + endpoint: + jolokia: + config: + debug: true ---- @@ -1393,9 +1488,12 @@ To do so, prefix the parameter with `management.endpoint.jolokia.config.`, as sh ==== Disabling Jolokia If you use Jolokia but do not want Spring Boot to configure it, set the configprop:management.endpoint.jolokia.enabled[] property to `false`, as follows: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.endpoint.jolokia.enabled=false + management: + endpoint: + jolokia: + enabled: false ---- @@ -1470,23 +1568,33 @@ Most registries share common features. For instance, you can disable a particular registry even if the Micrometer registry implementation is on the classpath. For example, to disable Datadog: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.metrics.export.datadog.enabled=false + management: + metrics: + export: + datadog: + enabled: false ---- You can also disable all registries unless stated otherwise by the registry-specific property, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.metrics.export.defaults.enabled=false + management: + metrics: + export: + defaults: + enabled: false ---- Spring Boot will also add any auto-configured registries to the global static composite registry on the `Metrics` class unless you explicitly tell it not to: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - management.metrics.use-global-registry=false + management: + metrics: + use-global-registry: false ---- You can register any number of `MeterRegistryCustomizer` beans to further configure the registry, such as applying common tags, before any meters are registered with the registry: @@ -1523,9 +1631,13 @@ Spring Boot also <` from `AcmeProperties`: Consider the following configuration: -[source,yaml,indent=0] +[source,yaml,indent=0,configblocks] ---- acme: map: key1: - name: my name 1 - description: my description 1 + name: "my name 1" + description: "my description 1" --- spring: - profiles: dev + config: + activate: + on-profile: "dev" acme: map: key1: - name: dev name 1 + name: "dev name 1" key2: - name: dev name 2 - description: dev description 2 + 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. +NOTE: The preceding merging rules apply to properties from all property sources, and not just files. @@ -1813,9 +1840,11 @@ You can use a configprop:spring.profiles.active[] `Environment` property to spec 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.profiles.active=dev,hsqldb + spring: + profiles: + active: "dev,hsqldb" ---- You could also specify it on the command line by using the following switch: `--spring.profiles.active=dev,hsqldb`. @@ -1843,11 +1872,14 @@ A profile group allows you to define a logical name for a related group of profi For example, we can create a `production` group that consists of our `proddb` and `prodmq` profiles. -[source,yaml,indent=0] +[source,yaml,indent=0,configblocks] ---- - spring.profiles.group.production: - - proddb - - prodmq + spring: + profiles: + group: + production: + - "proddb" + - "prodmq" ---- Our application can now be started using `--spring.profiles.active=production` to active the `production`, `proddb` and `prodmq` profiles in one hit. @@ -2040,13 +2072,24 @@ 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",configprops] +[source,properties,indent=0,subs="verbatim,quotes,attributes",configprops,role="primary"] +.Properties ---- logging.level.root=warn logging.level.org.springframework.web=debug logging.level.org.hibernate=error ---- +[source,properties,indent=0,subs="verbatim,quotes,attributes",role="secondary"] +.Yaml +---- + logging: + level: + root: "warn" + org.springframework.web: "debug" + org.hibernate: "error" +---- + It's also possible to set logging levels using environment variables. For example, `LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG` will set `org.springframework.web` to `DEBUG`. @@ -2064,16 +2107,20 @@ For example, you might commonly change the logging levels for _all_ Tomcat relat 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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat + 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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - logging.level.tomcat=TRACE + logging: + level: + tomcat: "trace" ---- Spring Boot includes the following pre-defined logging groups that can be used out-of-the-box: @@ -2297,10 +2344,12 @@ If no properties file is found that matches any of the configured base names, th 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.messages.basename=messages,config.i18n.messages - spring.messages.fallback-to-system-locale=false + spring: + messages: + basename: "messages,config.i18n.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. @@ -2504,9 +2553,11 @@ Most of the time, this does not happen (unless you modify the default MVC config By default, resources are mapped on `+/**+`, but you can tune that with the configprop: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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - spring.mvc.static-path-pattern=/resources/** + spring: + mvc: + static-path-pattern: "/resources/**" ---- You can also customize the static resource locations by using the configprop:spring.resources.static-locations[] property (replacing the default values with a list of directory locations). @@ -2529,10 +2580,15 @@ 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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - spring.resources.chain.strategy.content.enabled=true - spring.resources.chain.strategy.content.paths=/** + spring: + resources: + chain: + strategy: + content: + enabled: true + paths: "/**" ---- NOTE: Links to resources are rewritten in templates at runtime, thanks to a `ResourceUrlEncodingFilter` that is auto-configured for Thymeleaf and FreeMarker. @@ -2543,13 +2599,19 @@ When loading resources dynamically with, for example, a JavaScript module loader 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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - 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 + spring: + resources: + chain: + strategy: + content: + enabled: true + paths: "/**" + fixed: + enabled: true + paths: "/js/lib/" + 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 (``). @@ -2589,17 +2651,38 @@ 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,yaml,indent=0,subs="verbatim,quotes,attributes",configblocks] +---- + spring: + mvc: + contentnegotiation: + favor-parameter: true +---- + +Or if you prefer to use a different parameter name: + [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 + spring: + mvc: + contentnegotiation: + favor-parameter: true + parameter-name: "myparam" ---- +Most standard media types are supported out-of-the-box, but you can also define new ones: + +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configblocks] +---- + spring: + mvc: + contentnegotiation: + media-types: + markdown: "text/markdown" +---- + + + Suffix pattern matching is deprecated and will be removed in a future release. If you understand the caveats and would still like your application to use suffix pattern matching, the following configuration is required: @@ -2611,22 +2694,26 @@ If you understand the caveats and would still like your application to use suffi Alternatively, rather than open all suffix patterns, it's more secure to only support registered suffix patterns: -[source,properties,indent=0,subs="verbatim,quotes,attributes"] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - 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 + spring: + mvc: + contentnegotiation: + favor-path-extension: true + pathmatch: + use-registered-suffix-pattern: true ---- As of Spring Framework 5.3, Spring MVC supports several implementation strategies for matching request paths to Controller handlers. It was previously only supporting the `AntPathMatcher` strategy, but it now also offers `PathPatternParser`. Spring Boot now provides a configuration property to choose and opt in the new strategy: -[source,properties,indent=0,subs="verbatim,quotes,attributes"] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - spring.mvc.pathmatch.matching-strategy=path_pattern_parser + spring: + mvc: + pathmatch: + matching-strategy: "path-pattern-parser" ---- For more details on why you should consider this new implementation, please check out the @@ -2999,9 +3086,11 @@ It uses the `ResourceWebHandler` from Spring WebFlux so that you can modify that By default, resources are mapped on `+/**+`, but you can tune that by setting the configprop: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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - spring.webflux.static-path-pattern=/resources/** + spring: + webflux: + static-path-pattern: "/resources/**" ---- You can also customize the static resource locations by using `spring.resources.static-locations`. @@ -3264,7 +3353,7 @@ Most applications are auto-configured, and the appropriate `ApplicationContext` [[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. +Usually, you would define the properties in your `application.properties` or `application.yaml` file. Common server settings include: @@ -3382,16 +3471,19 @@ NOTE: Graceful shutdown with Tomcat requires Tomcat 9.0.33 or later. To enable graceful shutdown, configure the configprop:server.shutdown[] property, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- -server.shutdown=graceful +server: + shutdown: "graceful" ---- To configure the timeout period, configure the configprop:spring.lifecycle.timeout-per-shutdown-phase[] property, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- -spring.lifecycle.timeout-per-shutdown-phase=20s +spring: + lifecycle: + timeout-per-shutdown-phase: "20s" ---- IMPORTANT: Using graceful shutdown with your IDE may not work properly if it does not send a proper `SIGTERM` signal. @@ -3434,11 +3526,13 @@ This depends on the type of application and its configuration. For WebFlux application (i.e. of type `WebApplicationType.REACTIVE`), the RSocket server will be plugged into the Web Server only if the following properties match: -[source,properties,indent=0,subs="verbatim,quotes,attributes",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - 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 + spring: + rsocket: + server: + mapping-path: "/rsocket" + transport: "websocket" ---- WARNING: Plugging RSocket into a web server is only supported with Reactor Netty, as RSocket itself is built with that library. @@ -3446,10 +3540,12 @@ WARNING: Plugging RSocket into a web server is only supported with Reactor Netty Alternatively, an RSocket TCP or websocket server is started as an independent, embedded 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",configprops] +[source,yaml,indent=0,subs="verbatim,quotes,attributes",configprops,configblocks] ---- - spring.rsocket.server.port=9898 # the only required configuration - spring.rsocket.server.transport=tcp # you're free to configure other properties + spring: + rsocket: + server: + port: 9898 ---- @@ -3580,32 +3676,41 @@ 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - 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=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-1: + client-id: "abcd" + client-secret: "password" + client-name: "Client for user scope" + provider: "my-oauth-provider" + scope: "user" + redirect-uri: "https://my-redirect-uri.com" + client-authentication-method: "basic" + 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=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 + my-client-2: + client-id: "abcd" + client-secret: "password" + client-name: "Client for email scope" + provider: "my-oauth-provider" + scope: "email" + redirect-uri: "https://my-redirect-uri.com" + client-authentication-method: "basic" + 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 + provider: + my-oauth-provider: + authorization-uri: "https://my-auth-server/oauth/authorize" + token-uri: "https://my-auth-server/oauth/token" + user-info-uri: "https://my-auth-server/userinfo" + user-info-authentication-method: "header" + jwk-set-uri: "https://my-auth-server/token_keys" + 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. @@ -3614,9 +3719,15 @@ For example, if the `issuer-uri` provided is "https://example.com", then an `Ope 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/ + 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/*`. @@ -3651,14 +3762,20 @@ Also, if the key for the client registration matches a default supported provide In other words, the two configurations in the following example use the Google provider: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - 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 + spring: + security: + oauth2: + client: + registration: + my-client: + client-id: "abcd" + client-secret: "password" + provider: "google" + google: + client-id: "abcd" + client-secret: "password" ---- @@ -3668,14 +3785,24 @@ In other words, the two configurations in the following example use the Google p 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys + spring: + security: + oauth2: + resourceserver: + jwt: + jwk-set-uri: "https://example.com/oauth2/default/v1/keys" ---- -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/ + 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. @@ -3687,11 +3814,16 @@ Alternatively, you can define your own `JwtDecoder` bean for servlet application 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - 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 + spring: + security: + oauth2: + resourceserver: + opaquetoken: + introspection-uri: "https://example.com/check-token" + client-id: "my-client-id" + client-secret: "my-client-secret" ---- Again, the same properties are applicable for both servlet and reactive applications. @@ -3719,19 +3851,35 @@ This configuration makes use of the properties under `Saml2RelyingPartyPropertie A relying party registration represents a paired configuration between an Identity Provider, IDP, and a Service Provider, SP. You can register multiple relying parties under the `spring.security.saml2.relyingparty` prefix, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].private-key-location=path-to-private-key - spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].certificate-location=path-to-certificate - spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.verification.credentials[0].certificate-location=path-to-verification-cert - spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.entity-id=remote-idp-entity-id1 - spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.sso-url=https://remoteidp1.sso.url + spring: + security: + saml2: + relyingparty: + registration: + my-relying-party1: + signing.credentials: + - private-key-location: "path-to-private-key" + certificate-location: "path-to-certificate" + identityprovider: + verification: + credentials: + - certificate-location: "path-to-verification-cert" + entity-id: "remote-idp-entity-id1" + sso-url: "https://remoteidp1.sso.url" - spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].private-key-location=path-to-private-key - spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].certificate-location=path-to-certificate - spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.verification.credentials[0].certificate-location=path-to-other-verification-cert - spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.entity-id=remote-idp-entity-id2 - spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.sso-url=https://remoteidp2.sso.url + my-relying-party2: + signing: + credentials: + - private-key-location: "path-to-private-key" + certificate-location: "path-to-certificate" + identityprovider: + verification: + credentials: + - certificate-location: "path-to-other-verification-cert" + entity-id: "remote-idp-entity-id2" + sso-url: "https://remoteidp2.sso.url" ---- @@ -3840,18 +3988,21 @@ 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.datasource.url=jdbc:mysql://localhost/test - spring.datasource.username=dbuser - spring.datasource.password=dbpass - spring.datasource.driver-class-name=com.mysql.jdbc.Driver + spring: + datasource: + url: "jdbc:mysql://localhost/test" + username: "dbuser" + password: "dbpass" ---- NOTE: You should at least specify the URL by setting the configprop: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`. +TIP: Spring Boot can deduce the JDBC driver class for most databases from the URL. +If you need to specify a specific class, you can use the configprop:spring.datasource.driver-class-name[] property. + 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. @@ -3863,18 +4014,18 @@ Refer to the documentation of the connection pool implementation you are using f For instance, if you use the {tomcat-docs}/jdbc-pool.html#Common_Attributes[Tomcat connection pool], you could customize many additional settings, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - # 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 + spring: + datasource: + tomcat: + max-wait: 10000 + max-active: 50 + test-on-borrow: true ---- +This will set the pool to wait 10000 ms before throwing an exception if no connection is available, limit the maximum number of connections to 50 and validate the connection before borrowing it from the pool. + [[boot-features-connecting-to-a-jndi-datasource]] @@ -3884,9 +4035,11 @@ If you deploy your Spring Boot application to an Application Server, you might w The configprop:spring.datasource.jndi-name[] property can be used as an alternative to the configprop:spring.datasource.url[], configprop:spring.datasource.username[], and configprop: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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.datasource.jndi-name=java:jboss/datasources/customers + spring: + datasource: + jndi-name: "java:jboss/datasources/customers" ---- @@ -3918,9 +4071,12 @@ Spring's `JdbcTemplate` and `NamedParameterJdbcTemplate` classes are auto-config 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.jdbc.template.max-rows=500 + spring: + jdbc: + template: + max-rows: 500 ---- NOTE: The `NamedParameterJdbcTemplate` reuses the same `JdbcTemplate` instance behind the scenes. @@ -4224,11 +4380,13 @@ Connections are provided via a `ConnectionFactory`, similar to a `DataSource` wi `ConnectionFactory` configuration is controlled by external configuration properties in `+spring.r2dbc.*+`. For example, you might declare the following section in `application.properties`: -[source,properties,indent=0] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.r2dbc.url=r2dbc:postgresql://localhost/test - spring.r2dbc.username=dbuser - spring.r2dbc.password=dbpass + spring: + r2dbc: + url: "r2dbc:postgresql://localhost/test" + username: "dbuser" + password: "dbpass" ---- TIP: You do not need to specify a driver class name, since Spring Boot obtains the driver from R2DBC's Connection Factory discovery. @@ -4469,13 +4627,16 @@ You can set the configprop:spring.data.mongodb.uri[] property to change the URL Alternatively, you can specify connection details using discrete properties. For example, you might declare the following settings in your `application.properties`: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.data.mongodb.host=mongoserver.example.com - spring.data.mongodb.port=27017 - spring.data.mongodb.database=test - spring.data.mongodb.username=user - spring.data.mongodb.password=secret + spring: + data: + mongodb: + host: "mongoserver.example.com" + port: 27017 + database: "test" + username: "user" + password: "secret" ---- TIP: If `spring.data.mongodb.port` is not specified, the default of `27017` is used. @@ -4599,11 +4760,14 @@ The following example shows how to inject a Neo4j `Driver` that gives you access You can configure various aspects of the driver using `spring.neo4j.*` properties. The following example shows how to configure the uri and credentials to use: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.neo4j.uri=bolt://my-server:7687 - spring.neo4j.authentication.username=neo4j - spring.neo4j.authentication.password=secret + spring: + neo4j: + uri: "bolt://my-server:7687" + authentication: + username: "neo4j" + password: "secret" ---- The auto-configured `Driver` is created using `ConfigBuilder`. @@ -4703,6 +4867,7 @@ Spring Boot supports several clients: Spring Boot provides a dedicated "`Starter`", `spring-boot-starter-data-elasticsearch`. + [[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. @@ -4711,12 +4876,15 @@ Spring Boot provides support for the "High Level" client, which ships with `org. If you have this dependency on the classpath, Spring Boot will auto-configure and register a `RestHighLevelClient` bean that by default targets `http://localhost:9200`. You can further tune how `RestHighLevelClient` is configured, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - 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 + spring: + elasticsearch: + rest: + uris: "https://search.example.com:9200" + read-timeout: "10s" + username: "user" + password: "secret" ---- You can also register an arbitrary number of beans that implement `RestClientBuilderCustomizer` for more advanced customizations. @@ -4724,6 +4892,8 @@ To take full control over the registration, define a `RestClientBuilder` bean. TIP: If your application needs access to a "Low Level" `RestClient`, you can get it by calling `client.getLowLevelClient()` on the auto-configured `RestHighLevelClient`. + + [[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. @@ -4733,18 +4903,25 @@ By default, Spring Boot will auto-configure and register a `ReactiveElasticsearc bean that targets `http://localhost:9200`. You can further tune how it is configured, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.data.elasticsearch.client.reactive.endpoints=search.example.com:9200 - spring.data.elasticsearch.client.reactive.use-ssl=true - spring.data.elasticsearch.client.reactive.socket-timeout=10s - spring.data.elasticsearch.client.reactive.username=user - spring.data.elasticsearch.client.reactive.password=secret + spring: + data: + elasticsearch: + client: + reactive: + endpoints: "search.example.com:9200" + use-ssl: true + socket-timeout: "10s" + username: "user" + 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-spring-data]] ==== Connecting to Elasticsearch by Using Spring Data To connect to Elasticsearch, a `RestHighLevelClient` bean must be defined, @@ -4792,9 +4969,13 @@ Same applies to `ReactiveElasticsearchTemplate` and `ReactiveElasticsearchOperat You can choose to disable the repositories support with the following property: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.data.elasticsearch.repositories.enabled=false + spring: + data: + elasticsearch: + repositories: + enabled: false ---- @@ -4812,20 +4993,26 @@ You can inject an auto-configured `CassandraTemplate` or a Cassandra `CqlSession The `spring.data.cassandra.*` properties can be used to customize the connection. Generally, you provide `keyspace-name` and `contact-points` as well the local datacenter name, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.data.cassandra.keyspace-name=mykeyspace - spring.data.cassandra.contact-points=cassandrahost1:9042,cassandrahost2:9042 - spring.data.cassandra.local-datacenter=datacenter1 + spring: + data: + cassandra: + keyspace-name: "mykeyspace" + contact-points: "cassandrahost1:9042,cassandrahost2:9042" + local-datacenter: "datacenter1" ---- If the port is the same for all your contact points you can use a shortcut and only specify the host names, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.data.cassandra.keyspace-name=mykeyspace - spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2 - spring.data.cassandra.local-datacenter=datacenter1 + spring: + data: + cassandra: + keyspace-name: "mykeyspace" + contact-points: "cassandrahost1,cassandrahost2" + local-datacenter: "datacenter1" ---- TIP: Those two examples are identical as the port default to `9042`. @@ -4887,21 +5074,28 @@ You can get a `Cluster` by adding the Couchbase SDK and some configuration. The `spring.couchbase.*` properties can be used to customize the connection. Generally, you provide the https://github.com/couchbaselabs/sdk-rfcs/blob/master/rfc/0011-connection-string.md[connection string], username, and password, as shown in the following example: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.couchbase.connection-string=couchbase://192.168.1.123 - spring.couchbase.username=user - spring.couchbase.password=secret + spring: + couchbase: + connection-string: "couchbase://192.168.1.123" + username: "user" + password: "secret" ---- It is also possible to customize some of the `ClusterEnvironment` settings. For instance, the following configuration changes the timeout to use to open a new `Bucket` and enables SSL support: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.couchbase.env.timeouts.connect=3000 - spring.couchbase.env.ssl.key-store=/location/of/keystore.jks - spring.couchbase.env.ssl.key-store-password=secret + spring: + couchbase: + env: + timeouts: + connect: "3s" + ssl: + key-store: "/location/of/keystore.jks" + key-store-password: "secret" ---- TIP: Check the `spring.couchbase.env.*` properties for more details. @@ -4917,9 +5111,12 @@ For complete details of Spring Data Couchbase, refer to the {spring-data-couchba You can inject an auto-configured `CouchbaseTemplate` instance as you would with any other Spring Bean, provided a `CouchbaseClientFactory` bean is available. This happens when a `Cluster` is available, as described above, and a bucket name has been specified: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.data.couchbase.bucket-name=my-bucket + spring: + data: + couchbase: + bucket-name: "my-bucket" ---- The following examples shows how to inject a `CouchbaseTemplate` bean: @@ -4981,11 +5178,13 @@ There is a `spring-boot-starter-data-ldap` "`Starter`" for collecting the depend ==== 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.ldap.urls=ldap://myserver:1235 - spring.ldap.username=admin - spring.ldap.password=secret + spring: + ldap: + urls: "ldap://myserver:1235" + username: "admin" + password: "secret" ---- If you need to customize connection settings, you can use the `spring.ldap.base` and `spring.ldap.base-environment` properties. @@ -5029,32 +5228,26 @@ You can also inject an auto-configured `LdapTemplate` instance as you would with For testing purposes, Spring Boot supports auto-configuration of an in-memory LDAP server from https://ldap.com/unboundid-ldap-sdk-for-java/[UnboundID]. To configure the server, add a dependency to `com.unboundid:unboundid-ldapsdk` and declare a configprop:spring.ldap.embedded.base-dn[] property, as follows: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.ldap.embedded.base-dn=dc=spring,dc=io + 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: +In yaml files, you can use the yaml list notation. In properties files, you must include the index as part of the property name: -[source,yaml,indent=0] +[source,yaml,indent=0,configprops,configblocks] ---- 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,configprops] ----- - 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. @@ -5079,9 +5272,11 @@ https://www.influxdata.com/[InfluxDB] is an open-source time series database opt ==== 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.influx.url=https://172.0.0.1:8086 + 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. @@ -5168,10 +5363,12 @@ The following example sets a flag to say that `null` values should be passed dow @Bean public CacheManagerCustomizer cacheManagerCustomizer() { return new CacheManagerCustomizer() { + @Override public void customize(ConcurrentMapCacheManager cacheManager) { cacheManager.setAllowNullValues(false); } + }; } ---- @@ -5198,11 +5395,14 @@ 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- # Only necessary if more than one provider is present - spring.cache.jcache.provider=com.acme.MyCachingProvider - spring.cache.jcache.config=classpath:acme.xml + spring: + cache: + jcache: + provider: "com.acme.MyCachingProvider" + 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. @@ -5227,9 +5427,12 @@ https://www.ehcache.org/[EhCache] 2.x is used if a file named `ehcache.xml` can 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.cache.ehcache.config=classpath:config/another-config.xml + spring: + cache: + ehcache: + config: "classpath:config/another-config.xml" ---- @@ -5246,9 +5449,12 @@ If a `HazelcastInstance` has been auto-configured, it is automatically wrapped i 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,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.cache.infinispan.config=infinispan.xml + spring: + cache: + infinispan: + config: "infinispan.xml" ---- Caches can be created on startup by setting the configprop:spring.cache.cache-names[] property. @@ -5266,10 +5472,13 @@ If Spring Data Couchbase is available and Couchbase is <>, you would add the following property: +For example, to configure restart to always use a <>, you would add the following property to your `spring-boot-devtools` file: -.~/.config/spring-boot/spring-boot-devtools.properties -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.devtools.restart.trigger-file=.reloadtrigger + spring: + devtools: + restart: + trigger-file: ".reloadtrigger" ---- NOTE: If devtools configuration files are not found in `$HOME/.config/spring-boot`, the root of the `$HOME` directory is searched for the presence of a `.spring-boot-devtools.properties` file. @@ -803,10 +817,13 @@ Profile specific filenames (of the form `spring-boot-devtools-.properti Since Spring Boot relies entirely on the IDE to compile and copy files into the location from where Spring Boot can read them, you might find that there are times when certain changes are not reflected when devtools restarts the application. If you observe such problems constantly, try increasing the `spring.devtools.restart.poll-interval` and `spring.devtools.restart.quiet-period` parameters to the values that fit your development environment: -[source,properties,indent=0,configprops] +[source,yaml,indent=0,configprops,configblocks] ---- - spring.devtools.restart.poll-interval=2s - spring.devtools.restart.quiet-period=1s + spring: + devtools: + restart: + poll-interval: "2s" + quiet-period: "1s" ---- The monitored classpath directories are now polled every 2 seconds for changes, and a 1 second quiet period is maintained to make sure there are no additional class changes.