Spring 中使用 Redis

本文介绍了如何在 Spring 项目中集成 Redis,包括 Maven 配置、连接 Redis 的两种方式(Lettuce 和 Jedis Connector)、使用 RedisTemplate 以及哨兵模式。特别强调了 RedisTemplate 在不同数据类型操作中的应用,如 ValueOperations、ListOperations、SetOperations 和 HashOperations。文章还讨论了 Spring 提供的多种序列化方式,如默认的 JDK 序列化和使用 Jackson 序列化的不同形式,并解释了 Pipeline 管道操作在提高效率方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引入

  • Maven
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.0.9.RELEASE</version>
</dependency>

连接 Redis
使用 Lettuce 或者 Jedis

  • Lettuce Connector
@Configuration
class AppConfig {

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
    }
}
  • Jedis Connector
@Configuration
class AppConfig {

    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
    }
}

使用哨兵模式

/**
 * jedis
 */
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new JedisConnectionFactory(sentinelConfig);
}

/**
 * Lettuce
 */
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new LettuceConnectionFactory(sentinelConfig);
}

使用 RedisTemplate
Spring 提供了 RedisTemplate 类来操作 Redis,它高度抽象了 Redis 的各种操作, 根据不同的数据类型提供了对应的 operation,常用的如

  • ValueOperations 字符串
  • ListOperations 列表
  • SetOperations 集合
  • HashOperations 哈希表

因为我们通常使用 String 作为 key 和 value,所以 Spring 提供了 StringRedisTemplate 类,该类使用 StringRedisSerializer 进行序列化.

一个例子:

public class Example {

    @Autowired
    private StringRedisTemplate redisTemplate;

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

序列化
Spring 提供了多种序列化方式

  • JdkSerializationRedisSerializer RedisTemplate 默认序列化器,使用 JDK 原生序列化方式
  • StringRedisSerializer
  • Jackson2JsonRedisSerializer 使用 Jackson, 以 JSON 格式存储数据
  • GenericJackson2JsonRedisSerializer 使用 Jackson, 以 JSON 格式存储数据, JSON 中会存储对象类型

我们在 Java 中经常要存储对象, 此时可配置 Jackson2JsonRedisSerializer 或者 GenericJackson2JsonRedisSerializer

@Bean
public RedisTemplate<String, Person> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
    RedisTemplate<String, Person> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(lettuceConnectionFactory);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Person.class));

    return redisTemplate;
}

或者

@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(lettuceConnectionFactory);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

    return redisTemplate;
}

两者的区别是 GenericJackson2JsonRedisSerializer 在构造时不需要指定一个 Java 对象类型,当你需要存储不同的 Java 对象,又不想配置多个 RedisTemplate 的时候,就可以使用 GenericJackson2JsonRedisSerializer,在 Redis 中查看数据,可以发现 GenericJackson2JsonRedisSerializer 存储的 JSON 数据会多一个 @Class 的键,存储了该 JSON 对应的 Java 数据类型.

管道
多个操作使用管道能减少网络通讯消耗的时间。RedisTemplate 提供了几个方法来进行管道操作,如果不关心返回值,则可直接使用 execute 方法,如果需要返回值,使用 executePipelined 方法。

List<Object> results = stringRedisTemplate.executePipelined(
  new RedisCallback<Object>() {
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
      StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
      for(int i=0; i< batchSize; i++) {
        stringRedisConn.rPop("myqueue");
      }
    return null;
  }
});

RedisCallback 中 doInRedis 的返回值必须为 null

另一个重载的方法传递 SessionCallback

 public List<Object> getLockers(List<Integer> ids) {
      return redisTemplate.executePipelined(new SessionCallback<Locker>() {

          @Override
          public <K, V> Locker execute(RedisOperations<K, V> operations) throws DataAccessException {
              return null;
          }
      });
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值