跳到主要内容
版本:4.1.1

迁移指南

Doubao 中英对照 Migration Guides

本节包含有关迁移步骤、弃用和移除的详细信息。

从 3.x 升级到 4.x​

先升级到最新的 Spring Data Redis 3.5.x 版本,并在迁移到 4.0 之前替换为移除而弃用的 API。

Jackson 3​

Spring Data Redis 4.0 使用 Jackson 3 作为其主要的 JSON 库。下面列出的 Jackson 2 API 已弃用,将在后续版本中移除。

RedisSerializer.json() 现在使用来自 tools.jackson 包的 Jackson 3。它需要 tools.jackson.core:jackson-databind 以及最新版本的 com.fasterxml.jackson.core:jackson-annotations。有关更新应用程序代码的信息,请参阅 Jackson 3 迁移指南。

下表列出了 Jackson 3 的替代方案:

用途Jackson 2 APIJackson 3 API
通用 JSON 序列化器GenericJackson2JsonRedisSerializerGenericJacksonJsonRedisSerializer
类型化 JSON 序列化器Jackson2JsonRedisSerializerJacksonJsonRedisSerializer
Hash 映射器Jackson2HashMapperJacksonHashMapper
自定义读取器和写入器契约Jackson2ObjectReader and Jackson2ObjectWriterJacksonObjectReader and JacksonObjectWriter
备注

GenericJackson2JsonRedisSerializer 默认启用默认类型,而无需 PolymorphicTypeValidator。GenericJacksonJsonRedisSerializer 默认不启用默认类型。如果你需要默认类型,请通过 GenericJacksonJsonRedisSerializer 构建器启用它(GenericJacksonJsonRedisSerializer.builder().enableDefaultTyping(…))。

如果你在迁移期间继续使用 Jackson 2,请在构造函数和构建器中将 JacksonObjectReader 替换为 Jackson2ObjectReader,将 JacksonObjectWriter 替换为 Jackson2ObjectWriter。

以前,RedisSerializer.json() 使用 GenericJackson2JsonRedisSerializer。Jackson 3 序列化器生成的 JSON 输出可能与 Jackson 2 的输出不同。在现有值迁移完成之前,请继续使用 GenericJackson2JsonRedisSerializer 来读取这些值:

RedisSerializer<Object> serializer = new GenericJackson2JsonRedisSerializer();

使用 jackson2CompatibilityMode() 来读写与 Jackson2HashMapper 兼容的哈希:

JacksonHashMapper mapper = JacksonHashMapper.builder()
.jackson2CompatibilityMode()
.build();

在构建器上选择 flatten() 或 hierarchical(),以匹配现有的哈希表示形式。

Redis 缓存​

RedisCacheWriter 扩展了 evict(…) 和 clear(…) 方法,以支持异步缓存逐出和清除。

如果配置的 RedisConnectionFactory 实现了 ReactiveRedisConnectionFactory,则默认的 RedisCacheWriter 对 put(…)、evict(…) 和 clear(…) 使用异步行为。这些操作可能在调用方法返回之后才完成。对 Cache.evictIfPresent(…) 或 Cache.invalidate(…) 的调用会强制同步行为,即在返回之前等待操作完成。要对所有操作使用同步行为,请在 RedisCacheWriter 构建器上调用 immediateWrites():

RedisCacheWriter cacheWriter = RedisCacheWriter.create(connectionFactory,
configurer -> configurer.immediateWrites());

表 1. 缓存 API 变更

3.x API4.x 替代方案
RedisCacheConfiguration.getTtl()RedisCacheConfiguration.getTtlFunction().getTimeToLive(key, value)
RedisCacheManager(RedisCacheWriter, RedisCacheConfiguration, Map, boolean)RedisCacheManager(RedisCacheWriter, RedisCacheConfiguration, boolean, Map)

StringRedisTemplate 连接回调​

StringRedisTemplate 不再将传递给回调的连接暴露为 StringRedisConnection。请改用 StringRedisTemplate 操作:

String value = stringRedisTemplate.opsForValue().get("key");

对于其余回调,请使用二进制的 RedisConnection API。

Lettuce 可观测性​

