美文网首页
spring-data-redis exposeConnecti

spring-data-redis exposeConnecti

作者: huiwq1990 | 来源:发表于2017-07-03 19:01 被阅读0次

    问题

    spring-data-redis类加载阻塞问题。

    分析

    org.springframework.data.redis.core.RedisTemplate#execute(org.springframework.data.redis.core.RedisCallback<T>, boolean, boolean)

    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
      
    // 省略
    // 是否暴露connection,connToExpose=false会新建代理类
          RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
          T result = action.doInRedis(connToExpose);
          if (pipeline && !pipelineStatus) {
             connToUse.closePipeline();
          }
          return postProcessResult(result, connToUse, existingConnection);
       } finally {
       }
    }
    

    connection代理类

    protected RedisConnection createRedisConnectionProxy(RedisConnection pm) {
    // 会触发类加载
       Class<?>[] ifcs = ClassUtils.getAllInterfacesForClass(pm.getClass(), getClass().getClassLoader());
       return (RedisConnection) Proxy.newProxyInstance(pm.getClass().getClassLoader(), ifcs,
             new CloseSuppressingInvocationHandler(pm));
    }
    

    禁止关闭连接代理类

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
       if (method.getName().equals(EQUALS)) {
          // Only consider equal when proxies are identical.
          return (proxy == args[0]);
       } else if (method.getName().equals(HASH_CODE)) {
          // Use hashCode of PersistenceManager proxy.
          return System.identityHashCode(proxy);
    // 代理close方法,什么都不做
       } else if (method.getName().equals(CLOSE)) {
          // Handle close method: suppress, not valid.
          return null;
       }
       try {
          Object retVal = method.invoke(this.target, args);
          return retVal;
       } catch (InvocationTargetException ex) {
          throw ex.getTargetException();
       }
    }
    

    结论

    exposeConnection作用:是否暴露connection。如果暴露,connection会暴露在回调函数里
    org.springframework.data.redis.core.DefaultValueOperations#increment(K, long)

        public Long increment(K key, final long delta) {
            final byte[] rawKey = rawKey(key);
            return execute(new RedisCallback<Long>() {
    
                public Long doInRedis(RedisConnection connection) {
    // 这里可以把connection关闭,不安全。
                    return connection.incrBy(rawKey, delta);
                }
    // 一般会设置为true
            }, true);
        }
    

    RedisTemplate的exposeConnection默认为false,在操作的时候一般需要显示传参设置为true。

    相关文章

      网友评论

          本文标题:spring-data-redis exposeConnecti

          本文链接:https://www.haomeiwen.com/subject/bzszcxtx.html