透過 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.