Spring Data Redis 4.0 移除了其 Lettuce 可观测性适配器,转而使用 Lettuce 原生的 Micrometer 集成。请使用 Lettuce 的 io.lettuce.core.tracing.LettuceObservationContext 代替被移除的 org.springframework.data.redis.connection.lettuce.observability.LettuceObservationContext。RedisObservation 没有公开的替代方案。请用 Lettuce 的 io.lettuce.core.tracing.MicrometerTracing 替换 MicrometerTracingAdapter:

MicrometerTracing tracing = new MicrometerTracing(observationRegistry, "Redis");

ClientResources clientResources = ClientResources.builder()
.tracing(tracing)
.build();

在 LettuceClientConfiguration 上配置生成的 ClientResources 实例。有关高级配置选项,请参阅 Lettuce 的 Micrometer Tracing 文档。

JSpecify 可空性​

Spring Data Redis 4.0 使用 JSpecify 可空性注解来指示 API 的空性。大多数包默认标记为可空。某些包和接口无法声明非空默认值,因为返回值取决于连接状态。在事务执行期间或管道传输期间调用的方法会返回 null,直到事务被执行或管道被关闭。受影响的类型使用 @NullUnmarked,并对保留非空契约的参数和返回值应用 @NonNull。

RedisSerializer.serialize(Object) 现在必须返回非空字节数组。自定义 RedisSerializer 实现可以对 null 值使用空字节数组。RedisSerializer.deserialize(byte[]) 仍可返回 null。有关详细信息,请参阅 Spring Framework 关于空安全的文档。

其他已移除和已变更的 API​

表 2. 配置、操作和实用工具

3.x API4.x 替代方案或操作
new RedisClusterConfiguration(PropertySource)RedisClusterConfiguration.of(PropertySource)
new RedisSentinelConfiguration(PropertySource)RedisSentinelConfiguration.of(PropertySource)
BoundSetOperations.diff(…)BoundSetOperations.difference(…)
接受 RedisZSetCommands.Range 的 BoundZSetOperations、ZSetOperations 和 RedisZSet 重载使用接受 org.springframework.data.domain.Range<String> 的重载。
RedisPersistentEntity.hasExplictTimeToLiveProperty()RedisPersistentEntity.hasExplicitTimeToLiveProperty()
返回 Boolean 的 Converters.toBoolean(Long)重新编译调用方。该方法现在返回原始类型 boolean。
返回 Long 的 Converters.toTimeMillis(…)重新编译调用方。这些方法现在返回原始类型 long。
LettuceConverters.toBytesList(Collection<byte[]>)直接使用输入集合,或者在需要时将其转换为 List。
ByteUtils.extractBytes(ByteBuffer)ByteUtils.getBytes(ByteBuffer)
RedisAssertions使用 org.springframework.util.Assert 或显式检查。

表 3. 扩展 API

3.x API4.x 替代方案或操作
new ScanIteration(long, Collection) 和 ScanIteration.getCursorId()使用 new ScanIteration(Cursor.CursorId, Collection) 和 ScanIteration.getId()。
ScanCursor.doOpen(long) 和 ScanCursor.isFinished(long)重写接受 Cursor.CursorId 的变体。
接受 QueryMethodEvaluationContextProvider 的 RedisPartTreeQuery 构造函数使用接受 ValueExpressionDelegate 的构造函数。
JedisClusterTopologyProvider.shouldUseCachedValue()重写 shouldUseCachedValue(JedisClusterTopology)。

从 2.x 升级到 3.x​

重新/已移除的类型​

类型替代方案
o.s.d.redis.Versiono.s.d.util.Version
o.s.d.redis.VersionParser-
o.s.d.redis.connection.RedisZSetCommands.Aggregateo.s.d.redis.connection.zset.Aggregate
o.s.d.redis.connection.RedisZSetCommands.Tupleo.s.d.redis.connection.zset.Tuple
o.s.d.redis.connection.RedisZSetCommands.Weightso.s.d.redis.connection.zset.Weights
o.s.d.redis.connection.RedisZSetCommands.Rangeo.s.d.domain.Range
o.s.d.redis.connection.RedisZSetCommands.Limito.s.d.redis.connection.Limit.java
o.s.d.redis.connection.jedis.JedisUtils-
o.s.d.redis.connection.jedis.JedisVersionUtil-
o.s.d.redis.core.convert.CustomConversionso.s.d.convert.CustomConversions

已变更的方法和类型​

