From fe3f40c6f418de3998059dd06ff1b4184eff0df2 Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Fri, 27 Oct 2017 10:49:01 +0200 Subject: [PATCH] Harmonize Redis configurations This commit improves reactive Redis configuration by adding support for connection factory qualifier and Redis operations resolver annotations. --- .../java/sample/RedisSerializerTest.java | 2 +- ...edisOperationsSessionRepositoryITests.java | 2 +- ...isListenerContainerTaskExecutorITests.java | 2 +- .../SpringSessionRedisConnectionFactory.java | 2 +- .../SpringSessionRedisOperations.java | 2 +- .../http/RedisHttpSessionConfiguration.java | 1 + .../server/RedisWebSessionConfiguration.java | 36 ++-- ...urationOverrideDefaultSerializerTests.java | 1 + .../RedisHttpSessionConfigurationTests.java | 1 + .../RedisWebSessionConfigurationTests.java | 191 +++++++++++++++--- 10 files changed, 195 insertions(+), 45 deletions(-) rename spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/{web/http => }/SpringSessionRedisConnectionFactory.java (99%) rename spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/{web/http => }/SpringSessionRedisOperations.java (99%) diff --git a/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java b/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java index b8eccda5..62ab9cbf 100644 --- a/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java +++ b/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java @@ -27,7 +27,7 @@ import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; -import org.springframework.session.data.redis.config.annotation.web.http.SpringSessionRedisOperations; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java index c2a0fd12..a12b0952 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java @@ -37,8 +37,8 @@ import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.Session; import org.springframework.session.data.SessionEventRegistry; import org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; -import org.springframework.session.data.redis.config.annotation.web.http.SpringSessionRedisOperations; import org.springframework.session.events.SessionCreatedEvent; import org.springframework.session.events.SessionDestroyedEvent; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java index f1e9f007..19df6e8e 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java @@ -31,8 +31,8 @@ import org.springframework.core.task.TaskExecutor; import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.RedisOperations; import org.springframework.session.data.redis.AbstractRedisITests; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; -import org.springframework.session.data.redis.config.annotation.web.http.SpringSessionRedisOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/SpringSessionRedisConnectionFactory.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/SpringSessionRedisConnectionFactory.java similarity index 99% rename from spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/SpringSessionRedisConnectionFactory.java rename to spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/SpringSessionRedisConnectionFactory.java index 20c22b62..a118603e 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/SpringSessionRedisConnectionFactory.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/SpringSessionRedisConnectionFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.session.data.redis.config.annotation.web.http; +package org.springframework.session.data.redis.config.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/SpringSessionRedisOperations.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/SpringSessionRedisOperations.java similarity index 99% rename from spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/SpringSessionRedisOperations.java rename to spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/SpringSessionRedisOperations.java index 5c249a4e..30aac9e8 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/SpringSessionRedisOperations.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/SpringSessionRedisOperations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.session.data.redis.config.annotation.web.http; +package org.springframework.session.data.redis.config.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java index 6d859f96..e180031f 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java @@ -48,6 +48,7 @@ import org.springframework.session.data.redis.RedisFlushMode; import org.springframework.session.data.redis.RedisOperationsSessionRepository; import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; import org.springframework.session.data.redis.config.ConfigureRedisAction; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory; import org.springframework.session.web.http.SessionRepositoryFilter; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java index ac3cead8..bb25f932 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java @@ -18,6 +18,8 @@ package org.springframework.session.data.redis.config.annotation.web.server; import java.util.Map; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -33,6 +35,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.session.config.annotation.web.server.SpringWebSessionConfiguration; import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository; import org.springframework.session.data.redis.RedisFlushMode; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.StringValueResolver; @@ -61,20 +64,19 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE; + private ReactiveRedisConnectionFactory redisConnectionFactory; + private StringValueResolver embeddedValueResolver; @Bean - public ReactiveRedisOperationsSessionRepository sessionRepository( - ReactiveRedisConnectionFactory redisConnectionFactory) { + public ReactiveRedisOperationsSessionRepository sessionRepository() { ReactiveRedisOperationsSessionRepository sessionRepository = new ReactiveRedisOperationsSessionRepository( - createDefaultTemplate(redisConnectionFactory)); + createDefaultTemplate(this.redisConnectionFactory)); sessionRepository .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); - String redisNamespace = getRedisNamespace(); - - if (StringUtils.hasText(redisNamespace)) { - sessionRepository.setRedisKeyNamespace(redisNamespace); + if (StringUtils.hasText(this.redisNamespace)) { + sessionRepository.setRedisKeyNamespace(this.redisNamespace); } sessionRepository.setRedisFlushMode(this.redisFlushMode); @@ -95,6 +97,18 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration this.redisFlushMode = redisFlushMode; } + @Autowired + public void setRedisConnectionFactory( + @SpringSessionRedisConnectionFactory ObjectProvider springSessionRedisConnectionFactory, + ObjectProvider redisConnectionFactory) { + ReactiveRedisConnectionFactory redisConnectionFactoryToUse = springSessionRedisConnectionFactory + .getIfAvailable(); + if (redisConnectionFactoryToUse == null) { + redisConnectionFactoryToUse = redisConnectionFactory.getObject(); + } + this.redisConnectionFactory = redisConnectionFactoryToUse; + } + @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { this.embeddedValueResolver = resolver; @@ -127,12 +141,4 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration return new ReactiveRedisTemplate<>(connectionFactory, serializationContext); } - private String getRedisNamespace() { - if (StringUtils.hasText(this.redisNamespace)) { - return this.redisNamespace; - } - - return System.getProperty("spring.session.redis.namespace", ""); - } - } diff --git a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationOverrideDefaultSerializerTests.java b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationOverrideDefaultSerializerTests.java index 5e481016..47533019 100644 --- a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationOverrideDefaultSerializerTests.java +++ b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationOverrideDefaultSerializerTests.java @@ -28,6 +28,7 @@ import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; diff --git a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationTests.java b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationTests.java index e7d51d7b..8b485b72 100644 --- a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationTests.java +++ b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfigurationTests.java @@ -35,6 +35,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.mock.env.MockEnvironment; import org.springframework.session.data.redis.RedisOperationsSessionRepository; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfigurationTests.java b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfigurationTests.java index 36d031ce..c4116a61 100644 --- a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfigurationTests.java +++ b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfigurationTests.java @@ -18,14 +18,20 @@ package org.springframework.session.data.redis.config.annotation.web.server; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; +import org.springframework.data.redis.core.ReactiveRedisOperations; import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository; import org.springframework.session.data.redis.RedisFlushMode; +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -42,6 +48,9 @@ public class RedisWebSessionConfigurationTests { private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600; + @Rule + public final ExpectedException thrown = ExpectedException.none(); + private AnnotationConfigApplicationContext context; @Before @@ -58,7 +67,7 @@ public class RedisWebSessionConfigurationTests { @Test public void defaultConfiguration() { - registerAndRefresh(RedisConfiguration.class, DefaultConfiguration.class); + registerAndRefresh(RedisConfig.class, DefaultConfig.class); ReactiveRedisOperationsSessionRepository repository = this.context .getBean(ReactiveRedisOperationsSessionRepository.class); @@ -67,7 +76,7 @@ public class RedisWebSessionConfigurationTests { @Test public void customNamespace() { - registerAndRefresh(RedisConfiguration.class, CustomNamespaceConfiguration.class); + registerAndRefresh(RedisConfig.class, CustomNamespaceConfig.class); ReactiveRedisOperationsSessionRepository repository = this.context .getBean(ReactiveRedisOperationsSessionRepository.class); @@ -78,8 +87,7 @@ public class RedisWebSessionConfigurationTests { @Test public void customMaxInactiveInterval() { - registerAndRefresh(RedisConfiguration.class, - CustomMaxInactiveIntervalConfiguration.class); + registerAndRefresh(RedisConfig.class, CustomMaxInactiveIntervalConfig.class); ReactiveRedisOperationsSessionRepository repository = this.context .getBean(ReactiveRedisOperationsSessionRepository.class); @@ -90,7 +98,7 @@ public class RedisWebSessionConfigurationTests { @Test public void customFlushMode() { - registerAndRefresh(RedisConfiguration.class, CustomFlushModeConfiguration.class); + registerAndRefresh(RedisConfig.class, CustomFlushModeConfig.class); ReactiveRedisOperationsSessionRepository repository = this.context .getBean(ReactiveRedisOperationsSessionRepository.class); @@ -99,13 +107,160 @@ public class RedisWebSessionConfigurationTests { .isEqualTo(RedisFlushMode.IMMEDIATE); } + @Test + public void qualifiedConnectionFactoryRedisConfig() { + registerAndRefresh(RedisConfig.class, + QualifiedConnectionFactoryRedisConfig.class); + + ReactiveRedisOperationsSessionRepository repository = this.context + .getBean(ReactiveRedisOperationsSessionRepository.class); + ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean( + "qualifiedRedisConnectionFactory", ReactiveRedisConnectionFactory.class); + assertThat(repository).isNotNull(); + assertThat(redisConnectionFactory).isNotNull(); + ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils + .getField(repository, "sessionRedisOperations"); + assertThat(redisOperations).isNotNull(); + assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory")) + .isEqualTo(redisConnectionFactory); + } + + @Test + public void primaryConnectionFactoryRedisConfig() { + registerAndRefresh(RedisConfig.class, PrimaryConnectionFactoryRedisConfig.class); + + ReactiveRedisOperationsSessionRepository repository = this.context + .getBean(ReactiveRedisOperationsSessionRepository.class); + ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean( + "primaryRedisConnectionFactory", ReactiveRedisConnectionFactory.class); + assertThat(repository).isNotNull(); + assertThat(redisConnectionFactory).isNotNull(); + ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils + .getField(repository, "sessionRedisOperations"); + assertThat(redisOperations).isNotNull(); + assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory")) + .isEqualTo(redisConnectionFactory); + } + + @Test + public void qualifiedAndPrimaryConnectionFactoryRedisConfig() { + registerAndRefresh(RedisConfig.class, + QualifiedAndPrimaryConnectionFactoryRedisConfig.class); + + ReactiveRedisOperationsSessionRepository repository = this.context + .getBean(ReactiveRedisOperationsSessionRepository.class); + ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean( + "qualifiedRedisConnectionFactory", ReactiveRedisConnectionFactory.class); + assertThat(repository).isNotNull(); + assertThat(redisConnectionFactory).isNotNull(); + ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils + .getField(repository, "sessionRedisOperations"); + assertThat(redisOperations).isNotNull(); + assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory")) + .isEqualTo(redisConnectionFactory); + } + + @Test + public void namedConnectionFactoryRedisConfig() { + registerAndRefresh(RedisConfig.class, NamedConnectionFactoryRedisConfig.class); + + ReactiveRedisOperationsSessionRepository repository = this.context + .getBean(ReactiveRedisOperationsSessionRepository.class); + ReactiveRedisConnectionFactory redisConnectionFactory = this.context + .getBean("redisConnectionFactory", ReactiveRedisConnectionFactory.class); + assertThat(repository).isNotNull(); + assertThat(redisConnectionFactory).isNotNull(); + ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils + .getField(repository, "sessionRedisOperations"); + assertThat(redisOperations).isNotNull(); + assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory")) + .isEqualTo(redisConnectionFactory); + } + + @Test + public void multipleConnectionFactoryRedisConfig() { + this.thrown.expect(BeanCreationException.class); + this.thrown.expectMessage("expected single matching bean but found 2"); + + registerAndRefresh(RedisConfig.class, MultipleConnectionFactoryRedisConfig.class); + } + private void registerAndRefresh(Class... annotatedClasses) { this.context.register(annotatedClasses); this.context.refresh(); } @Configuration - static class RedisConfiguration { + static class RedisConfig { + + @Bean + public ReactiveRedisConnectionFactory defaultRedisConnectionFactory() { + return mock(ReactiveRedisConnectionFactory.class); + } + + } + + @EnableRedisWebSession + static class DefaultConfig { + + } + + @EnableRedisWebSession(redisNamespace = REDIS_NAMESPACE) + static class CustomNamespaceConfig { + + } + + @EnableRedisWebSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) + static class CustomMaxInactiveIntervalConfig { + + } + + @EnableRedisWebSession(redisFlushMode = RedisFlushMode.IMMEDIATE) + static class CustomFlushModeConfig { + + } + + @EnableRedisWebSession + static class QualifiedConnectionFactoryRedisConfig { + + @Bean + @SpringSessionRedisConnectionFactory + public ReactiveRedisConnectionFactory qualifiedRedisConnectionFactory() { + return mock(ReactiveRedisConnectionFactory.class); + } + + } + + @EnableRedisWebSession + static class PrimaryConnectionFactoryRedisConfig { + + @Bean + @Primary + public ReactiveRedisConnectionFactory primaryRedisConnectionFactory() { + return mock(ReactiveRedisConnectionFactory.class); + } + + } + + @EnableRedisWebSession + static class QualifiedAndPrimaryConnectionFactoryRedisConfig { + + @Bean + @SpringSessionRedisConnectionFactory + public ReactiveRedisConnectionFactory qualifiedRedisConnectionFactory() { + return mock(ReactiveRedisConnectionFactory.class); + } + + @Bean + @Primary + public ReactiveRedisConnectionFactory primaryRedisConnectionFactory() { + return mock(ReactiveRedisConnectionFactory.class); + } + + } + + @EnableRedisWebSession + static class NamedConnectionFactoryRedisConfig { @Bean public ReactiveRedisConnectionFactory redisConnectionFactory() { @@ -114,27 +269,13 @@ public class RedisWebSessionConfigurationTests { } - @Configuration @EnableRedisWebSession - static class DefaultConfiguration { + static class MultipleConnectionFactoryRedisConfig { - } - - @Configuration - @EnableRedisWebSession(redisNamespace = REDIS_NAMESPACE) - static class CustomNamespaceConfiguration { - - } - - @Configuration - @EnableRedisWebSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class CustomMaxInactiveIntervalConfiguration { - - } - - @Configuration - @EnableRedisWebSession(redisFlushMode = RedisFlushMode.IMMEDIATE) - static class CustomFlushModeConfiguration { + @Bean + public ReactiveRedisConnectionFactory secondaryRedisConnectionFactory() { + return mock(ReactiveRedisConnectionFactory.class); + } }