通过 RedisTemplate 使用对象

大多数用户可能会使用 RedisTemplate 及其对应的包 org.springframework.data.redis.core,或其响应式变体 ReactiveRedisTemplate。实际上,由于其丰富的功能集,该模板是 Redis 模块的核心类。该模板为 Redis 交互提供了高级抽象。虽然 [Reactive]RedisConnection 提供了接受和返回二进制值(byte 数组)的低级方法,但模板负责序列化和连接管理,使用户无需处理这些细节。

RedisTemplate 类实现了 RedisOperations 接口,其响应式变体 ReactiveRedisTemplate 实现了 ReactiveRedisOperations

引用 [Reactive]RedisTemplate 实例上操作的首选方式是通过 [Reactive]RedisOperations 接口。

此外,模板提供了操作视图(遵循 Redis 命令参考中的分组),这些视图提供了丰富、泛化的接口,用于针对特定类型或特定键(通过 KeyBound 接口)进行操作,如下表所述

操作视图
  • 命令式

  • Reactive

接口 描述

键类型操作

GeoOperations

Redis 地理空间操作,例如 GEOADDGEORADIUS

HashOperations

Redis 哈希操作

HyperLogLogOperations

Redis HyperLogLog 操作,例如 PFADDPFCOUNT

ListOperations

Redis 列表操作

SetOperations

Redis 集合操作

ValueOperations

Redis 字符串(或值)操作

ZSetOperations

Redis 有序集合(或排序集合)操作

键绑定操作

BoundGeoOperations

Redis 键绑定地理空间操作

BoundHashOperations

Redis 哈希键绑定操作

BoundKeyOperations

Redis 键绑定操作

BoundListOperations

Redis 列表键绑定操作

BoundSetOperations

Redis 集合键绑定操作

BoundValueOperations

Redis 字符串(或值)键绑定操作

BoundZSetOperations

Redis 有序集合(或排序集合)键绑定操作

接口 描述

键类型操作

ReactiveGeoOperations

Redis 地理空间操作(例如 GEOADDGEORADIUS 等)

ReactiveHashOperations

Redis 哈希操作

ReactiveHyperLogLogOperations

Redis HyperLogLog 操作(例如 (PFADDPFCOUNT 等)

ReactiveListOperations

Redis 列表操作

ReactiveSetOperations

Redis 集合操作

ReactiveValueOperations

Redis 字符串(或值)操作

ReactiveZSetOperations

Redis 有序集合(或排序集合)操作

一旦配置,模板是线程安全的,并且可以在多个实例之间重用。

RedisTemplate 对其大多数操作使用基于 Java 的序列化器。这意味着模板写入或读取的任何对象都通过 Java 进行序列化和反序列化。

您可以在模板上更改序列化机制,Redis 模块提供了几种实现,这些实现在 org.springframework.data.redis.serializer 包中可用。有关更多信息,请参阅 序列化器。您还可以将任何序列化器设置为 null,并通过将 enableDefaultSerializer 属性设置为 false 来使用原始字节数组的 RedisTemplate。请注意,模板要求所有键都非空。但是,只要底层序列化器接受它们,值可以为 null。有关更多信息,请阅读每个序列化器的 Javadoc。

对于需要特定模板视图的情况,将该视图声明为依赖项并注入模板。容器会自动执行转换,从而无需 opsFor[X] 调用,如以下示例所示

配置模板 API
  • Java 命令式

  • Java 响应式

  • XML

@Configuration
class MyConfig {

  @Bean
  LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
  }

  @Bean
  RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {

    RedisTemplate<String, String> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    return template;
  }
}
@Configuration
class MyConfig {

  @Bean
  LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
  }

  @Bean
  ReactiveRedisTemplate<String, String> ReactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory) {
    return new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.string());
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
  <!-- redis template definition -->
  <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="redisConnectionFactory"/>
  ...

</beans>
使用 [Reactive]RedisTemplate 将项目推送到列表
  • 命令式

  • Reactive

public class Example {

  // inject the actual operations
  @Autowired
  private RedisOperations<String, String> operations;

  // inject the template as ListOperations
  @Resource(name="redisTemplate")
  private ListOperations<String, String> listOps;

  public void addLink(String userId, URL url) {
    listOps.leftPush(userId, url.toExternalForm());
  }
}
public class Example {

