Skip to content

Commit de350a0

Browse files
committed
Merge pull request #26326 from weixsun
* pr/26326: Polish "Enable Redis connection pool if commons-pool2 is available" Enable Redis connection pool if commons-pool2 is available Closes gh-26326
2 parents a72da74 + d17c475 commit de350a0

File tree

8 files changed

+126
-21
lines changed

8 files changed

+126
-21
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -76,7 +76,7 @@ private JedisClientConfiguration getJedisClientConfiguration(
7676
ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) {
7777
JedisClientConfigurationBuilder builder = applyProperties(JedisClientConfiguration.builder());
7878
RedisProperties.Pool pool = getProperties().getJedis().getPool();
79-
if (pool != null) {
79+
if (isPoolEnabled(pool)) {
8080
applyPooling(pool, builder);
8181
}
8282
if (StringUtils.hasText(getProperties().getUrl())) {

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -104,10 +104,10 @@ private LettuceClientConfiguration getLettuceClientConfiguration(
104104
}
105105

106106
private LettuceClientConfigurationBuilder createBuilder(Pool pool) {
107-
if (pool == null) {
108-
return LettuceClientConfiguration.builder();
107+
if (isPoolEnabled(pool)) {
108+
return new PoolBuilderFactory().createBuilder(pool);
109109
}
110-
return new PoolBuilderFactory().createBuilder(pool);
110+
return LettuceClientConfiguration.builder();
111111
}
112112

113113
private LettuceClientConfigurationBuilder applyProperties(

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -22,12 +22,14 @@
2222
import java.util.List;
2323

2424
import org.springframework.beans.factory.ObjectProvider;
25+
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool;
2526
import org.springframework.data.redis.connection.RedisClusterConfiguration;
2627
import org.springframework.data.redis.connection.RedisNode;
2728
import org.springframework.data.redis.connection.RedisPassword;
2829
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
2930
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
3031
import org.springframework.util.Assert;
32+
import org.springframework.util.ClassUtils;
3133
import org.springframework.util.StringUtils;
3234

3335
/**
@@ -40,6 +42,9 @@
4042
*/
4143
abstract class RedisConnectionConfiguration {
4244

45+
private static final boolean COMMONS_POOL2_AVAILABLE = ClassUtils.isPresent("org.apache.commons.pool2.ObjectPool",
46+
RedisConnectionConfiguration.class.getClassLoader());
47+
4348
private final RedisProperties properties;
4449

4550
private final RedisSentinelConfiguration sentinelConfiguration;
@@ -122,6 +127,11 @@ protected final RedisProperties getProperties() {
122127
return this.properties;
123128
}
124129

130+
protected boolean isPoolEnabled(Pool pool) {
131+
Boolean enabled = pool.getEnabled();
132+
return (enabled != null) ? enabled : COMMONS_POOL2_AVAILABLE;
133+
}
134+
125135
private List<RedisNode> createSentinels(RedisProperties.Sentinel sentinel) {
126136
List<RedisNode> nodes = new ArrayList<>();
127137
for (String node : sentinel.getNodes()) {

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -233,6 +233,12 @@ public enum ClientType {
233233
*/
234234
public static class Pool {
235235

236+
/**
237+
* Whether to enable the pool. Enabled automatically if "commons-pool2" is
238+
* available.
239+
*/
240+
private Boolean enabled;
241+
236242
/**
237243
* Maximum number of "idle" connections in the pool. Use a negative value to
238244
* indicate an unlimited number of idle connections.
@@ -265,6 +271,14 @@ public static class Pool {
265271
*/
266272
private Duration timeBetweenEvictionRuns;
267273

274+
public Boolean getEnabled() {
275+
return this.enabled;
276+
}
277+
278+
public void setEnabled(Boolean enabled) {
279+
this.enabled = enabled;
280+
}
281+
268282
public int getMaxIdle() {
269283
return this.maxIdle;
270284
}
@@ -396,16 +410,12 @@ public static class Jedis {
396410
/**
397411
* Jedis pool configuration.
398412
*/
399-
private Pool pool;
413+
private final Pool pool = new Pool();
400414

401415
public Pool getPool() {
402416
return this.pool;
403417
}
404418

405-
public void setPool(Pool pool) {
406-
this.pool = pool;
407-
}
408-
409419
}
410420

411421
/**
@@ -421,7 +431,7 @@ public static class Lettuce {
421431
/**
422432
* Lettuce pool configuration.
423433
*/
424-
private Pool pool;
434+
private final Pool pool = new Pool();
425435

426436
private final Cluster cluster = new Cluster();
427437

@@ -437,10 +447,6 @@ public Pool getPool() {
437447
return this.pool;
438448
}
439449

440-
public void setPool(Pool pool) {
441-
this.pool = pool;
442-
}
443-
444450
public Cluster getCluster() {
445451
return this.cluster;
446452
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*
3737
* @author Mark Paluch
3838
* @author Stephane Nicoll
39+
* @author Weix Sun
3940
*/
4041
@ClassPathExclusions("lettuce-core-*.jar")
4142
class RedisAutoConfigurationJedisTests {
@@ -142,6 +143,16 @@ void testRedisConfigurationWithPool() {
142143
});
143144
}
144145

146+
@Test
147+
void testRedisConfigurationDisabledPool() {
148+
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.jedis.pool.enabled:false")
149+
.run((context) -> {
150+
JedisConnectionFactory cf = context.getBean(JedisConnectionFactory.class);
151+
assertThat(cf.getHostName()).isEqualTo("foo");
152+
assertThat(cf.getClientConfiguration().isUsePooling()).isEqualTo(false);
153+
});
154+
}
155+
145156
@Test
146157
void testRedisConfigurationWithTimeoutAndConnectTimeout() {
147158
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.timeout:250",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2012-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.data.redis;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.boot.autoconfigure.AutoConfigurations;
22+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
23+
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
24+
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
25+
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
26+
import org.springframework.test.util.ReflectionTestUtils;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
30+
/**
31+
* Tests for {@link RedisAutoConfiguration} when commons-pool2 is not on the classpath.
32+
*
33+
* @author Stephane Nicoll
34+
*/
35+
@ClassPathExclusions("commons-pool2-*.jar")
36+
public class RedisAutoConfigurationLettuceWithoutCommonsPool2Tests {
37+
38+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
39+
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class));
40+
41+
@Test
42+
void poolWithoutCommonsPool2IsDisabledByDefault() {
43+
this.contextRunner.withPropertyValues("spring.redis.host:foo").run((context) -> {
44+
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
45+
assertThat(cf.getHostName()).isEqualTo("foo");
46+
assertThat(ReflectionTestUtils.getField(cf, "clientConfiguration"))
47+
.isNotInstanceOf(LettucePoolingClientConfiguration.class);
48+
});
49+
}
50+
51+
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -31,6 +31,7 @@
3131
import org.junit.jupiter.api.Test;
3232

3333
import org.springframework.boot.autoconfigure.AutoConfigurations;
34+
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool;
3435
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
3536
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3637
import org.springframework.boot.test.context.runner.ContextConsumer;
@@ -65,6 +66,7 @@
6566
* @author Stephane Nicoll
6667
* @author Alen Turkovic
6768
* @author Scott Frederick
69+
* @author Weix Sun
6870
*/
6971
class RedisAutoConfigurationTests {
7072

@@ -155,7 +157,21 @@ void testPasswordInUrlStartsWithColon() {
155157
}
156158

157159
@Test
158-
void testRedisConfigurationWithPool() {
160+
void testRedisConfigurationUsePoolByDefault() {
161+
Pool defaultPool = new RedisProperties().getLettuce().getPool();
162+
this.contextRunner.withPropertyValues("spring.redis.host:foo").run((context) -> {
163+
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
164+
assertThat(cf.getHostName()).isEqualTo("foo");
165+
GenericObjectPoolConfig<?> poolConfig = getPoolingClientConfiguration(cf).getPoolConfig();
166+
assertThat(poolConfig.getMinIdle()).isEqualTo(defaultPool.getMinIdle());
167+
assertThat(poolConfig.getMaxIdle()).isEqualTo(defaultPool.getMaxIdle());
168+
assertThat(poolConfig.getMaxTotal()).isEqualTo(defaultPool.getMaxActive());
169+
assertThat(poolConfig.getMaxWaitMillis()).isEqualTo(defaultPool.getMaxWait().toMillis());
170+
});
171+
}
172+
173+
@Test
174+
void testRedisConfigurationWithCustomPoolSettings() {
159175
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.lettuce.pool.min-idle:1",
160176
"spring.redis.lettuce.pool.max-idle:4", "spring.redis.lettuce.pool.max-active:16",
161177
"spring.redis.lettuce.pool.max-wait:2000", "spring.redis.lettuce.pool.time-between-eviction-runs:30000",
@@ -172,6 +188,17 @@ void testRedisConfigurationWithPool() {
172188
});
173189
}
174190

191+
@Test
192+
void testRedisConfigurationDisabledPool() {
193+
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.lettuce.pool.enabled:false")
194+
.run((context) -> {
195+
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
196+
assertThat(cf.getHostName()).isEqualTo("foo");
197+
assertThat(ReflectionTestUtils.getField(cf, "clientConfiguration"))
198+
.isNotInstanceOf(LettucePoolingClientConfiguration.class);
199+
});
200+
}
201+
175202
@Test
176203
void testRedisConfigurationWithTimeoutAndConnectTimeout() {
177204
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.timeout:250",

spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/nosql.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ If you use Jedis, `JedisClientConfigurationBuilderCustomizer` is also available.
4646

4747
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).
4848

49-
A pooled connection factory is auto-configured if `commons-pool2` is on the classpath and at least one `Pool` option of {spring-boot-autoconfigure-module-code}/data/redis/RedisProperties.java[`RedisProperties`] is set.
49+
By default, a pooled connection factory is auto-configured if `commons-pool2` is on the classpath.
5050

5151

5252

0 commit comments

Comments
 (0)