• redisTemplate类学习及理解


    
    
    List<Object> list = masterRedisTemplate.executePipelined((RedisCallback<Long>) connection -> {
                StringRedisConnection redisConn = (StringRedisConnection) connection;
                Integer expireTime = XXX;
                redisConn.expire(XXX);
                RedisUtil.addSameScoreTail(XXXX);
                return null;
            });
    
    
    
     

        redisTemplate简化Redis数据访问代码的Helper类。在给定对象和中的基础二进制数据之间执行自动序列化/反序列化。中心方法是execute,支持实现X接口的Redis访问代码,它提供了RedisConnection处理,使得RedisCallback实现和调用代码都不需要显式关心检索/关闭Redis连接,或处理连接生命周期异常。对于典型的单步动作,有各种方便的方法。一旦配置好,这个类就是线程安全的。这是Redis支持的核心类。

      1 public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
          
    接口 RedisAccessor:,该接口指定了一组基本的Redis操作,由RedisTemplate实现。不经常使用,但对于可扩展性和可测试性来说是一个有用的选项(因为它很容易被模仿或存根)。
         

    2
    private boolean enableTransactionSupport = false;
          true:开启之后则开启事务;
      3     private boolean exposeConnection = false;
          
    曝光链接

        @Override
        public List<Object> executePipelined(RedisCallback<?> action, @Nullable RedisSerializer<?> resultSerializer) {

          return execute((RedisCallback<List<Object>>) connection -> {

    首先开通连接
            connection.openPipeline();

    标志连接是否关闭  这里有个问题时下面这个true设置是为什么 后续是不是会改为false,要不导致内存泄漏了。 :::在deserialize这个方法里传的closePipline参数可以把关闭连接传递过去。
            boolean pipelinedClosed = false;
            try {

    其次处理传来的action的doInRedis方法。 这个doinredis方法就是本文第一个代码块的代码,即当前方法入参传过来的代码块的内容。
    Object result = action.doInRedis(connection);
              if (result != null) {
                throw new InvalidDataAccessApiUsageException(
                  "Callback cannot return a non-null value as it gets overwritten by the pipeline");
                }
                List<Object> closePipeline = connection.closePipeline();
                pipelinedClosed = true;

    最后调用deserializeMixedResults,把返回结果带入到execute去继续执行。  这个是一个反序列化相关的方法。
    return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
            } finally {
              if (!pipelinedClosed) {
      connection.closePipeline();
            }
            }
          });
        }

    StringRedisConnection redisConn = (StringRedisConnection) connection; 在调用executePipelined前,可以用来操作数据。

      这个execute是executePipelined处理的具体实现。

       @Nullable
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it"); Assert.notNull(action, "Callback object must not be null"); RedisConnectionFactory factory = getRequiredConnectionFactory(); RedisConnection conn = null; try { if (enableTransactionSupport) { // only bind resources in case of potential transaction synchronization conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport); } else { conn = RedisConnectionUtils.getConnection(factory); } boolean existingConnection = TransactionSynchronizationManager.hasResource(factory); RedisConnection connToUse = preProcessConnection(conn, existingConnection); boolean pipelineStatus = connToUse.isPipelined(); if (pipeline && !pipelineStatus) { connToUse.openPipeline(); } RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse)); T result = action.doInRedis(connToExpose);
    具体执行的也是本文最上面的代码块里的方法。
    // close pipeline if (pipeline && !pipelineStatus) { connToUse.closePipeline(); } // TODO: any other connection processing? return postProcessResult(result, connToUse, existingConnection); } finally { RedisConnectionUtils.releaseConnection(conn, factory); } }

    redisTemplate其他方法

    delete

    @Override
        public Boolean delete(K key) {
          key转成序列化的
            byte[] rawKey = rawKey(key);
          调用execute方法
            Long result = execute(connection -> connection.del(rawKey), true);
          判断返回值
            return result != null && result.intValue() == 1;
        }

    这个execute也是调用的上面的execute方法,获取到连接之后,执行代码块里的del命令。

    expire

    加失效时间

    @Override
        public Boolean expire(K key, final long timeout, final TimeUnit unit) {
          序列化
            byte[] rawKey = rawKey(key);
          计算超时时间
    long rawTimeout = TimeoutUtils.toMillis(timeout, unit); return execute(connection -> { try {
              调用
    return connection.pExpire(rawKey, rawTimeout); } catch (Exception e) { // Driver may not support pExpire or we may be running on Redis 2.4 return connection.expire(rawKey, TimeoutUtils.toSeconds(timeout, unit)); } }, true); }

    计算好了之后 同样也是通过execute方法,获取连接后执行。

    opsForHash

    RedisTemplate.opsForHash().put/get/delete等等
    HashOperations
     @Override
        public <HK, HV> HashOperations<K, HK, HV> opsForHash() {
            return new DefaultHashOperations<>(this);
        }
    
    这个方法实现了hashOperations接口
    class DefaultHashOperations<K, HK, HV> extends AbstractOperations<K, Object> implements HashOperations<K, HK, HV> {
    
        @SuppressWarnings("unchecked")
        DefaultHashOperations(RedisTemplate<K, ?> template) {
            super((RedisTemplate<K, Object>) template);
        }
    }
    @Override
        public void put(K key, HK hashKey, HV value) {
    
            byte[] rawKey = rawKey(key);
            byte[] rawHashKey = rawHashKey(hashKey);
            byte[] rawHashValue = rawHashValue(value);
    
            execute(connection -> {
    这里通过execute方法,把这个代码块执行。具体的参数是key ,hashkey,value 的三个序列化之后的参数。 connection.hSet(rawKey, rawHashKey, rawHashValue);
    return null; }, true); }

    OpsForSet()

    RedisTemplate.opsForSet().add(key, value);
    
    
    public Long add(K key, V... values) {
          序列化
            byte[] rawKey = rawKey(key);
          values是多组二进制
    byte[][] rawValues = rawValues((Object[]) values);
          
    return execute(connection -> connection.sAdd(rawKey, rawValues), true); }

    大致就是相关的用法,不通的数据结构 ,有自己特有的Operations方法,可以具体查看。

  • 相关阅读:
    Heartbeat+Haproxy实现负载均衡高可用
    Heartbeat+Haproxy实现负载均衡高可用
    Heartbeat+Haproxy实现负载均衡高可用
    Heartbeat+Haproxy实现负载均衡高可用
    apache调优技巧之一隐藏apahce版本信息
    apache调优技巧之一隐藏apahce版本信息
    apache调优技巧之一隐藏apahce版本信息
    apache调优技巧之一隐藏apahce版本信息
    用VC实现洪水攻击程序
    WebAPI返回数据类型解惑 以及怎样解决Extjs无法解析返回的xml
  • 原文地址:https://www.cnblogs.com/jiangym/p/16017462.html
Copyright © 2020-2023  润新知