  // inject the actual template
  @Autowired
  private ReactiveRedisOperations<String, String> operations;

  public Mono<Long> addLink(String userId, URL url) {
    return operations.opsForList().leftPush(userId, url.toExternalForm());
  }
}

面向字符串的便利类

由于存储在 Redis 中的键和值通常是 java.lang.String,Redis 模块为 RedisConnectionRedisTemplate 分别提供了两个扩展:StringRedisConnection(及其 DefaultStringRedisConnection 实现)和 StringRedisTemplate,作为进行密集字符串操作的便捷一站式解决方案。除了绑定到 String 键之外,模板和连接在底层使用 StringRedisSerializer,这意味着存储的键和值是人类可读的(假设 Redis 和您的代码都使用相同的编码)。以下列表显示了一个示例

  • Java 命令式

  • Java 响应式

  • XML

@Configuration
class RedisConfiguration {

  @Bean
  LettuceConnectionFactory redisConnectionFactory() {
    return new LettuceConnectionFactory();
  }

  @Bean
  StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {

    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }
}
@Configuration
class RedisConfiguration {

  @Bean
  LettuceConnectionFactory redisConnectionFactory() {
    return new LettuceConnectionFactory();
  }

  @Bean
  ReactiveStringRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) {
    return new ReactiveStringRedisTemplate<>(factory);
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>

  <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="redisConnectionFactory"/>

</beans>
  • 命令式

  • Reactive

public class Example {

  @Autowired
  private StringRedisTemplate redisTemplate;

  public void addLink(String userId, URL url) {
    redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
  }
}
public class Example {

  @Autowired
  private ReactiveStringRedisTemplate redisTemplate;

  public Mono<Long> addLink(String userId, URL url) {
    return redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
  }
}

与其他 Spring 模板一样,RedisTemplateStringRedisTemplate 允许您通过 RedisCallback 接口直接与 Redis 通信。此功能使您拥有完全控制权,因为它直接与 RedisConnection 通信。请注意,当使用 StringRedisTemplate 时,回调会收到 StringRedisConnection 的实例。以下示例演示了如何使用 RedisCallback 接口

public void useCallback() {

  redisOperations.execute(new RedisCallback<Object>() {
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
      Long size = connection.dbSize();
      // Can cast to StringRedisConnection if using a StringRedisTemplate
      ((StringRedisConnection)connection).set("key", "value");
    }
   });
}

序列化器

从框架的角度来看,存储在 Redis 中的数据只是字节。虽然 Redis 本身支持各种类型,但在大多数情况下,这些类型指的是数据的存储方式,而不是它所代表的内容。由用户决定信息是转换为字符串还是任何其他对象。

在 Spring Data 中,用户(自定义)类型与原始数据之间的转换(反之亦然)由 Spring Data Redis 在 org.springframework.data.redis.serializer 包中处理。

此包包含两种类型的序列化器,顾名思义,它们负责序列化过程

  • 基于 RedisSerializer 的双向序列化器。

  • 使用 RedisElementReaderRedisElementWriter 的元素读取器和写入器。

这些变体之间的主要区别在于 RedisSerializer 主要序列化为 byte[],而读取器和写入器使用 ByteBuffer

提供了多种实现(包括本文档中已提及的两种)

但是,可以使用 OxmSerializer 通过 Spring OXM 支持进行对象/XML 映射,或者使用 JacksonJsonRedisSerializerGenericJacksonJsonRedisSerializer 将数据存储为 JSON 格式。

请注意,存储格式不仅限于值。它可以用于键、值或哈希,没有任何限制。

默认情况下,RedisCacheRedisTemplate 配置为使用 Java 原生序列化。Java 原生序列化以允许运行远程代码而闻名,这些代码是由利用易受攻击的库和类注入未经验证的字节码的有效负载引起的。在反序列化步骤中,被操作的输入可能导致应用程序中运行不需要的代码。因此,请勿在不受信任的环境中使用序列化。通常,我们强烈建议使用任何其他消息格式(例如 JSON)代替。

如果您担心 Java 序列化引起的安全漏洞,请考虑核心 JVM 级别的通用序列化过滤器机制

© . This site is unofficial and not affiliated with VMware.