Skip to content

Commit 519ec86

Browse files
committed
Merge branch '3.2.x' into 3.3.x
Closes gh-43058
2 parents 4900ca1 + 0be9fd9 commit 519ec86

File tree

9 files changed

+54
-54
lines changed

9 files changed

+54
-54
lines changed

spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/data-access.adoc

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,15 @@ app:
5454
pool-size: 30
5555
----
5656

57-
However, there is a catch.
58-
Because the actual type of the connection pool is not exposed, no keys are generated in the metadata for your custom `DataSource` and no completion is available in your IDE (because the `DataSource` interface exposes no properties).
59-
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).
60-
In that case, you must rewrite your configuration as follows:
57+
However, there is a catch due to the method's `DataSource` return type.
58+
This hides the actual type of the connection pool so no configuration property metadata is generated for your custom `DataSource` and no auto-completion is available in your IDE.
59+
To address this problem, use the builder's `type(Class)` method to specify the type of `DataSource` to be built and update the method's return type.
60+
For example, the following shows how to create a `HikariDataSource` with `DataSourceBuilder`:
61+
62+
include-code::simple/MyDataSourceConfiguration[]
63+
64+
Unfortunately, this basic setup does not work because Hikari has no `url` property.
65+
Instead, it has a `jdbc-url` property which means that you must rewrite your configuration as follows:
6166

6267
[configprops%novalidate,yaml]
6368
----
@@ -69,22 +74,15 @@ app:
6974
pool-size: 30
7075
----
7176

72-
You can fix that by forcing the connection pool to use and return a dedicated implementation rather than `DataSource`.
73-
You cannot change the implementation at runtime, but the list of options will be explicit.
74-
75-
The following example shows how to create a `HikariDataSource` with `DataSourceBuilder`:
76-
77-
include-code::simple/MyDataSourceConfiguration[]
78-
79-
You can even go further by leveraging what `DataSourceProperties` does for you -- that is, by providing a default embedded database with a sensible username and password if no URL is provided.
80-
You can easily initialize a `DataSourceBuilder` from the state of any `DataSourceProperties` object, so you could also inject the DataSource that Spring Boot creates automatically.
81-
However, that would split your configuration into two namespaces: `url`, `username`, `password`, `type`, and `driver` on `spring.datasource` and the rest on your custom namespace (`app.datasource`).
82-
To avoid that, you can redefine a custom `DataSourceProperties` on your custom namespace, as shown in the following example:
77+
To address this problem, make use of `DataSourceProperties` which will handle the `url` to `jdbc-url` translation for you.
78+
You can initialize a `DataSourceBuilder` from the state of any `DataSourceProperties` object using its `initializeDataSourceBuilder()` method.
79+
You could inject the `DataSourceProperties` that Spring Boot creates automatically, however, that would split your configuration across `+spring.datasource.*+` and `+app.datasource.*+`.
80+
To avoid this, define a custom `DataSourceProperties` with a custom configuration properties prefix, as shown in the following example:
8381

8482
include-code::configurable/MyDataSourceConfiguration[]
8583

86-
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.
87-
Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl` translation for you, you can configure it as follows:
84+
This setup is equivalent to what Spring Boot does for you by default, except that the pool's type is specified in code and its settings are exposed as `app.datasource.configuration.*` properties.
85+
`DataSourceProperties` takes care of the `url` to `jdbc-url` translation, so you can configure it as follows:
8886

8987
[configprops%novalidate,yaml]
9088
----
@@ -97,13 +95,16 @@ app:
9795
maximum-pool-size: 30
9896
----
9997

98+
Note that, as the custom configuration specifies in code that Hikari should be used, `app.datasource.type` will have no effect.
99+
100+
As described in xref:reference:data/sql.adoc#data.sql.datasource.connection-pool[], `DataSourceBuilder` supports several different connection pools.
101+
To use a pool other than Hikari, add it to the classpath, use the `type(Class)` method to specify the pool class to use, and update the `@Bean` method's return type to match.
102+
This will also provide you with configuration property metadata for the specific connection pool that you've chosen.
103+
100104
TIP: Spring Boot will expose Hikari-specific settings to `spring.datasource.hikari`.
101105
This example uses a more generic `configuration` sub namespace as the example does not support multiple datasource implementations.
102106

103-
NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type` has no effect.
104-
In practice, the builder is initialized with whatever value you might set there and then overridden by the call to `.type()`.
105-
106-
See xref:reference:data/sql.adoc#data.sql.datasource[] in the "`Spring Boot Features`" section and the {code-spring-boot-autoconfigure-src}/jdbc/DataSourceAutoConfiguration.java[`DataSourceAutoConfiguration`] class for more details.
107+
See xref:reference:data/sql.adoc#data.sql.datasource[] and the {code-spring-boot-autoconfigure-src}/jdbc/DataSourceAutoConfiguration.java[`DataSourceAutoConfiguration`] class for more details.
107108

