Spring redis实现

redis用的人很多,网络上基本都是一些入门配置。我想介绍下spring redis的实现(以接入Jedis客户端为例)。

spring redis中最主要的类就是RedisTemplate。

RedisTemplate

  • RedisTemplate实现了RedisOperations,即本身就是一个Operations。

RedisTemplate序列化

Redis存储的键值都需要序列化后传输。这是因为client 和 server 间的协议要求的是 byte,而Jedis 提供了 string 和 byte[] 类型的函数接口。序列化的工具很多,RedisTemplate默认使用JdkSerializationRedisSerializer。

   private boolean enableDefaultSerializer = true;
   private RedisSerializer defaultSerializer = new JdkSerializationRedisSerializer();
   
   private RedisSerializer keySerializer = null;
   private RedisSerializer valueSerializer = null;
   private RedisSerializer hashKeySerializer = null;
   private RedisSerializer hashValueSerializer = null;
   private RedisSerializer stringSerializer = new StringRedisSerializer();

如果要序列化的对象是String。需要使用对应的StringRedisSerializer,否则会出现\xac\xed\x00\x05t\x00\tb类似的乱码前缀。所以,要配置合适的序列化工具。
详情请看:Spring Data操作Redis时,发现key值出现\xac\xed\x00\x05t\x00\tb

RedisTemplate的操作视图

  • RedisTemplate中将redis的操作进行分类(如将Value类型的操作封装在ValueOperations中,将List类型的操作封装在ListOperations中)。更方便管理,也符合人们的使用习惯。
    RedisTemplate中通过如下方法获得对应的Operations。
   public ValueOperations opsForValue() {
     if (valueOps == null) {
       valueOps = new DefaultValueOperations(this);
     }
     return valueOps;
   }

RedisTemplate还提供了与Operations对应的BoundValueOperations。BoundOperations绑定了key值,通过代理实现Operations的功能。
RedisTemplate中通过如下方法获得对应的BoundOperations。

   public BoundValueOperations boundValueOps(K key)  {
     return new DefaultBoundValueOperations(key, this);//此处将RedisTemplate对象传递给DefaultBoundValueOperations对象
   }
   private final ValueOperations ops;
   public DefaultBoundValueOperations(K key, RedisOperations operations){
     super(key, operations);//将RedisTemplate对象注入
     ops = operations.opsForValue(); 
   }

BoundValueOperations作为ValueOperations的代理供外部调用。

   public V get() {
     return (V)ops.get(getKey());
   }

所以,不管是ValueOperations还是BoundValueOperations,本质上都是通过ValueOperations来操作。

我摘抄了一点DefaultValueOperations中的代码,其他的方法基本如此:

  public V get(Object key)
  {
    return execute(new AbstractOperations.ValueDeserializingRedisCallback(this, key)
    {
      protected byte[] inRedis(, RedisConnection connection) {
        return connection.get(rawKey);
      }
    }
    , true);
  }

由此可见,所有操作redis的操作都是在调用RedisTemplate的execute方法执行。execute方法有三类。

  • public T execute(RedisCallback action, boolean exposeConnection, boolean pipeline)
  • public T execute(SessionCallback session)
  • public List executePipelined(final SessionCallback session, final RedisSerializer resultSerializer)

    其中,execute(RedisCallback action, boolean exposeConnection, boolean pipeline)是无事物的。每次访问都到连接池拿取一个连接(池子里没有连接并且可以新建的话,就新建连接)。(此处有个是否支持事物的配置enableTransactionSupport,据说支持的不好,是个坑。未验证到底是怎么回事)

    连接池根据配置信息,定时扫描检测池子里的连接。清除无用连接或多余连接,或新建连接。保证连接池的清洁有效。

    execute(SessionCallback session)是大家比较推崇的spring redis使用事物的方式。将连接绑定到RedisConnectionHolder上,使用结束,解绑,归还连接。此处,可以通过设置RedisConnection的watch、multi、exec指令保证数据的一致性。

    executePipelined可以通过管道发送多个redis命令,这些命令会一起执行,不能互相有依赖。

    你可能感兴趣的:(Spring redis实现)