Allow RedisConnectionFactories to be initialized as part of the context lifecycle.
Lettuce and Jedis connection factories now can be configured to initialize early during afterPropertiesSet or configured whether the component should be auto-started by the container. By default, connection factories auto-startup early. Closes #2866 Original Pull Request: #2868
This commit is contained in:
committed by
Christoph Strobl
parent
779a0126e5
commit
7a94beb467
@@ -78,8 +78,9 @@ import org.springframework.util.ObjectUtils;
|
||||
* This connection factory implements {@link InitializingBean} and {@link SmartLifecycle} for flexible lifecycle
|
||||
* control. It must be {@link #afterPropertiesSet() initialized} and {@link #start() started} before you can obtain a
|
||||
* connection. {@link #afterPropertiesSet() Initialization} {@link SmartLifecycle#start() starts} this bean
|
||||
* {@link #isAutoStartup() by default}. You can {@link SmartLifecycle#stop()} and {@link SmartLifecycle#start() restart}
|
||||
* this connection factory if needed.
|
||||
* {@link #isEarlyStartup() early} by default. You can {@link SmartLifecycle#stop()} and {@link SmartLifecycle#start()
|
||||
* restart} this connection factory if needed. Disabling {@link #isEarlyStartup() early startup} leaves lifecycle
|
||||
* management to the container refresh if {@link #isAutoStartup() auto-startup} is enabled.
|
||||
* <p>
|
||||
* Note that {@link JedisConnection} and its {@link JedisClusterConnection clustered variant} are not Thread-safe and
|
||||
* instances should not be shared across threads. Refer to the
|
||||
@@ -103,9 +104,10 @@ public class JedisConnectionFactory
|
||||
private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new PassThroughExceptionTranslationStrategy(
|
||||
JedisExceptionConverter.INSTANCE);
|
||||
|
||||
private boolean convertPipelineAndTxResults = true;
|
||||
|
||||
private int phase = 0; // in between min and max values
|
||||
private boolean autoStartup = true;
|
||||
private boolean earlyStartup = true;
|
||||
private boolean convertPipelineAndTxResults = true;
|
||||
|
||||
private final AtomicReference<State> state = new AtomicReference<>(State.CREATED);
|
||||
|
||||
@@ -571,6 +573,70 @@ public class JedisConnectionFactory
|
||||
return RedisConfiguration.isClusterConfiguration(configuration) ? (RedisClusterConfiguration) configuration : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the lifecycle phase for pausing and resuming this executor. The default is {@code 0}.
|
||||
*
|
||||
* @since 3.2
|
||||
* @see SmartLifecycle#getPhase()
|
||||
*/
|
||||
public void setPhase(int phase) {
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.3
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return this.autoStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure if this Lifecycle connection factory should get started automatically by the container at the time that
|
||||
* the containing ApplicationContext gets refreshed.
|
||||
* <p>
|
||||
* This connection factory defaults to early auto-startup during {@link #afterPropertiesSet()} and can potentially
|
||||
* create Redis connections early on in the lifecycle. See {@link #setEarlyStartup(boolean)} for delaying connection
|
||||
* creation to the ApplicationContext refresh if auto-startup is enabled.
|
||||
*
|
||||
* @param autoStartup {@literal true} to automatically {@link #start()} the connection factory; {@literal false}
|
||||
* otherwise.
|
||||
* @since 3.3
|
||||
* @see #setEarlyStartup(boolean)
|
||||
* @see #start()
|
||||
*/
|
||||
public void setAutoStartup(boolean autoStartup) {
|
||||
this.autoStartup = autoStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether to {@link #start()} the component during {@link #afterPropertiesSet()}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public boolean isEarlyStartup() {
|
||||
return this.earlyStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure if this InitializingBean's component Lifecycle should get started early by {@link #afterPropertiesSet()}
|
||||
* at the time that the bean is initialized. The component defaults to auto-startup.
|
||||
* <p>
|
||||
* This method is related to {@link #setAutoStartup(boolean) auto-startup} and can be used to delay Redis client
|
||||
* startup until the ApplicationContext refresh. Disabling early startup does not disable auto-startup.
|
||||
*
|
||||
* @param earlyStartup {@literal true} to early {@link #start()} the component; {@literal false} otherwise.
|
||||
* @since 3.3
|
||||
* @see #setAutoStartup(boolean)
|
||||
*/
|
||||
public void setEarlyStartup(boolean earlyStartup) {
|
||||
this.earlyStartup = earlyStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if pipelined results should be converted to the expected data type. If {@code false}, results of
|
||||
* {@link JedisConnection#closePipeline()} and {@link JedisConnection#exec()} will be of the type returned by the
|
||||
@@ -616,7 +682,7 @@ public class JedisConnectionFactory
|
||||
|
||||
this.clientConfig = createClientConfig(getDatabase(), getRedisUsername(), getRedisPassword());
|
||||
|
||||
if (isAutoStartup()) {
|
||||
if (isEarlyStartup()) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
@@ -724,21 +790,6 @@ public class JedisConnectionFactory
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the lifecycle phase for pausing and resuming this executor. The default is {@code 0}.
|
||||
*
|
||||
* @since 3.2
|
||||
* @see SmartLifecycle#getPhase()
|
||||
*/
|
||||
public void setPhase(int phase) {
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return State.STARTED.equals(this.state.get());
|
||||
|
||||
@@ -100,8 +100,9 @@ import org.springframework.util.StringUtils;
|
||||
* This connection factory implements {@link InitializingBean} and {@link SmartLifecycle} for flexible lifecycle
|
||||
* control. It must be {@link #afterPropertiesSet() initialized} and {@link #start() started} before you can obtain a
|
||||
* connection. {@link #afterPropertiesSet() Initialization} {@link SmartLifecycle#start() starts} this bean
|
||||
* {@link #isAutoStartup() by default}. You can {@link SmartLifecycle#stop()} and {@link SmartLifecycle#start() restart}
|
||||
* this connection factory if needed.
|
||||
* {@link #isEarlyStartup() early} by default. You can {@link SmartLifecycle#stop()} and {@link SmartLifecycle#start()
|
||||
* restart} this connection factory if needed. Disabling {@link #isEarlyStartup() early startup} leaves lifecycle
|
||||
* management to the container refresh if {@link #isAutoStartup() auto-startup} is enabled.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Jennifer Hickey
|
||||
@@ -121,13 +122,14 @@ public class LettuceConnectionFactory implements RedisConnectionFactory, Reactiv
|
||||
private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new PassThroughExceptionTranslationStrategy(
|
||||
LettuceExceptionConverter.INSTANCE);
|
||||
|
||||
private int phase = 0; // in between min and max values
|
||||
private boolean autoStartup = true;
|
||||
private boolean earlyStartup = true;
|
||||
private boolean convertPipelineAndTxResults = true;
|
||||
private boolean eagerInitialization = false;
|
||||
|
||||
private boolean shareNativeConnection = true;
|
||||
private boolean validateConnection = false;
|
||||
|
||||
private int phase = 0; // in between min and max values
|
||||
|
||||
private @Nullable AbstractRedisClient client;
|
||||
|
||||
private final AtomicReference<State> state = new AtomicReference<>(State.CREATED);
|
||||
@@ -556,12 +558,13 @@ public class LettuceConnectionFactory implements RedisConnectionFactory, Reactiv
|
||||
|
||||
/**
|
||||
* Indicates {@link #setShareNativeConnection(boolean) shared connections} should be eagerly initialized. Eager
|
||||
* initialization requires a running Redis instance during application startup to allow early validation of connection
|
||||
* factory configuration. Eager initialization also prevents blocking connect while using reactive API and is
|
||||
* recommended for reactive API usage.
|
||||
* initialization requires a running Redis instance during {@link #start() startup} to allow early validation of
|
||||
* connection factory configuration. Eager initialization also prevents blocking connect while using reactive API and
|
||||
* is recommended for reactive API usage.
|
||||
*
|
||||
* @return {@link true} if the shared connection is initialized upon {@link #afterPropertiesSet()}.
|
||||
* @return {@link true} if the shared connection is initialized upon {@link #start()}.
|
||||
* @since 2.2
|
||||
* @see #start()
|
||||
*/
|
||||
public boolean getEagerInitialization() {
|
||||
return this.eagerInitialization;
|
||||
@@ -795,6 +798,70 @@ public class LettuceConnectionFactory implements RedisConnectionFactory, Reactiv
|
||||
return isClusterAware() ? (RedisClusterConfiguration) this.configuration : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the lifecycle phase for pausing and resuming this executor. The default is {@code 0}.
|
||||
*
|
||||
* @since 3.2
|
||||
* @see SmartLifecycle#getPhase()
|
||||
*/
|
||||
public void setPhase(int phase) {
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.3
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return this.autoStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure if this Lifecycle connection factory should get started automatically by the container at the time that
|
||||
* the containing ApplicationContext gets refreshed.
|
||||
* <p>
|
||||
* This connection factory defaults to early auto-startup during {@link #afterPropertiesSet()} and can potentially
|
||||
* create Redis connections early on in the lifecycle. See {@link #setEarlyStartup(boolean)} for delaying connection
|
||||
* creation to the ApplicationContext refresh if auto-startup is enabled.
|
||||
*
|
||||
* @param autoStartup {@literal true} to automatically {@link #start()} the connection factory; {@literal false}
|
||||
* otherwise.
|
||||
* @since 3.3
|
||||
* @see #setEarlyStartup(boolean)
|
||||
* @see #start()
|
||||
*/
|
||||
public void setAutoStartup(boolean autoStartup) {
|
||||
this.autoStartup = autoStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether to {@link #start()} the component during {@link #afterPropertiesSet()}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public boolean isEarlyStartup() {
|
||||
return this.earlyStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure if this InitializingBean's component Lifecycle should get started early by {@link #afterPropertiesSet()}
|
||||
* at the time that the bean is initialized. The component defaults to auto-startup.
|
||||
* <p>
|
||||
* This method is related to {@link #setAutoStartup(boolean) auto-startup} and can be used to delay Redis client
|
||||
* startup until the ApplicationContext refresh. Disabling early startup does not disable auto-startup.
|
||||
*
|
||||
* @param earlyStartup {@literal true} to early {@link #start()} the component; {@literal false} otherwise.
|
||||
* @since 3.3
|
||||
* @see #setAutoStartup(boolean)
|
||||
*/
|
||||
public void setEarlyStartup(boolean earlyStartup) {
|
||||
this.earlyStartup = earlyStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if pipelined results should be converted to the expected data type. If {@code false}, results of
|
||||
* {@link LettuceConnection#closePipeline()} and {LettuceConnection#exec()} will be of the type returned by the
|
||||
@@ -924,21 +991,6 @@ public class LettuceConnectionFactory implements RedisConnectionFactory, Reactiv
|
||||
state.set(State.STOPPED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the lifecycle phase for pausing and resuming this executor. The default is {@code 0}.
|
||||
*
|
||||
* @since 3.2
|
||||
* @see SmartLifecycle#getPhase()
|
||||
*/
|
||||
public void setPhase(int phase) {
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return State.STARTED.equals(this.state.get());
|
||||
@@ -947,7 +999,7 @@ public class LettuceConnectionFactory implements RedisConnectionFactory, Reactiv
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (isAutoStartup()) {
|
||||
if (isEarlyStartup()) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user