diff --git a/.gitignore b/.gitignore index 419a1317bd..b34bc1769a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,5 @@ work build/ node_modules node -package.json package-lock.json .mvn/.gradle-enterprise diff --git a/package.json b/package.json new file mode 100644 index 0000000000..4689506b3f --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "antora": "3.2.0-alpha.6", + "@antora/atlas-extension": "1.0.0-alpha.2", + "@antora/collector-extension": "1.0.0-alpha.7", + "@asciidoctor/tabs": "1.0.0-beta.6", + "@springio/antora-extensions": "1.13.0", + "@springio/asciidoctor-extensions": "1.0.0-alpha.11" + } +} diff --git a/pom.xml b/pom.xml index d129d27346..f39b1fe04c 100644 --- a/pom.xml +++ b/pom.xml @@ -367,7 +367,7 @@ - io.spring.maven.antora + org.antora antora-maven-plugin diff --git a/src/main/antora/antora-playbook.yml b/src/main/antora/antora-playbook.yml index b68f34c9b8..b90d6ab326 100644 --- a/src/main/antora/antora-playbook.yml +++ b/src/main/antora/antora-playbook.yml @@ -3,8 +3,7 @@ # The purpose of this Antora playbook is to build the docs in the current branch. antora: extensions: - - '@antora/collector-extension' - - require: '@springio/antora-extensions/root-component-extension' + - require: '@springio/antora-extensions' root_component_name: 'data-redis' site: title: Spring Data Redis @@ -22,13 +21,12 @@ content: start_path: src/main/antora asciidoc: attributes: - page-pagination: '' hide-uri-scheme: '@' tabs-sync-option: '@' - chomp: 'all' extensions: - '@asciidoctor/tabs' - '@springio/asciidoctor-extensions' + - '@springio/asciidoctor-extensions/javadoc-extension' sourcemap: true urls: latest_version_segment: '' @@ -38,5 +36,5 @@ runtime: format: pretty ui: bundle: - url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip + url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip snapshot: true diff --git a/src/main/antora/antora.yml b/src/main/antora/antora.yml index 3b978752a0..f2cc6bda15 100644 --- a/src/main/antora/antora.yml +++ b/src/main/antora/antora.yml @@ -10,3 +10,8 @@ ext: local: true scan: dir: target/classes/ + - run: + command: ./mvnw package -Pdistribute + local: true + scan: + dir: target/antora diff --git a/src/main/antora/modules/ROOT/nav.adoc b/src/main/antora/modules/ROOT/nav.adoc index 11f202b10c..7cc4db98ce 100644 --- a/src/main/antora/modules/ROOT/nav.adoc +++ b/src/main/antora/modules/ROOT/nav.adoc @@ -44,4 +44,6 @@ * xref:appendix.adoc[] -* https://github.com/spring-projects/spring-data-commons/wiki[Wiki] + +* xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank] +* https://github.com/spring-projects/spring-data-commons/wiki[Wiki,role=link-external,window=_blank] diff --git a/src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc b/src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc index 062eb33d06..2a8f11623f 100644 --- a/src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc @@ -9,7 +9,7 @@ Each mode of operation requires specific configuration that is explained in the The easiest way to get started is by using Redis Standalone with a single Redis server, -Configure `LettuceClientConfiguration` or `JedisConnectionFactory`, as shown in the following example: +Configure javadoc:org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory[] or javadoc:org.springframework.data.redis.connection.jedis.JedisConnectionFactory[], as shown in the following example: [source,java] ---- @@ -60,12 +60,12 @@ class WriteToMasterReadFromReplicaConfiguration { } ---- -TIP: For environments reporting non-public addresses through the `INFO` command (for example, when using AWS), use `RedisStaticMasterReplicaConfiguration` instead of `RedisStandaloneConfiguration`. Please note that `RedisStaticMasterReplicaConfiguration` does not support Pub/Sub because of missing Pub/Sub message propagation across individual servers. +TIP: For environments reporting non-public addresses through the `INFO` command (for example, when using AWS), use javadoc:org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration[] instead of javadoc:org.springframework.data.redis.connection.RedisStandaloneConfiguration[]. Please note that `RedisStaticMasterReplicaConfiguration` does not support Pub/Sub because of missing Pub/Sub message propagation across individual servers. [[redis:sentinel]] == Redis Sentinel -For dealing with high-availability Redis, Spring Data Redis has support for https://redis.io/topics/sentinel[Redis Sentinel], using `RedisSentinelConfiguration`, as shown in the following example: +For dealing with high-availability Redis, Spring Data Redis has support for https://redis.io/topics/sentinel[Redis Sentinel], using javadoc:org.springframework.data.redis.connection.RedisSentinelConfiguration[], as shown in the following example: [source,java] ---- @@ -113,8 +113,8 @@ Sometimes, direct interaction with one of the Sentinels is required. Using `Redi [[cluster.enable]] == Redis Cluster -xref:redis/cluster.adoc[Cluster support] is based on the same building blocks as non-clustered communication. `RedisClusterConnection`, an extension to `RedisConnection`, handles the communication with the Redis Cluster and translates errors into the Spring DAO exception hierarchy. -`RedisClusterConnection` instances are created with the `RedisConnectionFactory`, which has to be set up with the associated `RedisClusterConfiguration`, as shown in the following example: +xref:redis/cluster.adoc[Cluster support] is based on the same building blocks as non-clustered communication. javadoc:org.springframework.data.redis.connection.RedisClusterConnection[], an extension to `RedisConnection`, handles the communication with the Redis Cluster and translates errors into the Spring DAO exception hierarchy. +`RedisClusterConnection` instances are created with the `RedisConnectionFactory`, which has to be set up with the associated javadoc:org.springframework.data.redis.connection.RedisClusterConfiguration[], as shown in the following example: .Sample RedisConnectionFactory Configuration for Redis Cluster ==== diff --git a/src/main/antora/modules/ROOT/pages/redis/drivers.adoc b/src/main/antora/modules/ROOT/pages/redis/drivers.adoc index 2f649f3166..52570144d5 100644 --- a/src/main/antora/modules/ROOT/pages/redis/drivers.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/drivers.adoc @@ -154,7 +154,7 @@ public LettuceConnectionFactory lettuceConnectionFactory() { } ---- -For more detailed client configuration tweaks, see https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/connection/lettuce/LettuceClientConfiguration.html[`LettuceClientConfiguration`]. +For more detailed client configuration tweaks, see javadoc:org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration[]. Lettuce integrates with Netty's https://netty.io/wiki/native-transports.html[native transports], letting you use Unix domain sockets to communicate with Redis. Make sure to include the appropriate native transport dependencies that match your runtime environment. diff --git a/src/main/antora/modules/ROOT/pages/redis/getting-started.adoc b/src/main/antora/modules/ROOT/pages/redis/getting-started.adoc index 4c16e17e98..3a803ad85b 100644 --- a/src/main/antora/modules/ROOT/pages/redis/getting-started.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/getting-started.adoc @@ -37,5 +37,5 @@ include::example$examples/ReactiveRedisApplication.java[tags=file] Even in this simple example, there are a few notable things to point out: -* You can create an instance of `RedisTemplate` (or `ReactiveRedisTemplate` for reactive usage) with a `RedisConnectionFactory`. Connection factories are an abstraction on top of the supported drivers. +* You can create an instance of javadoc:org.springframework.data.redis.core.RedisTemplate[] (or javadoc:org.springframework.data.redis.core.ReactiveRedisTemplate[]for reactive usage) with a javadoc:org.springframework.data.redis.connection.RedisConnectionFactory[]. Connection factories are an abstraction on top of the supported drivers. * There's no single way to use Redis as it comes with support for a wide range of data structures such as plain keys ("strings"), lists, sets, sorted sets, streams, hashes and so on. diff --git a/src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc b/src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc index 2ecbc321b7..334a2fd515 100644 --- a/src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc @@ -1,21 +1,21 @@ [[redis.hashmappers.root]] = Hash Mapping -Data can be stored by using various data structures within Redis. `Jackson2JsonRedisSerializer` can convert objects in https://en.wikipedia.org/wiki/JSON[JSON] format. Ideally, JSON can be stored as a value by using plain keys. You can achieve a more sophisticated mapping of structured objects by using Redis hashes. Spring Data Redis offers various strategies for mapping data to hashes (depending on the use case): +Data can be stored by using various data structures within Redis. javadoc:org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer[] can convert objects in https://en.wikipedia.org/wiki/JSON[JSON] format. Ideally, JSON can be stored as a value by using plain keys. You can achieve a more sophisticated mapping of structured objects by using Redis hashes. Spring Data Redis offers various strategies for mapping data to hashes (depending on the use case): -* Direct mapping, by using `HashOperations` and a xref:redis.adoc#redis:serializer[serializer] +* Direct mapping, by using javadoc:org.springframework.data.redis.core.HashOperations[] and a xref:redis.adoc#redis:serializer[serializer] * Using xref:repositories.adoc[Redis Repositories] -* Using `HashMapper` and `HashOperations` +* Using javadoc:org.springframework.data.redis.hash.HashMapper[] and javadoc:org.springframework.data.redis.core.HashOperations[] [[redis.hashmappers.mappers]] == Hash Mappers -Hash mappers are converters of map objects to a `Map` and back. `HashMapper` is intended for using with Redis Hashes. +Hash mappers are converters of map objects to a `Map` and back. javadoc:org.springframework.data.redis.hash.HashMapper[] is intended for using with Redis Hashes. Multiple implementations are available: -* `BeanUtilsHashMapper` using Spring's {spring-framework-javadoc}/org/springframework/beans/BeanUtils.html[BeanUtils]. -* `ObjectHashMapper` using xref:redis/redis-repositories/mapping.adoc[Object-to-Hash Mapping]. +* javadoc:org.springframework.data.redis.hash.BeanUtilsHashMapper[] using Spring's {spring-framework-javadoc}/org/springframework/beans/BeanUtils.html[BeanUtils]. +* javadoc:org.springframework.data.redis.hash.ObjectHashMapper[] using xref:redis/redis-repositories/mapping.adoc[Object-to-Hash Mapping]. * <> using https://github.com/FasterXML/jackson[FasterXML Jackson]. The following example shows one way to implement hash mapping: @@ -53,7 +53,7 @@ public class HashMapping { [[redis.hashmappers.jackson2]] === Jackson2HashMapper -`Jackson2HashMapper` provides Redis Hash mapping for domain objects by using https://github.com/FasterXML/jackson[FasterXML Jackson]. +javadoc:org.springframework.data.redis.hash.Jackson2HashMapper[] provides Redis Hash mapping for domain objects by using https://github.com/FasterXML/jackson[FasterXML Jackson]. `Jackson2HashMapper` can map top-level properties as Hash field names and, optionally, flatten the structure. Simple types map to simple values. Complex types (nested objects, collections, maps, and so on) are represented as nested JSON. diff --git a/src/main/antora/modules/ROOT/pages/redis/pubsub.adoc b/src/main/antora/modules/ROOT/pages/redis/pubsub.adoc index 0fdc427c58..6539ca127c 100644 --- a/src/main/antora/modules/ROOT/pages/redis/pubsub.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/pubsub.adoc @@ -66,13 +66,13 @@ In order to subscribe to messages, one needs to implement the `MessageListener` [[redis:pubsub:subscribe:containers]] === Message Listener Containers -Due to its blocking nature, low-level subscription is not attractive, as it requires connection and thread management for every single listener. To alleviate this problem, Spring Data offers `RedisMessageListenerContainer`, which does all the heavy lifting. If you are familiar with EJB and JMS, you should find the concepts familiar, as it is designed to be as close as possible to the support in Spring Framework and its message-driven POJOs (MDPs). +Due to its blocking nature, low-level subscription is not attractive, as it requires connection and thread management for every single listener. To alleviate this problem, Spring Data offers javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[], which does all the heavy lifting. If you are familiar with EJB and JMS, you should find the concepts familiar, as it is designed to be as close as possible to the support in Spring Framework and its message-driven POJOs (MDPs). -`RedisMessageListenerContainer` acts as a message listener container. It is used to receive messages from a Redis channel and drive the `MessageListener` instances that are injected into it. The listener container is responsible for all threading of message reception and dispatches into the listener for processing. A message listener container is the intermediary between an MDP and a messaging provider and takes care of registering to receive messages, resource acquisition and release, exception conversion, and the like. This lets you as an application developer write the (possibly complex) business logic associated with receiving a message (and reacting to it) and delegates boilerplate Redis infrastructure concerns to the framework. +javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[] acts as a message listener container. It is used to receive messages from a Redis channel and drive the javadoc:org.springframework.data.redis.connection.MessageListener[] instances that are injected into it. The listener container is responsible for all threading of message reception and dispatches into the listener for processing. A message listener container is the intermediary between an MDP and a messaging provider and takes care of registering to receive messages, resource acquisition and release, exception conversion, and the like. This lets you as an application developer write the (possibly complex) business logic associated with receiving a message (and reacting to it) and delegates boilerplate Redis infrastructure concerns to the framework. -A `MessageListener` can additionally implement `SubscriptionListener` to receive notifications upon subscription/unsubscribe confirmation. Listening to subscription notifications can be useful when synchronizing invocations. +A javadoc:org.springframework.data.redis.connection.MessageListener[] can additionally implement javadoc:org.springframework.data.redis.connection.SubscriptionListener[] to receive notifications upon subscription/unsubscribe confirmation. Listening to subscription notifications can be useful when synchronizing invocations. -Furthermore, to minimize the application footprint, `RedisMessageListenerContainer` lets one connection and one thread be shared by multiple listeners even though they do not share a subscription. Thus, no matter how many listeners or channels an application tracks, the runtime cost remains the same throughout its lifetime. Moreover, the container allows runtime configuration changes so that you can add or remove listeners while an application is running without the need for a restart. Additionally, the container uses a lazy subscription approach, using a `RedisConnection` only when needed. If all the listeners are unsubscribed, cleanup is automatically performed, and the thread is released. +Furthermore, to minimize the application footprint, javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[] lets one connection and one thread be shared by multiple listeners even though they do not share a subscription. Thus, no matter how many listeners or channels an application tracks, the runtime cost remains the same throughout its lifetime. Moreover, the container allows runtime configuration changes so that you can add or remove listeners while an application is running without the need for a restart. Additionally, the container uses a lazy subscription approach, using a `RedisConnection` only when needed. If all the listeners are unsubscribed, cleanup is automatically performed, and the thread is released. To help with the asynchronous nature of messages, the container requires a `java.util.concurrent.Executor` (or Spring's `TaskExecutor`) for dispatching the messages. Depending on the load, the number of listeners, or the runtime environment, you should change or tweak the executor to better serve your needs. In particular, in managed environments (such as app servers), it is highly recommended to pick a proper `TaskExecutor` to take advantage of its runtime. @@ -80,7 +80,7 @@ To help with the asynchronous nature of messages, the container requires a `java [[redis:pubsub:subscribe:adapter]] === The MessageListenerAdapter -The `MessageListenerAdapter` class is the final component in Spring's asynchronous messaging support. In a nutshell, it lets you expose almost *any* class as a MDP (though there are some constraints). +The javadoc:org.springframework.data.redis.listener.adapter.MessageListenerAdapter[] class is the final component in Spring's asynchronous messaging support. In a nutshell, it lets you expose almost *any* class as a MDP (though there are some constraints). Consider the following interface definition: @@ -96,7 +96,7 @@ public interface MessageDelegate { } ---- -Notice that, although the interface does not extend the `MessageListener` interface, it can still be used as a MDP by using the `MessageListenerAdapter` class. Notice also how the various message handling methods are strongly typed according to the *contents* of the various `Message` types that they can receive and handle. In addition, the channel or pattern to which a message is sent can be passed in to the method as the second argument of type `String`: +Notice that, although the interface does not extend the `MessageListener` interface, it can still be used as a MDP by using the javadoc:org.springframework.data.redis.listener.adapter.MessageListenerAdapter[] class. Notice also how the various message handling methods are strongly typed according to the *contents* of the various `Message` types that they can receive and handle. In addition, the channel or pattern to which a message is sent can be passed in to the method as the second argument of type `String`: [source,java] ---- @@ -105,7 +105,7 @@ public class DefaultMessageDelegate implements MessageDelegate { } ---- -Notice how the above implementation of the `MessageDelegate` interface (the above `DefaultMessageDelegate` class) has *no* Redis dependencies at all. It truly is a POJO that we make into an MDP with the following configuration: + Notice how the above implementation of the `MessageDelegate` interface (the above `DefaultMessageDelegate` class) has *no* Redis dependencies at all. It truly is a POJO that we make into an MDP with the following configuration: [tabs] ====== @@ -193,7 +193,7 @@ Each time a message is received, the adapter automatically and transparently per [[redis:reactive:pubsub:subscribe:containers]] == Reactive Message Listener Container -Spring Data offers `ReactiveRedisMessageListenerContainer` which does all the heavy lifting of conversion and subscription state management on behalf of the user. +Spring Data offers javadoc:org.springframework.data.redis.listener.ReactiveRedisMessageListenerContainer[] which does all the heavy lifting of conversion and subscription state management on behalf of the user. The message listener container itself does not require external threading resources. It uses the driver threads to publish messages. @@ -223,7 +223,7 @@ stream.doOnNext(inner -> // notification hook when Redis subscriptions are synch [[redis:reactive:pubsub:subscribe:template]] === Subscribing via template API -As mentioned above you can directly use `ReactiveRedisTemplate` to subscribe to channels / patterns. This approach +As mentioned above you can directly use javadoc:org.springframework.data.redis.core.ReactiveRedisTemplate[] to subscribe to channels / patterns. This approach offers a straight forward, though limited solution as you lose the option to add subscriptions after the initial ones. Nevertheless you still can control the message stream via the returned `Flux` using eg. `take(Duration)`. When done reading, on error or cancellation all bound resources are freed again. diff --git a/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc b/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc index c965f352a9..3726bb0680 100644 --- a/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc @@ -2,7 +2,7 @@ = Redis Cache Spring Data Redis provides an implementation of Spring Framework's {spring-framework-docs}/integration.html#cache[Cache Abstraction] in the `org.springframework.data.redis.cache` package. -To use Redis as a backing implementation, add `RedisCacheManager` to your configuration, as follows: +To use Redis as a backing implementation, add javadoc:org.springframework.data.redis.cache.RedisCacheManager[] to your configuration, as follows: [source,java] ---- @@ -12,7 +12,7 @@ public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) } ---- -`RedisCacheManager` behavior can be configured with `RedisCacheManagerBuilder`, letting you set the default `RedisCacheConfiguration`, transaction behavior, and predefined caches. +`RedisCacheManager` behavior can be configured with javadoc:org.springframework.data.redis.cache.RedisCacheManager$RedisCacheManagerBuilder[], letting you set the default javadoc:org.springframework.data.redis.cache.RedisCacheManager[], transaction behavior, and predefined caches. [source,java] ---- @@ -26,7 +26,7 @@ RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory) As shown in the preceding example, `RedisCacheManager` allows custom configuration on a per-cache basis. -The behavior of `RedisCache` created by `RedisCacheManager` is defined with `RedisCacheConfiguration`. +The behavior of javadoc:org.springframework.data.redis.cache.RedisCache[] created by javadoc:org.springframework.data.redis.cache.RedisCacheManager[] is defined with `RedisCacheConfiguration`. The configuration lets you set key expiration times, prefixes, and `RedisSerializer` implementations for converting to and from the binary storage format, as shown in the following example: [source,java] @@ -36,7 +36,7 @@ RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCach .disableCachingNullValues(); ---- -`RedisCacheManager` defaults to a lock-free `RedisCacheWriter` for reading and writing binary values. +javadoc:org.springframework.data.redis.cache.RedisCacheManager[] defaults to a lock-free javadoc:org.springframework.data.redis.cache.RedisCacheWriter[] for reading and writing binary values. Lock-free caching improves throughput. The lack of entry locking can lead to overlapping, non-atomic commands for the `Cache` `putIfAbsent` and `clean` operations, as those require multiple commands to be sent to Redis. The locking counterpart prevents command overlap by setting an explicit lock key and checking against presence of this key, which leads to additional requests and potential command wait times. diff --git a/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cdi-integration.adoc b/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cdi-integration.adoc index d841506565..bd36cb1c59 100644 --- a/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cdi-integration.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cdi-integration.adoc @@ -6,7 +6,7 @@ Spring offers sophisticated for creating bean instances. Spring Data Redis ships with a custom CDI extension that lets you use the repository abstraction in CDI environments. The extension is part of the JAR, so, to activate it, drop the Spring Data Redis JAR into your classpath. -You can then set up the infrastructure by implementing a CDI Producer for the `RedisConnectionFactory` and `RedisOperations`, as shown in the following example: +You can then set up the infrastructure by implementing a CDI Producer for the javadoc:org.springframework.data.redis.connection.RedisConnectionFactory[] and javadoc:org.springframework.data.redis.core.RedisOperations[], as shown in the following example: [source,java] ---- @@ -62,7 +62,7 @@ class RepositoryClient { } ---- -A Redis Repository requires `RedisKeyValueAdapter` and `RedisKeyValueTemplate` instances. +A Redis Repository requires javadoc:org.springframework.data.redis.core.RedisKeyValueAdapter[] and javadoc:org.springframework.data.redis.core.RedisKeyValueTemplate[] instances. These beans are created and managed by the Spring Data CDI extension if no provided beans are found. -You can, however, supply your own beans to configure the specific properties of `RedisKeyValueAdapter` and `RedisKeyValueTemplate`. +You can, however, supply your own beans to configure the specific properties of javadoc:org.springframework.data.redis.core.RedisKeyValueAdapter[] and javadoc:org.springframework.data.redis.core.RedisKeyValueTemplate[]. diff --git a/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cluster.adoc b/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cluster.adoc index 2ca39dee6d..2aa5e5eac5 100644 --- a/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cluster.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cluster.adoc @@ -13,7 +13,6 @@ The following table shows the details of data on a cluster (based on previous ex |people:e2c7dcee-b8cd-4424-883e-736ce564363e|id for hash|15171|127.0.0.1:7381 |people:a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56|id for hash|7373|127.0.0.1:7380 |people:firstname:rand|index|1700|127.0.0.1:7379 -| |=============== ==== @@ -29,7 +28,6 @@ The following table shows what happens when you do (note the change in the slot |\{people}:e2c7dcee-b8cd-4424-883e-736ce564363e|id for hash|2399|127.0.0.1:7379 |\{people}:a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56|id for hash|2399|127.0.0.1:7379 |\{people}:firstname:rand|index|2399|127.0.0.1:7379 -| |=============== ==== diff --git a/src/main/antora/modules/ROOT/pages/redis/redis-repositories/expirations.adoc b/src/main/antora/modules/ROOT/pages/redis/redis-repositories/expirations.adoc index 4372f7749b..ddb794213d 100644 --- a/src/main/antora/modules/ROOT/pages/redis/redis-repositories/expirations.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/redis-repositories/expirations.adoc @@ -3,7 +3,7 @@ Objects stored in Redis may be valid only for a certain amount of time. This is especially useful for persisting short-lived objects in Redis without having to remove them manually when they reach their end of life. -The expiration time in seconds can be set with `@RedisHash(timeToLive=...)` as well as by using `KeyspaceSettings` (see xref:redis/redis-repositories/keyspaces.adoc[Keyspaces]). +The expiration time in seconds can be set with `@RedisHash(timeToLive=...)` as well as by using javadoc:org.springframework.data.redis.core.convert.KeyspaceConfiguration$KeyspaceSettings[] (see xref:redis/redis-repositories/keyspaces.adoc[Keyspaces]). More flexible expiration times can be set by using the `@TimeToLive` annotation on either a numeric property or a method. However, do not apply `@TimeToLive` on both a method and a property within the same class. @@ -37,16 +37,16 @@ public class TimeToLiveOnMethod { NOTE: Annotating a property explicitly with `@TimeToLive` reads back the actual `TTL` or `PTTL` value from Redis. -1 indicates that the object has no associated expiration. -The repository implementation ensures subscription to https://redis.io/topics/notifications[Redis keyspace notifications] via `RedisMessageListenerContainer`. +The repository implementation ensures subscription to https://redis.io/topics/notifications[Redis keyspace notifications] via javadoc:org.springframework.data.redis.listener.RedisMessageListenerContainer[]. When the expiration is set to a positive value, the corresponding `EXPIRE` command is run. 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. +This is done to enable the Repository support to publish javadoc:org.springframework.data.redis.core.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/{version}/api/org/springframework/data/redis/core/RedisKeyValueAdapter.EnableKeyspaceEvents.html[`EnableKeyspaceEvents`] for possible values. +See javadoc:org.springframework.data.redis.core.RedisKeyValueAdapter$EnableKeyspaceEvents[] for possible values. The `RedisKeyExpiredEvent` holds a copy of the expired domain object as well as the key. diff --git a/src/main/antora/modules/ROOT/pages/redis/redis-streams.adoc b/src/main/antora/modules/ROOT/pages/redis/redis-streams.adoc index 97febc2cee..25d916f637 100644 --- a/src/main/antora/modules/ROOT/pages/redis/redis-streams.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/redis-streams.adoc @@ -73,8 +73,8 @@ Due to its blocking nature, low-level polling is not attractive, as it requires Spring Data ships with two implementations tailored to the used programming model: -* `StreamMessageListenerContainer` acts as message listener container for imperative programming models. It is used to consume records from a Redis Stream and drive the `StreamListener` instances that are injected into it. -* `StreamReceiver` provides a reactive variant of a message listener. It is used to consume messages from a Redis Stream as potentially infinite stream and emit stream messages through a `Flux`. +* javadoc:org.springframework.data.redis.stream.StreamMessageListenerContainer[] acts as message listener container for imperative programming models. It is used to consume records from a Redis Stream and drive the javadoc:org.springframework.data.redis.stream.StreamListener[] instances that are injected into it. +* javadoc:org.springframework.data.redis.stream.StreamReceiver[] provides a reactive variant of a message listener. It is used to consume messages from a Redis Stream as potentially infinite stream and emit stream messages through a `Flux`. `StreamMessageListenerContainer` and `StreamReceiver` are responsible for all threading of message reception and dispatch into the listener for processing. A message listener container/receiver is the intermediary between an MDP and a messaging provider and takes care of registering to receive messages, resource acquisition and release, exception conversion, and the like. This lets you as an application developer write the (possibly complex) business logic associated with receiving a message (and reacting to it) and delegates boilerplate Redis infrastructure concerns to the framework. @@ -84,7 +84,7 @@ Both containers allow runtime configuration changes so that you can add or remov [[imperative-streammessagelistenercontainer]] ==== Imperative `StreamMessageListenerContainer` -In a fashion similar to a Message-Driven Bean (MDB) in the EJB world, the Stream-Driven POJO (SDP) acts as a receiver for Stream messages. The one restriction on an SDP is that it must implement the `org.springframework.data.redis.stream.StreamListener` interface. Please also be aware that in the case where your POJO receives messages on multiple threads, it is important to ensure that your implementation is thread-safe. +In a fashion similar to a Message-Driven Bean (MDB) in the EJB world, the Stream-Driven POJO (SDP) acts as a receiver for Stream messages. The one restriction on an SDP is that it must implement the javadoc:org.springframework.data.redis.stream.StreamListener[] interface. Please also be aware that in the case where your POJO receives messages on multiple threads, it is important to ensure that your implementation is thread-safe. [source,java] ---- diff --git a/src/main/antora/modules/ROOT/pages/redis/scripting.adoc b/src/main/antora/modules/ROOT/pages/redis/scripting.adoc index 38864e6e99..436c50d11c 100644 --- a/src/main/antora/modules/ROOT/pages/redis/scripting.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/scripting.adoc @@ -3,9 +3,9 @@ Redis versions 2.6 and higher provide support for running Lua scripts through the https://redis.io/commands/eval[eval] and https://redis.io/commands/evalsha[evalsha] commands. Spring Data Redis provides a high-level abstraction for running scripts that handles serialization and automatically uses the Redis script cache. -Scripts can be run by calling the `execute` methods of `RedisTemplate` and `ReactiveRedisTemplate`. Both use a configurable `ScriptExecutor` (or `ReactiveScriptExecutor`) to run the provided script. By default, the `ScriptExecutor` (or `ReactiveScriptExecutor`) takes care of serializing the provided keys and arguments and deserializing the script result. This is done through the key and value serializers of the template. There is an additional overload that lets you pass custom serializers for the script arguments and the result. +Scripts can be run by calling the `execute` methods of `RedisTemplate` and `ReactiveRedisTemplate`. Both use a configurable javadoc:org.springframework.data.redis.core.script.ScriptExecutor[] (or javadoc:org.springframework.data.redis.core.script.ReactiveScriptExecutor[]) to run the provided script. By default, the javadoc:org.springframework.data.redis.core.script.ScriptExecutor[] (or javadoc:org.springframework.data.redis.core.script.ReactiveScriptExecutor[]) takes care of serializing the provided keys and arguments and deserializing the script result. This is done through the key and value serializers of the template. There is an additional overload that lets you pass custom serializers for the script arguments and the result. -The default `ScriptExecutor` optimizes performance by retrieving the SHA1 of the script and attempting first to run `evalsha`, falling back to `eval` if the script is not yet present in the Redis script cache. +The default javadoc:org.springframework.data.redis.core.script.ScriptExecutor[] optimizes performance by retrieving the SHA1 of the script and attempting first to run `evalsha`, falling back to `eval` if the script is not yet present in the Redis script cache. The following example runs a common "`check-and-set`" scenario by using a Lua script. This is an ideal use case for a Redis script, as it requires that running a set of commands atomically, and the behavior of one command is influenced by the result of another. @@ -69,10 +69,10 @@ end return false ---- -The preceding code configures a `RedisScript` pointing to a file called `checkandset.lua`, which is expected to return a boolean value. The script `resultType` should be one of `Long`, `Boolean`, `List`, or a deserialized value type. It can also be `null` if the script returns a throw-away status (specifically, `OK`). +The preceding code configures a javadoc:org.springframework.data.redis.core.script.RedisScript[] pointing to a file called `checkandset.lua`, which is expected to return a boolean value. The script `resultType` should be one of `Long`, `Boolean`, `List`, or a deserialized value type. It can also be `null` if the script returns a throw-away status (specifically, `OK`). TIP: It is ideal to configure a single instance of `DefaultRedisScript` in your application context to avoid re-calculation of the script's SHA1 on every script run. -The `checkAndSet` method above then runs the scripts. Scripts can be run within a `SessionCallback` as part of a transaction or pipeline. See "`xref:redis/transactions.adoc[Redis Transactions]`" and "`xref:redis/pipelining.adoc[Pipelining]`" for more information. +The `checkAndSet` method above then runs the scripts. Scripts can be run within a javadoc:org.springframework.data.redis.core.SessionCallback[] as part of a transaction or pipeline. See "`xref:redis/transactions.adoc[Redis Transactions]`" and "`xref:redis/pipelining.adoc[Pipelining]`" for more information. The scripting support provided by Spring Data Redis also lets you schedule Redis scripts for periodic running by using the Spring Task and Scheduler abstractions. See the https://spring.io/projects/spring-framework/[Spring Framework] documentation for more details. diff --git a/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc b/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc index 14ae2a6ac9..e363bb4f53 100644 --- a/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc @@ -4,11 +4,11 @@ Package `org.springframework.data.redis.support` offers various reusable components that rely on Redis as a backing store. Currently, the package contains various JDK-based interface implementations on top of Redis, such as https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/package-summary.html[atomic] counters and JDK https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collection.html[Collections]. -NOTE: `RedisList` is forward-compatible with Java 21 `SequencedCollection`. +NOTE: javadoc:org.springframework.data.redis.support.collections.RedisList[] is forward-compatible with Java 21 `SequencedCollection`. The atomic counters make it easy to wrap Redis key incrementation while the collections allow easy management of Redis keys with minimal storage exposure or API leakage. -In particular, the `RedisSet` and `RedisZSet` interfaces offer easy access to the set operations supported by Redis, such as `intersection` and `union`. `RedisList` implements the `List`, `Queue`, and `Deque` contracts (and their equivalent blocking siblings) on top of Redis, exposing the storage as a FIFO (First-In-First-Out), LIFO (Last-In-First-Out) or capped collection with minimal configuration. -The following example shows the configuration for a bean that uses a `RedisList`: +In particular, the javadoc:org.springframework.data.redis.support.collections.RedisSet[] and javadoc:org.springframework.data.redis.support.collections.RedisZSet[] interfaces offer easy access to the set operations supported by Redis, such as `intersection` and `union`. javadoc:org.springframework.data.redis.support.collections.RedisList[] implements the `List`, `Queue`, and `Deque` contracts (and their equivalent blocking siblings) on top of Redis, exposing the storage as a FIFO (First-In-First-Out), LIFO (Last-In-First-Out) or capped collection with minimal configuration. +The following example shows the configuration for a bean that uses a javadoc:org.springframework.data.redis.support.collections.RedisList[]: [tabs] ====== diff --git a/src/main/antora/modules/ROOT/pages/redis/template.adoc b/src/main/antora/modules/ROOT/pages/redis/template.adoc index 38dd0d42e9..a43028834d 100644 --- a/src/main/antora/modules/ROOT/pages/redis/template.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/template.adoc @@ -1,12 +1,12 @@ [[redis:template]] = Working with Objects through `RedisTemplate` -Most users are likely to use `RedisTemplate` and its corresponding package, `org.springframework.data.redis.core` or its reactive variant `ReactiveRedisTemplate`. +Most users are likely to use javadoc:org.springframework.data.redis.core.RedisTemplate[] and its corresponding package, `org.springframework.data.redis.core` or its reactive variant javadoc:org.springframework.data.redis.core.ReactiveRedisTemplate[]. 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 `[Reactive]RedisConnection` offers low-level methods that accept and return binary values (`byte` arrays), the template takes care of serialization and connection management, freeing the user from dealing with such details. -The `RedisTemplate` class implements the `RedisOperations` interface and its reactive variant `ReactiveRedisTemplate` implements `ReactiveRedisOperations`. +The javadoc:org.springframework.data.redis.core.RedisTemplate[] class implements the javadoc:org.springframework.data.redis.core.RedisOperations[] interface and its reactive variant javadoc:org.springframework.data.redis.core.ReactiveRedisTemplate[] implements javadoc:org.springframework.data.redis.core.ReactiveRedisOperations[]. NOTE: The preferred way to reference operations on a `[Reactive]RedisTemplate` instance is through the `[Reactive]RedisOperations` interface. @@ -27,48 +27,48 @@ Imperative:: 2+^|_Key Type Operations_ -|`GeoOperations` +|javadoc:org.springframework.data.redis.core.GeoOperations[] |Redis geospatial operations, such as `GEOADD`, `GEORADIUS`,... -|`HashOperations` +|javadoc:org.springframework.data.redis.core.HashOperations[] |Redis hash operations -|`HyperLogLogOperations` +|javadoc:org.springframework.data.redis.core.HyperLogLogOperations[] |Redis HyperLogLog operations, such as `PFADD`, `PFCOUNT`,... -|`ListOperations` +|javadoc:org.springframework.data.redis.core.ListOperations[] |Redis list operations -|`SetOperations` +|javadoc:org.springframework.data.redis.core.SetOperations[] |Redis set operations -|`ValueOperations` +|javadoc:org.springframework.data.redis.core.ValueOperations[] |Redis string (or value) operations -|`ZSetOperations` +|javadoc:org.springframework.data.redis.core.ZSetOperations[] |Redis zset (or sorted set) operations 2+^|_Key Bound Operations_ -|`BoundGeoOperations` +|javadoc:org.springframework.data.redis.core.BoundGeoOperations[] |Redis key bound geospatial operations -|`BoundHashOperations` +|javadoc:org.springframework.data.redis.core.BoundHashOperations[] |Redis hash key bound operations -|`BoundKeyOperations` +|javadoc:org.springframework.data.redis.core.BoundKeyOperations[] |Redis key bound operations -|`BoundListOperations` +|javadoc:org.springframework.data.redis.core.BoundListOperations[] |Redis list key bound operations -|`BoundSetOperations` +|javadoc:org.springframework.data.redis.core.BoundSetOperations[] |Redis set key bound operations -|`BoundValueOperations` +|javadoc:org.springframework.data.redis.core.BoundValueOperations[] |Redis string (or value) key bound operations -|`BoundZSetOperations` +|javadoc:org.springframework.data.redis.core.BoundZSetOperations[] |Redis zset (or sorted set) key bound operations |==== @@ -82,25 +82,25 @@ Reactive:: 2+^|_Key Type Operations_ -|`ReactiveGeoOperations` +|javadoc:org.springframework.data.redis.core.ReactiveGeoOperations[] |Redis geospatial operations such as `GEOADD`, `GEORADIUS`, and others) -|`ReactiveHashOperations` +|javadoc:org.springframework.data.redis.core.ReactiveHashOperations[] |Redis hash operations -|`ReactiveHyperLogLogOperations` +|javadoc:org.springframework.data.redis.core.ReactiveHyperLogLogOperations[] |Redis HyperLogLog operations such as (`PFADD`, `PFCOUNT`, and others) -|`ReactiveListOperations` +|javadoc:org.springframework.data.redis.core.ReactiveListOperations[] |Redis list operations -|`ReactiveSetOperations` +|javadoc:org.springframework.data.redis.core.ReactiveSetOperations[] |Redis set operations -|`ReactiveValueOperations` +|javadoc:org.springframework.data.redis.core.ReactiveValueOperations[] |Redis string (or value) operations -|`ReactiveZSetOperations` +|javadoc:org.springframework.data.redis.core.ReactiveZSetOperations[] |Redis zset (or sorted set) operations |==== ====== @@ -355,24 +355,24 @@ In Spring Data, the conversion between the user (custom) types and raw data (and This package contains two types of serializers that, as the name implies, take care of the serialization process: -* Two-way serializers based on ``RedisSerializer``. +* Two-way serializers based on javadoc:org.springframework.data.redis.serializer.RedisSerializer[]. * Element readers and writers that use `RedisElementReader` and ``RedisElementWriter``. The main difference between these variants is that `RedisSerializer` primarily serializes to `byte[]` while readers and writers use `ByteBuffer`. Multiple implementations are available (including two that have been already mentioned in this documentation): -* `JdkSerializationRedisSerializer`, which is used by default for `RedisCache` and `RedisTemplate`. +* javadoc:org.springframework.data.redis.serializer.JdkSerializationRedisSerializer[], which is used by default for javadoc:org.springframework.data.redis.cache.RedisCache[] and javadoc:org.springframework.data.redis.core.RedisTemplate[]. * the `StringRedisSerializer`. -However, one can use `OxmSerializer` for Object/XML mapping through Spring {spring-framework-docs}/data-access.html#oxm[OXM] support or `Jackson2JsonRedisSerializer` or `GenericJackson2JsonRedisSerializer` for storing data in https://en.wikipedia.org/wiki/JSON[JSON] format. +However, one can use `OxmSerializer` for Object/XML mapping through Spring {spring-framework-docs}/data-access.html#oxm[OXM] support or javadoc:org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer[] or javadoc:org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer[] for storing data in https://en.wikipedia.org/wiki/JSON[JSON] format. Do note that the storage format is not limited only to values. It can be used for keys, values, or hashes without any restrictions. [WARNING] ==== -By default, `RedisCache` and `RedisTemplate` are configured to use Java native serialization. +By default, javadoc:org.springframework.data.redis.cache.RedisCache[] and javadoc:org.springframework.data.redis.core.RedisTemplate[] are configured to use Java native serialization. Java native serialization is known for allowing the running of remote code caused by payloads that exploit vulnerable libraries and classes injecting unverified bytecode. Manipulated input could lead to unwanted code being run in the application during the deserialization step. As a consequence, do not use serialization in untrusted environments. diff --git a/src/main/antora/modules/ROOT/pages/redis/transactions.adoc b/src/main/antora/modules/ROOT/pages/redis/transactions.adoc index de48a55cc5..8ba20676bc 100644 --- a/src/main/antora/modules/ROOT/pages/redis/transactions.adoc +++ b/src/main/antora/modules/ROOT/pages/redis/transactions.adoc @@ -2,10 +2,10 @@ = Redis Transactions Redis provides support for https://redis.io/topics/transactions[transactions] through the `multi`, `exec`, and `discard` commands. -These operations are available on `RedisTemplate`. +These operations are available on javadoc:org.springframework.data.redis.core.RedisTemplate[]. However, `RedisTemplate` is not guaranteed to run all the operations in the transaction with the same connection. -Spring Data Redis provides the `SessionCallback` interface for use when multiple operations need to be performed with the same `connection`, such as when using Redis transactions.The following example uses the `multi` method: +Spring Data Redis provides the javadoc:org.springframework.data.redis.core.SessionCallback[] interface for use when multiple operations need to be performed with the same `connection`, such as when using Redis transactions.The following example uses the `multi` method: [source,java] ----