Allow configuration of RedisMessageListenerContainer through @EnableRedisRepositories.
We now support configuration of a bean reference to RedisMessageListenerContainer that should be used with `RedisKeyValueAdapter` for easier configuration of the listener container. Closes #1827
This commit is contained in:
@@ -112,6 +112,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
private RedisOperations<?, ?> redisOps;
|
||||
private RedisConverter converter;
|
||||
private @Nullable RedisMessageListenerContainer messageListenerContainer;
|
||||
private boolean managedListenerContainer = true;
|
||||
private final AtomicReference<KeyExpirationEventMessageListener> expirationListener = new AtomicReference<>(null);
|
||||
private @Nullable ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@@ -179,7 +180,6 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
this.converter = redisConverter;
|
||||
this.redisOps = redisOps;
|
||||
initMessageListenerContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,7 +216,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
connection.hMSet(objectKey, rdo.getBucket().rawMap());
|
||||
|
||||
if(isNew) {
|
||||
if (isNew) {
|
||||
connection.sAdd(toBytes(rdo.getKeyspace()), key);
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
connection.sRem(binKeyspace, binId);
|
||||
new IndexWriter(connection, converter).removeKeyFromIndexes(asString(keyspace), binId);
|
||||
|
||||
if(RedisKeyValueAdapter.this.keepShadowCopy()) {
|
||||
if (RedisKeyValueAdapter.this.keepShadowCopy()) {
|
||||
|
||||
RedisPersistentEntity<?> persistentEntity = converter.getMappingContext().getPersistentEntity(type);
|
||||
if (persistentEntity != null && persistentEntity.isExpiring()) {
|
||||
@@ -464,7 +464,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
connection.persist(redisKey);
|
||||
|
||||
if(keepShadowCopy()) {
|
||||
if (keepShadowCopy()) {
|
||||
connection.del(ByteUtils.concat(redisKey, BinaryKeyspaceIdentifier.PHANTOM_SUFFIX));
|
||||
}
|
||||
}
|
||||
@@ -625,7 +625,6 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@link RedisData#getTimeToLive()} has a positive value.
|
||||
*
|
||||
* @param data must not be {@literal null}.
|
||||
* @since 2.3.7
|
||||
*/
|
||||
@@ -643,6 +642,28 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
this.enableKeyspaceEvents = enableKeyspaceEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a {@link RedisMessageListenerContainer} to listen for Keyspace expiry events. The container can only be
|
||||
* set when this bean hasn't been yet {@link #afterPropertiesSet() initialized}.
|
||||
*
|
||||
* @param messageListenerContainer the container to use.
|
||||
* @since 2.7.2
|
||||
* @throws IllegalStateException when trying to set a {@link RedisMessageListenerContainer} after
|
||||
* {@link #afterPropertiesSet()} has been called to initialize a managed container instance.
|
||||
*/
|
||||
public void setMessageListenerContainer(RedisMessageListenerContainer messageListenerContainer) {
|
||||
|
||||
Assert.notNull(messageListenerContainer, "RedisMessageListenerContainer must not be null");
|
||||
|
||||
if (this.managedListenerContainer && this.messageListenerContainer != null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot set RedisMessageListenerContainer after initializing a managed RedisMessageListenerContainer instance");
|
||||
}
|
||||
|
||||
this.managedListenerContainer = false;
|
||||
this.messageListenerContainer = messageListenerContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the {@literal notify-keyspace-events} property if not already set. Use an empty {@link String} or
|
||||
* {@literal null} to retain existing server settings.
|
||||
@@ -671,6 +692,10 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (this.managedListenerContainer) {
|
||||
initMessageListenerContainer();
|
||||
}
|
||||
|
||||
if (ObjectUtils.nullSafeEquals(EnableKeyspaceEvents.ON_STARTUP, this.enableKeyspaceEvents)) {
|
||||
initKeyExpirationListener();
|
||||
}
|
||||
@@ -682,8 +707,9 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
this.expirationListener.get().destroy();
|
||||
}
|
||||
|
||||
if (this.messageListenerContainer != null) {
|
||||
if (this.managedListenerContainer && this.messageListenerContainer != null) {
|
||||
this.messageListenerContainer.destroy();
|
||||
this.messageListenerContainer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +167,16 @@ public @interface EnableRedisRepositories {
|
||||
*/
|
||||
EnableKeyspaceEvents enableKeyspaceEvents() default EnableKeyspaceEvents.OFF;
|
||||
|
||||
/**
|
||||
* Configure the name of the {@link org.springframework.data.redis.listener.RedisMessageListenerContainer} bean to be
|
||||
* used for keyspace event subscriptions. Defaults to use an anonymous managed instance by
|
||||
* {@link org.springframework.data.redis.core.RedisKeyValueAdapter}.
|
||||
*
|
||||
* @return
|
||||
* @since 2.7.2
|
||||
*/
|
||||
String messageListenerContainerRef() default "";
|
||||
|
||||
/**
|
||||
* Configuration flag controlling storage of phantom keys (shadow copies) of expiring entities to read them later when
|
||||
* publishing {@link org.springframework.data.redis.core.RedisKeyspaceEvent keyspace events}.
|
||||
|
||||
@@ -138,15 +138,19 @@ public class RedisRepositoryConfigurationExtension extends KeyValueRepositoryCon
|
||||
|
||||
private static AbstractBeanDefinition createRedisKeyValueAdapter(RepositoryConfigurationSource configuration) {
|
||||
|
||||
return BeanDefinitionBuilder.rootBeanDefinition(RedisKeyValueAdapter.class) //
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(RedisKeyValueAdapter.class) //
|
||||
.addConstructorArgReference(configuration.getRequiredAttribute("redisTemplateRef", String.class)) //
|
||||
.addConstructorArgReference(REDIS_CONVERTER_BEAN_NAME) //
|
||||
.addPropertyValue("enableKeyspaceEvents",
|
||||
configuration.getRequiredAttribute("enableKeyspaceEvents", EnableKeyspaceEvents.class)) //
|
||||
.addPropertyValue("keyspaceNotificationsConfigParameter",
|
||||
configuration.getAttribute("keyspaceNotificationsConfigParameter", String.class).orElse("")) //
|
||||
.addPropertyValue("shadowCopy", configuration.getRequiredAttribute("shadowCopy", ShadowCopy.class)) //
|
||||
.getBeanDefinition();
|
||||
.addPropertyValue("shadowCopy", configuration.getRequiredAttribute("shadowCopy", ShadowCopy.class));
|
||||
|
||||
configuration.getAttribute("messageListenerContainerRef")
|
||||
.ifPresent(it -> builder.addPropertyReference("messageListenerContainer", it));
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private static AbstractBeanDefinition createRedisReferenceResolverDefinition(String redisTemplateRef) {
|
||||
|
||||
Reference in New Issue
Block a user