美文网首页
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