表 4. 核心

类型方法替代方案
o.s.d.redis.core.Cursoropen-
o.s.d.redis.core.RedisTemplateexecutedoWithKeys
o.s.d.redis.stream.StreamMessageListenerContainerisAutoAckisAutoAcknowledge
o.s.d.redis.stream.StreamMessageListenerContainerautoAckautoAcknowledge

表 5. Redis 连接

类型方法替代方案
o.s.d.redis.connection.ClusterCommandExecutionFailureExceptiongetCausesgetSuppressed
o.s.d.redis.connection.RedisConnectionbgWriteAofbgReWriteAof
o.s.d.redis.connection.RedisConnectionslaveOfreplicaOf
o.s.d.redis.connection.RedisConnectionslaveOfNoOnereplicaOfNoOne
o.s.d.redis.connection.ReactiveClusterCommandsclusterGetSlavesclusterGetReplicas
o.s.d.redis.connection.ReactiveClusterCommandsclusterGetMasterSlaveMapclusterGetMasterReplicaMap
o.s.d.redis.connection.ReactiveKeyCommandsgetNewNamegetNewKey
o.s.d.redis.connection.RedisClusterNode.FlagSLAVEREPLICA
o.s.d.redis.connection.RedisClusterNode.BuilderslaveOfreplicaOf
o.s.d.redis.connection.RedisNodeisSlaveisReplica
o.s.d.redis.connection.RedisSentinelCommandsslavesreplicas
o.s.d.redis.connection.RedisServergetNumberSlavesgetNumberReplicas
o.s.d.redis.connection.RedisServerCommandsslaveOfreplicaOf
o.s.d.redis.core.ClusterOperationsgetSlavesgetReplicas
o.s.d.redis.core.RedisOperationsslaveOfreplicaOf

表 6. Redis 操作

类型方法替代方案
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoAddadd
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoDistdistance
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoHashhash
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoPosposition
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoRadiusradius
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoRadiusByMemberradius
o.s.d.redis.core.GeoOperations & BoundGeoOperationsgeoRemoveremove

表 7. Redis 缓存

类型方法替代方案
o.s.d.redis.cache.RedisCacheConfigurationprefixKeysWithprefixCacheNameWith
o.s.d.redis.cache.RedisCacheConfigurationgetKeyPrefixgetKeyPrefixFor

Jedis​

请阅读 Jedis 的升级指南,其中涵盖了重要的驱动程序变更。

表 8. Jedis Redis 连接

类型方法替代方案
o.s.d.redis.connection.jedis.JedisConnectionFactorygetShardInfo可通过 JedisClientConfiguration 获取
o.s.d.redis.connection.jedis.JedisConnectionFactorysetShardInfo可通过 JedisClientConfiguration 设置
o.s.d.redis.connection.jedis.JedisConnectionFactorycreateCluster现在需要 Connection 而不是 Jedis 实例
o.s.d.redis.connection.jedis.JedisConverters现在具有包可见性
o.s.d.redis.connection.jedis.JedisConverterstuplesToTuples-
o.s.d.redis.connection.jedis.JedisConverterstuplesToTuples-
o.s.d.redis.connection.jedis.JedisConvertersstringListToByteList-
o.s.d.redis.connection.jedis.JedisConvertersstringSetToByteSet-
o.s.d.redis.connection.jedis.JedisConvertersstringMapToByteMap-
o.s.d.redis.connection.jedis.JedisConverterstupleSetToTupleSet-
o.s.d.redis.connection.jedis.JedisConverterstoTupleSet-
o.s.d.redis.connection.jedis.JedisConverterstoDataAccessExceptiono.s.d.redis.connection.jedis.JedisExceptionConverter#convert

事务 / 管道​

管道和事务现在是互斥的。在管道/事务模式下使用服务器或连接命令不再可行。

Lettuce​

Lettuce 连接池​

LettucePool 及其实现 DefaultLettucePool 已被移除,且没有替代方案。有关驱动程序原生连接池功能,请参阅驱动程序文档。接受连接池参数的方法已更新。这会影响 LettuceConnectionFactory 和 LettuceConnection 上的方法。

Lettuce 认证​

AuthenticatingRedisClient 已被移除,且没有替代方案。请参阅驱动程序文档,了解如何使用 RedisURI 设置认证数据。