diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnectionFactory.java b/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnectionFactory.java index e9bd578f9..af3eb469e 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnectionFactory.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnectionFactory.java @@ -32,13 +32,15 @@ public interface ReactiveRedisConnectionFactory extends PersistenceExceptionTran /** * @return a reactive Redis connection. - * @since 2.0. + * @throws IllegalStateException if the connection factory requires initialization and the factory was not yet + * initialized. */ ReactiveRedisConnection getReactiveConnection(); /** * @return a reactive Redis Cluster connection. - * @since 2.0 + * @throws IllegalStateException if the connection factory requires initialization and the factory was not yet + * initialized. */ ReactiveRedisClusterConnection getReactiveClusterConnection(); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisConnectionFactory.java b/src/main/java/org/springframework/data/redis/connection/RedisConnectionFactory.java index bcc5d7f07..85cb649c3 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisConnectionFactory.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisConnectionFactory.java @@ -30,6 +30,8 @@ public interface RedisConnectionFactory extends PersistenceExceptionTranslator { * Provides a suitable connection for interacting with Redis. * * @return connection for interacting with Redis. + * @throws IllegalStateException if the connection factory requires initialization and the factory was not yet + * initialized. */ RedisConnection getConnection(); @@ -37,6 +39,8 @@ public interface RedisConnectionFactory extends PersistenceExceptionTranslator { * Provides a suitable connection for interacting with Redis Cluster. * * @return + * @throws IllegalStateException if the connection factory requires initialization and the factory was not yet + * initialized. * @since 1.7 */ RedisClusterConnection getClusterConnection(); @@ -55,6 +59,8 @@ public interface RedisConnectionFactory extends PersistenceExceptionTranslator { * Provides a suitable connection for interacting with Redis Sentinel. * * @return connection for interacting with Redis Sentinel. + * @throws IllegalStateException if the connection factory requires initialization and the factory was not yet + * initialized. * @since 1.4 */ RedisSentinelConnection getSentinelConnection(); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java index 397b4ab18..f09edff5a 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java @@ -73,6 +73,9 @@ import org.springframework.util.StringUtils; *
+ * This connection factory must be {@link #afterPropertiesSet() initialized} prior to {@link #getConnection obtaining
+ * connections}.
*
* @author Costin Leau
* @author Thomas Darimont
@@ -104,6 +107,9 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
private @Nullable ClusterTopologyProvider topologyProvider;
private @Nullable ClusterCommandExecutor clusterCommandExecutor;
+ private boolean initialized;
+ private boolean destroyed;
+
/**
* Constructs a new JedisConnectionFactory instance with default settings (default connection pooling, no
* shard information).
@@ -350,6 +356,8 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
new JedisClusterConnection.JedisClusterNodeResourceProvider(this.cluster, this.topologyProvider),
EXCEPTION_TRANSLATION);
}
+
+ this.initialized = true;
}
private JedisClientConfig createClientConfig(@Nullable String username, RedisPassword password) {
@@ -484,6 +492,8 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
log.warn("Cannot properly close cluster command executor", ex);
}
}
+
+ this.destroyed = true;
}
/*
@@ -492,6 +502,8 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
*/
public RedisConnection getConnection() {
+ assertInitialized();
+
if (isRedisClusterAware()) {
return getClusterConnection();
}
@@ -517,6 +529,8 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
@Override
public RedisClusterConnection getClusterConnection() {
+ assertInitialized();
+
if (!isRedisClusterAware()) {
throw new InvalidDataAccessApiUsageException("Cluster is not configured!");
}
@@ -876,6 +890,8 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
@Override
public RedisSentinelConnection getSentinelConnection() {
+ assertInitialized();
+
if (!isRedisSentinelAware()) {
throw new InvalidDataAccessResourceUsageException("No Sentinels configured");
}
@@ -945,6 +961,11 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
return (MutableJedisClientConfiguration) clientConfiguration;
}
+ private void assertInitialized() {
+ Assert.state(this.initialized, "JedisConnectionFactory was not initialized through afterPropertiesSet()");
+ Assert.state(!this.destroyed, "JedisConnectionFactory was destroyed and cannot be used anymore");
+ }
+
/**
* Mutable implementation of {@link JedisClientConfiguration}.
*
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java
index 5f2ab8cfc..e04f45bac 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java
@@ -84,6 +84,9 @@ import org.springframework.util.StringUtils;
*
+ * This connection factory must be {@link #afterPropertiesSet() initialized} prior to {@link #getConnection obtaining
+ * connections}.
*
* @author Costin Leau
* @author Jennifer Hickey
@@ -124,6 +127,9 @@ public class LettuceConnectionFactory
private @Nullable ClusterCommandExecutor clusterCommandExecutor;
+ private boolean initialized;
+ private boolean destroyed;
+
/**
* Constructs a new {@link LettuceConnectionFactory} instance with default settings.
*/
@@ -293,6 +299,8 @@ public class LettuceConnectionFactory
EXCEPTION_TRANSLATION);
}
+ this.initialized = true;
+
if (getEagerInitialization() && getShareNativeConnection()) {
initConnection();
}
@@ -329,6 +337,8 @@ public class LettuceConnectionFactory
log.warn("Cannot properly close cluster command executor", ex);
}
}
+
+ this.destroyed = true;
}
private void dispose(LettuceConnectionProvider connectionProvider) {
@@ -351,6 +361,8 @@ public class LettuceConnectionFactory
*/
public RedisConnection getConnection() {
+ assertInitialized();
+
if (isClusterAware()) {
return getClusterConnection();
}
@@ -368,6 +380,8 @@ public class LettuceConnectionFactory
@Override
public RedisClusterConnection getClusterConnection() {
+ assertInitialized();
+
if (!isClusterAware()) {
throw new InvalidDataAccessApiUsageException("Cluster is not configured!");
}
@@ -437,6 +451,8 @@ public class LettuceConnectionFactory
@Override
public LettuceReactiveRedisConnection getReactiveConnection() {
+ assertInitialized();
+
if (isClusterAware()) {
return getReactiveClusterConnection();
}
@@ -453,6 +469,8 @@ public class LettuceConnectionFactory
@Override
public LettuceReactiveRedisClusterConnection getReactiveClusterConnection() {
+ assertInitialized();
+
if (!isClusterAware()) {
throw new InvalidDataAccessApiUsageException("Cluster is not configured!");
}
@@ -481,6 +499,8 @@ public class LettuceConnectionFactory
*/
public void resetConnection() {
+ assertInitialized();
+
Optionals.toStream(Optional.ofNullable(connection), Optional.ofNullable(reactiveConnection))
.forEach(SharedConnection::resetConnection);
@@ -496,6 +516,8 @@ public class LettuceConnectionFactory
*/
public void validateConnection() {
+ assertInitialized();
+
getOrCreateSharedConnection().validateConnection();
getOrCreateSharedReactiveConnection().validateConnection();
}
@@ -801,6 +823,7 @@ public class LettuceConnectionFactory
*/
@Nullable
public AbstractRedisClient getNativeClient() {
+ assertInitialized();
return this.client;
}
@@ -1167,6 +1190,11 @@ public class LettuceConnectionFactory
return redisUri;
}
+ private void assertInitialized() {
+ Assert.state(this.initialized, "LettuceConnectionFactory was not initialized through afterPropertiesSet()");
+ Assert.state(!this.destroyed, "LettuceConnectionFactory was destroyed and cannot be used anymore");
+ }
+
private static void applyToAll(RedisURI source, Consumer