Jedis 源代码阅读一 —— Jedis
这是jedis 源代码文件夹,我们接下来选择性阅读重要的接口以及实现。
└─redis
    └─clients
        ├─jedis
        │  │  BinaryClient.java
        │  │  BinaryJedis.java
        │  │  BinaryJedisCluster.java
        │  │  BinaryJedisPubSub.java
        │  │  BinaryShardedJedis.java
        │  │  BitOP.java
        │  │  BitPosParams.java
        │  │  Builder.java
        │  │  BuilderFactory.java
        │  │  Client.java
        │  │  Connection.java
        │  │  DebugParams.java
        │  │  GeoCoordinate.java
        │  │  GeoRadiusResponse.java
        │  │  GeoUnit.java
        │  │  HostAndPort.java
        │  │  Jedis.java
        │  │  JedisCluster.java
        │  │  JedisClusterCommand.java
        │  │  JedisClusterConnectionHandler.java
        │  │  JedisClusterInfoCache.java
        │  │  JedisFactory.java
        │  │  JedisMonitor.java
        │  │  JedisPool.java
        │  │  JedisPoolAbstract.java
        │  │  JedisPoolConfig.java
        │  │  JedisPubSub.java
        │  │  JedisSentinelPool.java
        │  │  JedisShardInfo.java
        │  │  JedisSlotBasedConnectionHandler.java
        │  │  MultiKeyPipelineBase.java
        │  │  Pipeline.java
        │  │  PipelineBase.java
        │  │  Protocol.java
        │  │  Queable.java
        │  │  Response.java
        │  │  ScanParams.java
        │  │  ScanResult.java
        │  │  ShardedJedis.java
        │  │  ShardedJedisPipeline.java
        │  │  ShardedJedisPool.java
        │  │  SortingParams.java
        │  │  Transaction.java
        │  │  Tuple.java
        │  │  ZParams.java
        │  │
        │  ├─commands
        │  │      AdvancedBinaryJedisCommands.java
        │  │      AdvancedJedisCommands.java
        │  │      BasicCommands.java
        │  │      BasicRedisPipeline.java
        │  │      BinaryJedisClusterCommands.java
        │  │      BinaryJedisCommands.java
        │  │      BinaryRedisPipeline.java
        │  │      BinaryScriptingCommands.java
        │  │      BinaryScriptingCommandsPipeline.java
        │  │      ClusterCommands.java
        │  │      ClusterPipeline.java
        │  │      Commands.java
        │  │      JedisClusterBinaryScriptingCommands.java
        │  │      JedisClusterCommands.java
        │  │      JedisClusterScriptingCommands.java
        │  │      JedisCommands.java
        │  │      MultiKeyBinaryCommands.java
        │  │      MultiKeyBinaryJedisClusterCommands.java
        │  │      MultiKeyBinaryRedisPipeline.java
        │  │      MultiKeyCommands.java
        │  │      MultiKeyCommandsPipeline.java
        │  │      MultiKeyJedisClusterCommands.java
        │  │      ProtocolCommand.java
        │  │      RedisPipeline.java
        │  │      ScriptingCommands.java
        │  │      ScriptingCommandsPipeline.java
        │  │      SentinelCommands.java
        │  │
        │  ├─exceptions
        │  │      InvalidURIException.java
        │  │      JedisAskDataException.java
        │  │      JedisClusterCrossSlotException.java
        │  │      JedisClusterException.java
        │  │      JedisClusterMaxRedirectionsException.java
        │  │      JedisConnectionException.java
        │  │      JedisDataException.java
        │  │      JedisException.java
        │  │      JedisMovedDataException.java
        │  │      JedisRedirectionException.java
        │  │
        │  └─params
        │      │  Params.java
        │      │
        │      ├─geo
        │      │      GeoRadiusParam.java
        │      │
        │      ├─set
        │      │      SetParams.java
        │      │
        │      └─sortedset
        │              ZAddParams.java
        │              ZIncrByParams.java
        │
        └─util
                ClusterNodeInformation.java
                ClusterNodeInformationParser.java
                Hashing.java
                IOUtils.java
                JedisByteHashMap.java
                JedisClusterCRC16.java
                JedisURIHelper.java
                KeyMergeUtil.java
                MurmurHash.java
                Pool.java
                RedisInputStream.java
                RedisOutputStream.java
                SafeEncoder.java
                Sharded.java
                ShardInfo.java
                Slowlog.javaJedis.java
 