108109

109110

@@ -145,9 +146,12 @@ You can apply the same concept to the secondary `DataSource` as well, as shown i
145146

146147
include-code::MyCompleteDataSourcesConfiguration[]
147148

148-
The preceding example configures two data sources on custom namespaces with the same logic as Spring Boot would use in auto-configuration.
149+
The preceding example configures two data sources on custom configuration property namespaces with the same logic as Spring Boot would use in auto-configuration.
149150
Note that each `configuration` sub namespace provides advanced settings based on the chosen implementation.
150151

152+
As with xref:how-to:data-access.adoc#howto.data-access.configure-custom-datasource[configuring a single custom `DataSource`], the type of one or both of the `DataSource` beans can be customized using the `type(Class)` method on `DataSourceBuilder`.
153+
See xref:reference:data/sql.adoc#data.sql.datasource.connection-pool[] for details of the supported types.
154+
151155

152156

153157
[[howto.data-access.spring-data-repositories]]

spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/testing.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ include-code::MyConfiguration[]
3333
For a `@WebMvcTest` for an application with the above `@Configuration` class, you might expect to have the `SecurityFilterChain` bean in the application context so that you can test if your controller endpoints are secured properly.
3434
However, `MyConfiguration` is not picked up by @WebMvcTest's component scanning filter because it doesn't match any of the types specified by the filter.
3535
You can include the configuration explicitly by annotating the test class with `@Import(MyConfiguration.class)`.
36-
This will load all the beans in `MyConfiguration` including the `BasicDataSource` bean which isn't required when testing the web tier.
36+
This will load all the beans in `MyConfiguration` including the `HikariDataSource` bean which isn't required when testing the web tier.
3737
Splitting the configuration class into two will enable importing just the security configuration.
3838

3939
include-code::MySecurityConfiguration[]

spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteDataSourcesConfiguration.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
1717
package org.springframework.boot.docs.howto.dataaccess.configuretwodatasources;
1818

1919
import com.zaxxer.hikari.HikariDataSource;
20-
import org.apache.commons.dbcp2.BasicDataSource;
2120

