diff --git a/pom.xml b/pom.xml
index 8e149f902c..e1587487f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-redis
- 2.3.0.BUILD-SNAPSHOT
+ 2.3.0.DATAREDIS-1075-SNAPSHOT
Spring Data Redis
diff --git a/src/main/asciidoc/reference/redis-repositories.adoc b/src/main/asciidoc/reference/redis-repositories.adoc
index 9f5ab7b891..a44bd60770 100644
--- a/src/main/asciidoc/reference/redis-repositories.adoc
+++ b/src/main/asciidoc/reference/redis-repositories.adoc
@@ -581,7 +581,8 @@ The repository implementation ensures subscription to https://redis.io/topics/no
When the expiration is set to a positive value, the corresponding `EXPIRE` command is executed. In addition to persisting the original, a phantom copy is persisted in Redis and set to expire five minutes after the original one. This is done to enable the Repository support to publish `RedisKeyExpiredEvent`, holding the expired value in Spring's `ApplicationEventPublisher` whenever a key expires, even though the original values have already been removed. Expiry events are received on all connected applications that use Spring Data Redis repositories.
-By default, the key expiry listener is disabled when initializing the application. The startup mode can be adjusted in `@EnableRedisRepositories` or `RedisKeyValueAdapter` to start the listener with the application or upon the first insert of an entity with a TTL. See https://docs.spring.io/spring-data/redis/docs/{revnumber}/api/org/springframework/data/redis/core/RedisKeyValueAdapter.EnableKeyspaceEvents.html[`EnableKeyspaceEvents`] for possible values.
+By default, the key expiry listener is disabled when initializing the application.
+The startup mode can be adjusted via `@EnableKeyspaceNotifications` or `RedisKeyValueAdapter` to start the listener with the application or upon the first insert of an entity with a TTL. See https://docs.spring.io/spring-data/redis/docs/{revnumber}/api/org/springframework/data/redis/core/RedisKeyValueAdapter.EnableKeyspaceEvents.html[`EnableKeyspaceEvents`] for possible values.
The `RedisKeyExpiredEvent` holds a copy of the expired domain object as well as the key.
diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java
index a8ea1e2ac9..46505b4d58 100644
--- a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java
+++ b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java
@@ -110,8 +110,8 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
private final AtomicReference expirationListener = new AtomicReference<>(null);
private @Nullable ApplicationEventPublisher eventPublisher;
- private EnableKeyspaceEvents enableKeyspaceEvents = EnableKeyspaceEvents.OFF;
- private @Nullable String keyspaceNotificationsConfigParameter = null;
+ private RedisKeyspaceNotificationsConfig keyspaceNotificationsConfig = new RedisKeyspaceNotificationsConfig(
+ EnableKeyspaceEvents.OFF, null);
/**
* Creates new {@link RedisKeyValueAdapter} with default {@link RedisMappingContext} and default
@@ -208,8 +208,8 @@ public Object put(final Object id, Object item, String keyspace) {
converter.write(item, rdo);
}
- if (ObjectUtils.nullSafeEquals(EnableKeyspaceEvents.ON_DEMAND, enableKeyspaceEvents)
- && this.expirationListener.get() == null) {
+ if (ObjectUtils.nullSafeEquals(EnableKeyspaceEvents.ON_DEMAND,
+ keyspaceNotificationsConfig.getEnableKeyspaceEvents()) && this.expirationListener.get() == null) {
if (rdo.getTimeToLive() != null && rdo.getTimeToLive() > 0) {
initKeyExpirationListener();
@@ -636,7 +636,7 @@ private T readBackTimeToLiveIfSet(@Nullable byte[] key, @Nullable T target)
* @since 1.8
*/
public void setEnableKeyspaceEvents(EnableKeyspaceEvents enableKeyspaceEvents) {
- this.enableKeyspaceEvents = enableKeyspaceEvents;
+ this.keyspaceNotificationsConfig.setEnableKeyspaceEvents(enableKeyspaceEvents);
}
/**
@@ -647,7 +647,17 @@ public void setEnableKeyspaceEvents(EnableKeyspaceEvents enableKeyspaceEvents) {
* @since 1.8
*/
public void setKeyspaceNotificationsConfigParameter(String keyspaceNotificationsConfigParameter) {
- this.keyspaceNotificationsConfigParameter = keyspaceNotificationsConfigParameter;
+ this.keyspaceNotificationsConfig.setKeyspaceNotificationsConfigParameter(keyspaceNotificationsConfigParameter);
+ }
+
+ /**
+ * Configure the database from which to receive keyspace notifications. Use a negative value for all databases.
+ *
+ * @param database the database index to listen for keyspace notifications. Negative value for all.
+ * @since 2.3
+ */
+ public void setKeyspaceNotificationsDatabase(int database) {
+ this.keyspaceNotificationsConfig.setDatabase(database);
}
/**
@@ -657,7 +667,8 @@ public void setKeyspaceNotificationsConfigParameter(String keyspaceNotifications
@Override
public void afterPropertiesSet() {
- if (ObjectUtils.nullSafeEquals(EnableKeyspaceEvents.ON_STARTUP, this.enableKeyspaceEvents)) {
+ if (ObjectUtils.nullSafeEquals(EnableKeyspaceEvents.ON_STARTUP,
+ this.keyspaceNotificationsConfig.getEnableKeyspaceEvents())) {
initKeyExpirationListener();
}
}
@@ -707,10 +718,10 @@ private void initKeyExpirationListener() {
if (this.expirationListener.get() == null) {
- MappingExpirationListener listener = new MappingExpirationListener(this.messageListenerContainer, this.redisOps,
- this.converter);
- listener.setKeyspaceNotificationsConfigParameter(keyspaceNotificationsConfigParameter);
-
+ MappingExpirationListener listener = new MappingExpirationListener(this.keyspaceNotificationsConfig.getDatabase(),
+ this.messageListenerContainer, this.redisOps, this.converter);
+ listener.setKeyspaceNotificationsConfigParameter(
+ keyspaceNotificationsConfig.getKeyspaceNotificationsConfigParameter());
if (this.eventPublisher != null) {
listener.setApplicationEventPublisher(this.eventPublisher);
}
@@ -737,14 +748,15 @@ static class MappingExpirationListener extends KeyExpirationEventMessageListener
/**
* Creates new {@link MappingExpirationListener}.
*
+ * @param database The database to listen to for expiration events. Use {@literal null} or a nevative value for all.
* @param listenerContainer
* @param ops
* @param converter
*/
- MappingExpirationListener(RedisMessageListenerContainer listenerContainer, RedisOperations, ?> ops,
- RedisConverter converter) {
+ MappingExpirationListener(Integer database, RedisMessageListenerContainer listenerContainer,
+ RedisOperations, ?> ops, RedisConverter converter) {
- super(listenerContainer);
+ super(listenerContainer, database);
this.ops = ops;
this.converter = converter;
}
@@ -762,7 +774,8 @@ public void onMessage(Message message, @Nullable byte[] pattern) {
byte[] key = message.getBody();
- byte[] phantomKey = ByteUtils.concat(key, converter.getConversionService().convert(KeyspaceIdentifier.PHANTOM_SUFFIX, byte[].class));
+ byte[] phantomKey = ByteUtils.concat(key,
+ converter.getConversionService().convert(KeyspaceIdentifier.PHANTOM_SUFFIX, byte[].class));
Map hash = ops.execute((RedisCallback