SpringData-Redis缓存之RedisTemplate

📅 2026/7/17 12:51:01
SpringData-Redis缓存之RedisTemplate
一、概述大多数用户可能会使用RedisTemplate及其相应的包org.springframework.data.redis.core或其反应式变体ReactiveRedisTemplate。由于其丰富的功能集该模板实际上是Redis模块的中心类。该模板为Redis交互提供了高级抽象。虽然[Reactive]RedisConnection提供了接受和返回二进制值字节数组的低级方法但模板负责序列化和连接管理使用户无需处理此类细节。RedisTemplate类实现RedisOperations接口其反应变量ReactiveRedisTemplate实现ReactiveEdisOperations。此外该模板还提供了操作视图遵循Redis命令参考中的分组这些视图提供了丰富的通用接口用于处理特定类型或特定键通过KeyBound接口如下表所述操作视图InterfaceDescriptionKey Type OperationsGeoOperationsRedis geospatial operations, such asGEOADD,GEORADIUS,…​HashOperationsRedis hash operationsHyperLogLogOperationsRedis HyperLogLog operations, such asPFADD,PFCOUNT,…​ListOperationsRedis list operationsSetOperationsRedis set operationsValueOperationsRedis string (or value) operationsZSetOperationsRedis zset (or sorted set) operationsKey Bound OperationsBoundGeoOperationsRedis key bound geospatial operationsBoundHashOperationsRedis hash key bound operationsBoundKeyOperationsRedis key bound operationsBoundListOperationsRedis list key bound operationsBoundSetOperationsRedis set key bound operationsBoundValueOperationsRedis string (or value) key bound operationsBoundZSetOperationsRedis zset (or sorted set) key bound operations配置后模板是线程安全的可以跨多个实例重用。RedisTemplate对其大多数操作使用基于Java的序列化程序。这意味着模板写入或读取的任何对象都将通过Java序列化和反序列化。您可以在模板上更改序列化机制Redis模块提供了几种实现可在org.springframework.data.Redis.serializer包中获得。有关详细信息请参阅序列化程序。您还可以通过将enableDefaultSerializer属性设置为false将任何序列化程序设置为null并将RedisTemplate与原始字节数组一起使用。请注意模板要求所有键都不为null。然而只要底层序列化程序接受它们值就可以为null。阅读每个序列化程序的Javadoc以了解更多信息。对于需要特定模板视图的情况请将视图声明为依赖项然后注入模板。容器自动执行转换消除opsFor[X]调用如下例所示配置模板APIConfiguration class MyConfig { Bean LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); } Bean RedisTemplateString, String redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplateString, String template new RedisTemplate(); template.setConnectionFactory(connectionFactory); return template; } }‌LettuceConnectionFactory‌是Spring Data Redis中的一个类用于创建和管理与Redis服务器的连接。它是一个连接工厂负责创建和配置Redis连接并提供与Redis服务器进行通信的方法使用[Reactive]RedisTemplate将项目推送到列表public class Example { // inject the actual operations Autowired private RedisOperationsString, String operations; // inject the template as ListOperations Resource(nameredisTemplate) private ListOperationsString, String listOps; public void addLink(String userId, URL url) { listOps.leftPush(userId, url.toExternalForm()); } }二、围绕着字符串的操作由于Redis中存储的键和值通常是java.lang.String因此Redis模块为RedisConnection和RedisTemplate提供了两个扩展分别是StringRedisConnectition及其DefaultStringRedissConnection实现和StringRedistTemplate作为密集String操作的便捷一站式解决方案。除了绑定到String键之外模板和连接还使用下面的StringRedisSerializer这意味着存储的键和值是人类可读的假设Redis和代码中使用相同的编码。以下列表显示了一个示例Configuration class RedisConfiguration { Bean LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); } Bean StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } }public class Example { Autowired private StringRedisTemplate redisTemplate; public void addLink(String userId, URL url) { redisTemplate.opsForList().leftPush(userId, url.toExternalForm()); } }与其他Spring模板一样RedisTemplate和StringRedisTemplet允许您通过RedisCallback接口直接与Redis对话。此功能为您提供了完全的控制因为它直接与RedisConnection对话。请注意当使用StringRedisTemplate时回调接收StringRedissConnection的实例。下面的例子展示了如何使用RedisCallback接口public void useCallback() { redisOperations.execute(new RedisCallbackObject() { public Object doInRedis(RedisConnection connection) throws DataAccessException { Long size connection.dbSize(); // Can cast to StringRedisConnection if using a StringRedisTemplate ((StringRedisConnection)connection).set(key, value); } }); }三、Serializers从框架的角度来看Redis中存储的数据只是字节。虽然Redis本身支持各种类型但在大多数情况下这些类型是指数据的存储方式而不是它所表示的内容。由用户决定是否将信息转换为字符串或任何其他对象。在Spring Data中用户自定义类型和原始数据之间的转换反之亦然由org.springframework.Data.Redis.serializer包中的Spring Data Redis处理。此包包含两种类型的序列化程序顾名思义它们负责序列化过程基于RedisSerializer的双向序列化程序。使用RedisElementReader和RedisElement Writer的元素读取器和写入器。这些变体之间的主要区别是RedisSerializer主要序列化为byte[]而读取器和写入器使用ByteBuffer。有多种实现包括本文档中已经提到的两种JdkSerializationRedisSerializer默认情况下用于RedisCache和RedisTemplate。StringRedisSerializer。然而可以通过Spring OXM支持使用OxmSerializer进行Object/XML映射或者使用Jackson2JsonRedisSerializers或GenericJackson2-JsonRedissSerializer.以JSON格式存储数据。请注意存储格式不仅限于值。它可以用于键、值或哈希没有任何限制。四、开发实例1、单机版dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependencyspring: data: redis: host: Redis所在主机地址 port: Redis对应端口号默认6379 password: 密码 lettuce: pool: max-active: 最大连接数 max-wait: 等待时长 max-idle: 最大空闲连接 min-idle: 最小空闲连接数import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisconnectionFactory; import org.springframework.data.redis.core.RedisTemplate; configuration public class Redisconfig { Bean public RedisTemplatestring, object redisTemplate(RedisconnectionFactory connectionfactory) { RedisTemplatestring, object template new RedisTemplate(); template.setconnectionFactory(connectionFactory); return template; } }service public class Userservice { Autowired private RedisTemplatestring, object redisTemplate; public void saveUser(string userId, User user) { redisTemplate.opsForValue().set(userId, user); } public User getuser(string userId) { return (user) redisTemplate.opsForValue().get(userId); } public void deleteuser(string userId) { redisTemplate.delete(userId); } public void setuserwithExpiry(string userId, User user, long timeout) { redisTemplate.opsForValue().set(userId, user, timeout, TimeUnit.SECONDS); } }二、集群版spring: redis: # 集群节点列表至少3主3从 cluster: nodes: - 192.168.1.100:7001 - 192.168.1.100:7002 - 192.168.1.100:7003 - 192.168.1.100:7004 - 192.168.1.100:7005 - 192.168.1.100:7006 max-redirects: 3 # 槽位迁移最大重定向次数 password: Redis123456 # 集群统一密码所有节点密码必须一致 # Lettuce 连接池配置 lettuce: pool: max-active: 64 max-idle: 16 min-idle: 4 max-wait: 1000ms shutdown-timeout: 100msimport org.springframework.data.redis.core.RedisTemplate; import javax.annotation.Resource; Service public class RedisClusterService { Resource private RedisTemplateString, Object redisTemplate; public void test() { // 普通单key自动路由到对应节点 redisTemplate.opsForValue().set(order:10001, 美客多订单数据); Object val redisTemplate.opsForValue().get(order:10001); // HashTag 强制多key落到同一槽支持mget/mset String tagKey1 {sync:mercadolibre}:order:10001; String tagKey2 {sync:mercadolibre}:order:10002; redisTemplate.opsForValue().multiSet(Map.of(tagKey1, a, tagKey2, b)); } }