2221
import org.springframework.beans.factory.annotation.Qualifier;
2322
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
@@ -51,9 +50,9 @@ public DataSourceProperties secondDataSourceProperties() {
5150

5251
@Bean
5352
@ConfigurationProperties("app.datasource.second.configuration")
54-
public BasicDataSource secondDataSource(
53+
public HikariDataSource secondDataSource(
5554
@Qualifier("secondDataSourceProperties") DataSourceProperties secondDataSourceProperties) {
56-
return secondDataSourceProperties.initializeDataSourceBuilder().type(BasicDataSource.class).build();
55+
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
5756
}
5857

5958
}

spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyDataSourcesConfiguration.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
1717
package org.springframework.boot.docs.howto.dataaccess.configuretwodatasources;
1818

1919
import com.zaxxer.hikari.HikariDataSource;
20-
import org.apache.commons.dbcp2.BasicDataSource;
2120

2221
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
2322
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -45,8 +44,8 @@ public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProp
4544

4645
@Bean
4746
@ConfigurationProperties("app.datasource.second")
48-
public BasicDataSource secondDataSource() {
49-
return DataSourceBuilder.create().type(BasicDataSource.class).build();
47+
public HikariDataSource secondDataSource() {
48+
return DataSourceBuilder.create().type(HikariDataSource.class).build();
5049
}
5150

5251
}

spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/testing/slicetests/MyConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
1616

1717
package org.springframework.boot.docs.howto.testing.slicetests;
1818

19-
import org.apache.commons.dbcp2.BasicDataSource;
19+
import com.zaxxer.hikari.HikariDataSource;
2020

2121
import org.springframework.boot.context.properties.ConfigurationProperties;
2222
import org.springframework.boot.jdbc.DataSourceBuilder;
@@ -36,8 +36,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
3636

3737
@Bean
3838
@ConfigurationProperties("app.datasource.second")
39-
public BasicDataSource secondDataSource() {
40-
return DataSourceBuilder.create().type(BasicDataSource.class).build();
39+
public HikariDataSource secondDataSource() {
40+
return DataSourceBuilder.create().type(HikariDataSource.class).build();
4141
}
4242

4343
}

spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/testing/slicetests/MyDatasourceConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
1616

1717
package org.springframework.boot.docs.howto.testing.slicetests;
1818

19-
import org.apache.commons.dbcp2.BasicDataSource;
19+
import com.zaxxer.hikari.HikariDataSource;
2020

2121
import org.springframework.boot.context.properties.ConfigurationProperties;
2222
import org.springframework.boot.jdbc.DataSourceBuilder;
@@ -28,8 +28,8 @@ public class MyDatasourceConfiguration {
2828

2929
@Bean
3030
@ConfigurationProperties("app.datasource.second")
31-
public BasicDataSource secondDataSource() {
32-
return DataSourceBuilder.create().type(BasicDataSource.class).build();
31+
public HikariDataSource secondDataSource() {
32+
return DataSourceBuilder.create().type(HikariDataSource.class).build();
3333
}
3434

3535
}

spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteDataSourcesConfiguration.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
1717
package org.springframework.boot.docs.howto.dataaccess.configuretwodatasources
1818

1919
import com.zaxxer.hikari.HikariDataSource
20-
import org.apache.commons.dbcp2.BasicDataSource
2120
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
2221
import org.springframework.boot.context.properties.ConfigurationProperties
2322
import org.springframework.context.annotation.Bean
@@ -49,8 +48,8 @@ class MyCompleteDataSourcesConfiguration {
4948

5049
@Bean
5150
@ConfigurationProperties("app.datasource.second.configuration")
52-
fun secondDataSource(secondDataSourceProperties: DataSourceProperties): BasicDataSource {
53-
return secondDataSourceProperties.initializeDataSourceBuilder().type(BasicDataSource::class.java).build()
51+
fun secondDataSource(secondDataSourceProperties: DataSourceProperties): HikariDataSource {
52+
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
5453
}
5554

5655
}

spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyDataSourcesConfiguration.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
1717
package org.springframework.boot.docs.howto.dataaccess.configuretwodatasources
1818

1919
import com.zaxxer.hikari.HikariDataSource
20-
import org.apache.commons.dbcp2.BasicDataSource
2120
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
2221
import org.springframework.boot.context.properties.ConfigurationProperties
2322
import org.springframework.boot.jdbc.DataSourceBuilder
@@ -44,8 +43,8 @@ class MyDataSourcesConfiguration {
4443

4544
@Bean
4645
@ConfigurationProperties("app.datasource.second")
47-
fun secondDataSource(): BasicDataSource {
48-
return DataSourceBuilder.create().type(BasicDataSource::class.java).build()
46+
fun secondDataSource(): HikariDataSource {
47+
return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
4948
}
5049

5150
}

spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyDataSourcesConfigurationTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
2020

2121
import javax.sql.DataSource;
2222

23-
import org.apache.commons.dbcp2.BasicDataSource;
23+
import com.zaxxer.hikari.HikariDataSource;
2424
import org.junit.jupiter.api.Test;
2525
import org.junit.jupiter.api.extension.ExtendWith;
2626

@@ -38,8 +38,8 @@
3838
* @author Stephane Nicoll
3939
*/
4040
@ExtendWith(SpringExtension.class)
41-
@SpringBootTest(properties = { "app.datasource.second.url=jdbc:h2:mem:bar;DB_CLOSE_DELAY=-1",
42-
"app.datasource.second.max-total=42" })
41+
@SpringBootTest(properties = { "app.datasource.second.jdbc-url=jdbc:h2:mem:bar;DB_CLOSE_DELAY=-1",
42+
"app.datasource.second.maximum-pool-size=42" })
4343
@Import(MyDataSourcesConfiguration.class)
4444
class MyDataSourcesConfigurationTests {
4545

@@ -52,9 +52,9 @@ void validateConfiguration() throws SQLException {
5252
DataSource dataSource = this.context.getBean(DataSource.class);
5353
assertThat(this.context.getBean("firstDataSource")).isSameAs(dataSource);
5454
assertThat(dataSource.getConnection().getMetaData().getURL()).startsWith("jdbc:h2:mem:");
55-
BasicDataSource secondDataSource = this.context.getBean("secondDataSource", BasicDataSource.class);
56-
assertThat(secondDataSource.getUrl()).isEqualTo("jdbc:h2:mem:bar;DB_CLOSE_DELAY=-1");
57-
assertThat(secondDataSource.getMaxTotal()).isEqualTo(42);
55+
HikariDataSource secondDataSource = this.context.getBean("secondDataSource", HikariDataSource.class);
56+
assertThat(secondDataSource.getJdbcUrl()).isEqualTo("jdbc:h2:mem:bar;DB_CLOSE_DELAY=-1");
57+
assertThat(secondDataSource.getMaximumPoolSize()).isEqualTo(42);
5858
}
5959

6060
}

0 commit comments

Comments
 (0)