我们每次使用jedis都会初始化一个jedis对象,对下面代码肯定不会陌生:
public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands,
    AdvancedJedisCommands, ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands {
  protected JedisPoolAbstract dataSource = null;
  public Jedis() {
    super();
  }
  public Jedis(final String host) {
    super(host);
  }
  public Jedis(final String host, final int port) {
    super(host, port);
  }
............Jedis对象调用父类BinaryJedis构造器:
public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKeyBinaryCommands,
        AdvancedBinaryJedisCommands, BinaryScriptingCommands, Closeable {
    protected Client client = null;
    protected Transaction transaction = null;
    protected Pipeline pipeline = null;
    public BinaryJedis() {
        client = new Client();
    }
    public BinaryJedis(final String host) {
        URI uri = URI.create(host);
        if (uri.getScheme() != null && uri.getScheme().equals("redis")) {
            initializeClientFromURI(uri);
        } else {
            client = new Client(host);
        }
    }
    public BinaryJedis(final String host, final int port) {
        client = new Client(host, port);
    }
    public BinaryJedis(final String host, final int port, final int timeout) {
        client = new Client(host, port);
        client.setConnectionTimeout(timeout);
        client.setSoTimeout(timeout);
    }实际上,new Jedis()的初始化中。最重要的是new Client()这句代码。
Client 继承自 BinaryClient
public class Client extends BinaryClient implements Commands {
  public Client() {
    super();
  }
而BinaryClient又继承自Collection
public class BinaryClient extends Connection {
 ............
  private String password;
  private int db;
  private boolean isInWatch;
............
  public BinaryClient() {
    super();
  }
............接着我们来看Collection代码:
    public class Connection implements Closeable {
    .....
    protected Connection sendCommand(final ProtocolCommand cmd, final String... args) {
        final byte[][] bargs = new byte[args.length][];
        for (int i = 0; i < args.length; i++) {
            // 对cmd判空并返回bytes
            bargs[i] = SafeEncoder.encode(args[i]);
        }
        return sendCommand(cmd, bargs);
    }
    protected Connection sendCommand(final ProtocolCommand cmd) {
        return sendCommand(cmd, EMPTY_ARGS);
    }
    protected Connection sendCommand(final ProtocolCommand cmd, final byte[]... args) {
        try {
            // 1.建立Socket连接
            connect();
            // 2.依照协议完毕IO操作,也就是命令的运行
            Protocol.sendCommand(outputStream, cmd, args);
            return this;
        } catch (JedisConnectionException ex) {
            /*
             * When client send request which formed by invalid protocol, Redis
             * send back error message before close connection. We try to read
             * it to provide reason of failure.
             */
            try {
                String errorMessage = Protocol.readErrorLineIfPossible(inputStream);
                if (errorMessage != null && errorMessage.length() > 0) {
                    ex = new JedisConnectionException(errorMessage, ex.getCause());
                }
            } catch (Exception e) {
                /*
                 * Catch any IOException or JedisConnectionException occurred
                 * from InputStream#read and just ignore. This approach is safe
                 * because reading error message is optional and connection will
                 * eventually be closed.
                 */
            }
            // Any other exceptions related to connection?
broken = true;
            throw ex;
        }
    }
    ...
    // 建立Sock连接
    public void connect() {
        if (!isConnected()) {
            try {
                socket = new Socket();
                // ->@wjw_add
                socket.setReuseAddress(true);
                socket.setKeepAlive(true); // Will monitor the TCP connection is
                // valid
                socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
                // ensure timely delivery of data
                socket.setSoLinger(true, 0); // Control calls close () method,
                // the underlying socket is closed
                // immediately
                // <-@wjw_add
                socket.connect(new InetSocketAddress(host, port), connectionTimeout);
                socket.setSoTimeout(soTimeout);
                outputStream = new RedisOutputStream(socket.getOutputStream());
                inputStream = new RedisInputStream(socket.getInputStream());
            } catch (IOException ex) {
                broken = true;
                throw new JedisConnectionException(ex);
            }
        }
    }
    ...在这里完毕了Socket连接。并返回这个Socket. 
 
每次我们使用Jedis去运行命令。都是这个持有Soket的client去运行的。
比方:
    /**
     * Get the value of the specified key. If the key does not exist null is
     * returned. If the value stored at key is not a string an error is returned
     * because GET can only handle string values.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @return Bulk reply
     */
    @Override
    public String get(final String key) {
        checkIsInMultiOrPipeline();// 检查是否在事物中;检查是否是哟好难过管道技术
        client.sendCommand(Protocol.Command.GET, key);// 使用Socket进行IO操作,运行命令
        return client.getBulkReply();
    }jedis除了继承的BinaryJedis完毕主要的IO操作。还实现了 JedisCommands, MultiKeyCommands, AdvancedJedisCommands,ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands 
这几个可使用的命令的接口。
你能够參考redis自带的 unitTest,更深入的理解。
http://download.csdn.net/detail/lemon89/9407039
关于soTimeout 与 connectionTimeOut
我不多说了,这个链接解释非常清楚。
http://stackoverflow.com/questions/7360520/connectiontimeout-versus-sockettimeout
Jedis 源代码阅读一 —— Jedis的更多相关文章
- Jedis源代码探索
		[连接池实现] [一致性hash实现] [Redis客户端-Jedis源代码探索][http://blog.sina.com.cn/s/blog_6bc4401501018bgh.html] ... 
- Mongodb源代码阅读笔记:Journal机制
		Mongodb源代码阅读笔记:Journal机制 Mongodb源代码阅读笔记:Journal机制 涉及的文件 一些说明 PREPLOGBUFFER WRITETOJOURNAL WRITETODAT ... 
- 【转】Tomcat总体结构(Tomcat源代码阅读系列之二)
		本文是Tomcat源代码阅读系列的第二篇文章,我们在本系列的第一篇文章:在IntelliJ IDEA 和 Eclipse运行tomcat 7源代码一文中介绍了如何在intelliJ IDEA 和 Ec ... 
- 利用doxygen提高源代码阅读效率
		阅读开源项目的源代码是提高自己编程能力的好方法,而有一个好的源代码阅读工具无疑能够让你在阅读源代码时事半功倍.之前找过不少源代码阅读工具,像SourceInsight.sourcenav.scitoo ... 
- CI框架源代码阅读笔记5 基准測试 BenchMark.php
		上一篇博客(CI框架源代码阅读笔记4 引导文件CodeIgniter.php)中.我们已经看到:CI中核心流程的核心功能都是由不同的组件来完毕的.这些组件类似于一个一个单独的模块,不同的模块完毕不同的 ... 
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--Schema模式
		淘宝数据库OceanBase SQL编译器部分 源代码阅读--Schema模式 什么是Database,什么是Schema,什么是Table,什么是列,什么是行,什么是User?我们能够能够把Data ... 
- CI框架源代码阅读笔记3 全局函数Common.php
		从本篇開始.将深入CI框架的内部.一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说.全局函数具有最高的载入优先权.因此大多数的框架中BootStrap ... 
- [C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化
		[C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化 // point_test.cpp : 知识点练习和测试,用于单步调试,跟 ... 
- 【转】Tomcat源代码阅读系列
		在IntelliJ IDEA 和 Eclipse运行tomcat 7源代码(Tomcat源代码阅读系列之一) Tomcat总体结构(Tomcat源代码阅读系列之二) Tomcat启动过程(Tomcat ... 
随机推荐
- 保留的 IPv4 地址
			保留的IP地址 https://en.wikipedia.org/wiki/Reserved_IP_addresses 地址块(CIDR) 范围 地址数量 范围 目的 0.0.0.0/8 0.0. ... 
- Uniform Server
			Uniform Server http://www.uniformserver.com/ https://sourceforge.net/projects/miniserver/files/ Unif ... 
- STL中向量vector笔记
			vector的本质是:数组的封装 特点:读取能在常数时间内完成 Vector成员函数 函数 表述 c.assign(beg,end) c.assign(n,elem) 将[beg; end)区间中的数 ... 
- 5.使用SOAP的XML消息传递
			转自:https://blog.csdn.net/u014066037/article/details/51724658 使用SOAP的XML消息传递的简易流程图: 详细步骤如下: (1)服务请求者的 ... 
- 洛谷 P3386 【模板】二分图匹配 Dinic版
			题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ... 
- 利用日志使管理Linux更轻松
			利用日志使管理Linux更轻松 操作系统的日志主要具有审计与监测的功能,通过对日志信息的分析,可以检查错误发生的原因,监测追踪入侵者及受到攻击时留下的痕迹,甚至还能实时的进行系统状态的监控.有效利用日 ... 
- Moodle 中文 API 之 文件管理API
			File API 文件管理 文件夹 1. 概述 2. 文件域 2.1 命名文件域 3. 提供文件给用户 4. 从用户那获取文件 5. 样例 5.1 浏览文件 5.2 移动文件 5.3 文件列表 5. ... 
- 一起talk C栗子吧(第九十八回:C语言实例--使用消息队列进行进程间通信二)
			各位看官们,大家好,上一回中咱们说的是使用消息队列进行进程间通信的样例.这一回咱们接着上一回的内容继续说使用消息队列进行进程间通信.闲话休提.言归正转.让我们一起talk C栗子吧! 我们在上一回中介 ... 
- python-string中部分string替换
			今天遇到一个问题,就是需要把 “/home/zhangshuli/32_kk/” 中的32_kk 替换成为 52_kk 然后就在网上找方法,刚开始尝试的方法是 aaa = "/home/zh ... 
- ASP.net 环境搭建
			https://www.cnblogs.com/leizhanjun/p/6081928.html 
