DATAREDIS-619 - Polishing.
Add dedicated section on executing lua scripts via the reactive infrastructure, rephrase some other parts adapt non-Javadoc comments to code style. Original Pull Request: #280
This commit is contained in:
@@ -7,7 +7,7 @@ This section covers reactive Redis support and how to get started. You will find
|
||||
[[redis:reactive:requirements]]
|
||||
== Redis Requirements
|
||||
|
||||
Spring Redis requires Redis 2.6 or above and Java SE 8.0 or above. In terms of language bindings (or connectors), Spring Data Redis integrates with http://github.com/lettuce-io/lettuce-core[Lettuce] as the only reactive Java connector. Spring Data Redis uses https://projectreactor.io/[Project Reactor] as reactive composition library.
|
||||
Spring Data Redis requires Redis 2.6 or above and Java SE 8.0 or above. In terms of language bindings (or connectors), Spring Data Redis currently integrates with http://github.com/lettuce-io/lettuce-core[Lettuce] as the only reactive Java connector. https://projectreactor.io/[Project Reactor] is used as reactive composition library.
|
||||
|
||||
[[redis:reactive:connectors]]
|
||||
== Connecting to Redis using a reactive driver
|
||||
@@ -17,13 +17,13 @@ One of the first tasks when using Redis and Spring is to connect to the store th
|
||||
[[redis:reactive:connectors:operation-modes]]
|
||||
=== Redis Operation Modes
|
||||
|
||||
Redis can be run as Standalone server, with <<redis:sentinel,Redis Sentinel>> or in <<cluster,Redis Cluster>> mode.
|
||||
Redis can be run as standalone server, with <<redis:sentinel,Redis Sentinel>> or in <<cluster,Redis Cluster>> mode.
|
||||
http://github.com/lettuce-io/lettuce-core[Lettuce] supports all above mentioned connection types.
|
||||
|
||||
[[redis:reactive:connectors:connection]]
|
||||
=== ReactiveRedisConnection and ReactiveRedisConnectionFactory
|
||||
|
||||
`ReactiveRedisConnection` provides the building block for Redis communication as it handles the communication with the Redis back-end. It also automatically translates the underlying connecting library exceptions to Spring's consistent DAO exception http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/data-access.html#dao-exceptions[hierarchy] so one can switch the connectors without any code changes as the operation semantics remain the same.
|
||||
`ReactiveRedisConnection` provides the building block for Redis communication as it handles the communication with the Redis back-end. It also automatically translates the underlying driver exceptions to Spring's consistent DAO exception http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/data-access.html#dao-exceptions[hierarchy] so one can switch the connectors without any code changes as the operation semantics remain the same.
|
||||
|
||||
Active ``ReactiveRedisConnection``s are created through `ReactiveRedisConnectionFactory`. In addition, the factories act as ``PersistenceExceptionTranslator``s, meaning once declared, they allow one to do transparent exception translation. For example, exception translation through the use of the `@Repository` annotation and AOP. For more information see the dedicated http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/data-access.html#orm-exception-translation[section] in Spring Framework documentation.
|
||||
|
||||
@@ -34,45 +34,43 @@ The easiest way to work with a `ReactiveRedisConnectionFactory` is to configure
|
||||
[[redis:reactive:connectors:lettuce]]
|
||||
=== Configuring Lettuce connector
|
||||
|
||||
https://github.com/lettuce-io/lettuce-core[Lettuce] is a http://netty.io/[netty]-based open-source connector supported by Spring Data Redis through the `org.springframework.data.redis.connection.lettuce` package.
|
||||
https://github.com/lettuce-io/lettuce-core[Lettuce] is supported by Spring Data Redis through the `org.springframework.data.redis.connection.lettuce` package.
|
||||
|
||||
Its configuration is probably easy to guess:
|
||||
Setting up `ReactiveRedisConnectionFactory` for Lettuce can be done as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public ReactiveRedisConnectionFactory lettuceConnectionFactory() {
|
||||
public ReactiveRedisConnectionFactory connectionFactory() {
|
||||
return new LettuceConnectionFactory("localhost", 6379);
|
||||
}
|
||||
----
|
||||
|
||||
A more sophisticated configuration could look like:
|
||||
A more sophisticated configuration, including SSL and timeouts, using `LettuceClientConfigurationBuilder` might look like below:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public ReactiveRedisConnectionFactory lettuceConnectionFactory() {
|
||||
|
||||
RedisStandaloneConfiguration standalone = new RedisStandaloneConfiguration("localhost", 6379);
|
||||
|
||||
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
|
||||
.useSsl().and()
|
||||
.commandTimeout(Duration.ofSeconds(2))
|
||||
.shutdownTimeout(Duration.ZERO)
|
||||
.build();
|
||||
|
||||
return new LettuceConnectionFactory(standalone, clientConfig);
|
||||
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379), clientConfig);
|
||||
}
|
||||
----
|
||||
|
||||
There are also a few Lettuce-specific connection parameters that can be tweaked. See `LettuceClientConfiguration` for more details.
|
||||
For more detailed client configuration tweaks have a look at `LettuceClientConfiguration`.
|
||||
|
||||
[[redis:reactive:template]]
|
||||
== Working with Objects through ReactiveRedisTemplate
|
||||
|
||||
Most users are likely to use `ReactiveRedisTemplate` and its corresponding package `org.springframework.data.redis.core` - the template is in fact the central class of the Redis module due to its rich feature set. The template offers a high-level abstraction for Redis interactions. While `ReactiveRedisConnection` offers low level methods that accept and return binary values (`ByteBuffer`), the template takes care of serialization and connection management, freeing the user from dealing with such details.
|
||||
|
||||
Moreover, the template provides operations views (following the grouping from Redis command http://redis.io/commands[reference]) that offer rich, generified interfaces for working against a certain type as described below:
|
||||
Moreover, the template provides operation views (following the grouping from Redis command http://redis.io/commands[reference]) that offer rich, generified interfaces for working against a certain type as described below:
|
||||
|
||||
.Operational views
|
||||
[width="80%",cols="<1,<2",options="header"]
|
||||
@@ -106,7 +104,7 @@ Moreover, the template provides operations views (following the grouping from Re
|
||||
|
||||
Once configured, the template is thread-safe and can be reused across multiple instances.
|
||||
|
||||
Out of the box, `ReactiveRedisTemplate` uses a Java-based serializer for most of its operations. This means that any object written or read by the template will be serialized/deserialized through Java throug `RedisElementWriter` respective `RedisElementReader`. The serialization context is passed to the template upon construction, and the Redis module offers several implementations available in the `org.springframework.data.redis.serializer` package - see <<redis:serializer>> for more information.
|
||||
Out of the box, `ReactiveRedisTemplate` uses a Java-based serializer for most of its operations. This means that any object written or read by the template will be serialized/deserialized through `RedisElementWriter` respective `RedisElementReader`. The serialization context is passed to the template upon construction, and the Redis module offers several implementations available in the `org.springframework.data.redis.serializer` package - see <<redis:serializer>> for more information.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -124,15 +122,36 @@ class RedisConfiguration {
|
||||
----
|
||||
public class Example {
|
||||
|
||||
// inject the actual template
|
||||
@Autowired
|
||||
private ReactiveRedisTemplate<String, String> template;
|
||||
|
||||
|
||||
public Mono<Long> addLink(String userId, URL url) {
|
||||
return template.opsForList().leftPush(userId, url.toExternalForm());
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
== Reactive Scripting
|
||||
|
||||
Executing Redis scripts via the reactive infrastructure can be done using the `ReactiveScriptExecutor` accessed best via `ReactiveRedisTemplate`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public class Example {
|
||||
|
||||
@Autowired
|
||||
private ReactiveRedisTemplate<String, String> template;
|
||||
|
||||
public Flux<Long> theAnswerToLife() {
|
||||
|
||||
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
|
||||
script.setLocation(new ClassPathResource("META-INF/scripts/42.lua"));
|
||||
script.setResultType(Long.class);
|
||||
|
||||
return reactiveTemplate.execute(script);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Please refer to the <<scripting,scripting section>> for more details on scripting commands.
|
||||
|
||||
|
||||
@@ -102,7 +102,6 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Execution methods
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -198,7 +197,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
// Methods dealing with Redis keys
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#hasKey(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -209,7 +209,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().exists(rawKey(key)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#type(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -220,7 +221,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().type(rawKey(key)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#keys(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -233,7 +235,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
.map(this::readKey);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#randomKey()
|
||||
*/
|
||||
@Override
|
||||
@@ -241,7 +244,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().randomKey()).map(this::readKey);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#rename(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -253,7 +257,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().rename(rawKey(oldKey), rawKey(newKey)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#renameIfAbsent(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -265,7 +270,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().renameNX(rawKey(oldKey), rawKey(newKey)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#delete(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
@@ -284,7 +290,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> listOfKeys.flatMap(rawKeys -> connection.keyCommands().mDel(rawKeys)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#delete(org.reactivestreams.Publisher)
|
||||
*/
|
||||
@Override
|
||||
@@ -297,7 +304,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
.map(CommandResponse::getOutput));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#expire(java.lang.Object, java.time.Duration)
|
||||
*/
|
||||
@Override
|
||||
@@ -314,7 +322,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().pExpire(rawKey(key), timeout));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#expireAt(java.lang.Object, java.time.Instant)
|
||||
*/
|
||||
@Override
|
||||
@@ -331,7 +340,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().pExpireAt(rawKey(key), expireAt));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#persist(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -342,7 +352,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return createMono(connection -> connection.keyCommands().persist(rawKey(key)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#getExpire(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -364,7 +375,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
}));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#move(java.lang.Object, int)
|
||||
*/
|
||||
@Override
|
||||
@@ -435,7 +447,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
new CloseSuppressingInvocationHandler(reactiveRedisConnection));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForGeo()
|
||||
*/
|
||||
@Override
|
||||
@@ -443,7 +456,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForGeo(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForGeo(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -451,7 +465,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveGeoOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForHash()
|
||||
*/
|
||||
@Override
|
||||
@@ -459,7 +474,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForHash(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForHash(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -468,7 +484,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveHashOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForHyperLogLog()
|
||||
*/
|
||||
@Override
|
||||
@@ -476,7 +493,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForHyperLogLog(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForHyperLogLog(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -485,7 +503,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveHyperLogLogOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForList()
|
||||
*/
|
||||
@Override
|
||||
@@ -493,7 +512,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForList(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForList(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -501,7 +521,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveListOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForSet()
|
||||
*/
|
||||
@Override
|
||||
@@ -509,7 +530,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForSet(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForSet(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -517,7 +539,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveSetOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForValue()
|
||||
*/
|
||||
@Override
|
||||
@@ -525,7 +548,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForValue(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForValue(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -533,7 +557,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveValueOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForZSet()
|
||||
*/
|
||||
@Override
|
||||
@@ -541,7 +566,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return opsForZSet(serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#opsForZSet(org.springframework.data.redis.serializer.RedisSerializationContext)
|
||||
*/
|
||||
@Override
|
||||
@@ -549,7 +575,8 @@ public class ReactiveRedisTemplate<K, V> implements ReactiveRedisOperations<K, V
|
||||
return new DefaultReactiveZSetOperations<>(this, serializationContext);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveRedisOperations#serialization()
|
||||
*/
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user