Spring与Redis的集成详解二

Jedis获取Redis连接详解: http://donald-draper.iteye.com/blog/2347121
Redis的客户端Jedis及Jedis操作Redis命令详解: http://donald-draper.iteye.com/blog/2347192
Spring与Redis的集成详解一: http://donald-draper.iteye.com/blog/2347337
上一篇我们分析了Jedis连接工厂创建redis连接JedisConnection,及RedisTemplate执行Redis回调接口方法,
今天来看一下RedisTemplate的相关设值方法
public class RedisTemplate extends RedisAccessor
    implements RedisOperations
{
    private boolean exposeConnection;
    private RedisSerializer defaultSerializer;
    private RedisSerializer keySerializer;
    private RedisSerializer valueSerializer;
    private RedisSerializer hashKeySerializer;
    private RedisSerializer hashValueSerializer;
    private RedisSerializer stringSerializer;
    private ValueOperations valueOps;
    private ListOperations listOps;
    private SetOperations setOps;
    private ZSetOperations zSetOps;
     public RedisTemplate()
    {
        exposeConnection = false;
        defaultSerializer = new JdkSerializationRedisSerializer();
        keySerializer = null;
        valueSerializer = null;
        hashKeySerializer = null;
        hashValueSerializer = null;
        stringSerializer = new StringRedisSerializer();
    }
    //序列化字符串,这个我们在上一篇中,一看到
     private byte[] rawString(String key)
    {
        return stringSerializer.serialize(key);
    }
    //删除key
    public void delete(Object key)
    {
        final byte rawKey[] = rawKey(key);
        execute(new RedisCallback() {
           //从前文的分析中,connection实际为JedisConnection
            public Object doInRedis(RedisConnection connection)
            {
                connection.del(new byte[][] {
                    rawKey
                });
                return null;
            }

            final byte val$rawKey[];
            final RedisTemplate this$0;

            
            {
                this$0 = RedisTemplate.this;
                rawKey = abyte0;
                super();
            }
        }, true);
    }
    //过期时间设置
    public Boolean expire(Object key, long timeout, TimeUnit unit)
    {
        final byte rawKey[] = rawKey(key);
        final long rawTimeout = unit.toSeconds(timeout);
        return (Boolean)execute(new RedisCallback() {

            public Boolean doInRedis(RedisConnection connection)
            {
                return connection.expire(rawKey, rawTimeout);
            }

            public volatile Object doInRedis(RedisConnection x0)
                throws DataAccessException
            {
                return doInRedis(x0);
            }

            final byte val$rawKey[];
            final long val$rawTimeout;
            final RedisTemplate this$0;

            
            {
                this$0 = RedisTemplate.this;
                rawKey = abyte0;
                rawTimeout = l;
                super();
            }
        }, true);
    }
    //重命令key
     public void rename(Object oldKey, Object newKey)
    {
        final byte rawOldKey[] = rawKey(oldKey);
        final byte rawNewKey[] = rawKey(newKey);
        execute(new RedisCallback() {

            public Object doInRedis(RedisConnection connection)
            {
                connection.rename(rawOldKey, rawNewKey);
                return null;
            }

            final byte val$rawOldKey[];
            final byte val$rawNewKey[];
            final RedisTemplate this$0;

            
            {
                this$0 = RedisTemplate.this;
                rawOldKey = abyte0;
                rawNewKey = abyte1;
                super();
            }
        }, true);
    }
    //开启事务
    public void multi()
    {
        execute(new RedisCallback() {

            public Object doInRedis(RedisConnection connection)
                throws DataAccessException
            {
                connection.multi();
                return null;
            }

            final RedisTemplate this$0;

            
            {
                this$0 = RedisTemplate.this;
                super();
            }
        }, true);
    }
}

从RedisTemplate的关于key的相关操作都是封装在Redis回调接口中,然后再执行。

我们在来看JedisConnection
public class JedisConnection
    implements RedisConnection
{
    private static final Field CLIENT_FIELD;
    private static final Method SEND_COMMAND;//发送命令方法
    private static final Method GET_RESPONSE;
    private final Jedis jedis;//jedis连接
    private final Client client;//jedis与redis的socket客户端
    private final BinaryTransaction transaction;//事务
    private final Pool pool;//Jedis连接池
    private boolean broken;
    private volatile JedisSubscription subscription;
    private volatile Pipeline pipeline;//管道
    private final int dbIndex;//数据库

    static 
    {
        //通过反射工具获取BinaryJedis的Client属性
        CLIENT_FIELD = ReflectionUtils.findField(redis/clients/jedis/BinaryJedis, "client", redis/clients/jedis/Client);
        ReflectionUtils.makeAccessible(CLIENT_FIELD);
	//获取Jedis的Connection发送命令方法
        SEND_COMMAND = ReflectionUtils.findMethod(redis/clients/jedis/Connection, "sendCommand", new Class[] {
            redis/clients/jedis/Protocol$Command, [[B
        });
        ReflectionUtils.makeAccessible(SEND_COMMAND);
        //Jedis的Connection获取redis回复结果的方法
        GET_RESPONSE = ReflectionUtils.findMethod(redis/clients/jedis/Queable, "getResponse", new Class[] {
            redis/clients/jedis/Builder
        });
        ReflectionUtils.makeAccessible(GET_RESPONSE);
    }
    public JedisConnection(Jedis jedis, Pool pool, int dbIndex)
    {
        broken = false;
        this.jedis = jedis;
	//获取Jedis的Client属性
        client = (Client)ReflectionUtils.getField(CLIENT_FIELD, jedis);
	//设置事务
        transaction = new Transaction(client);
	//连接池
        this.pool = pool;
	//数据库
        this.dbIndex = dbIndex;
        if(dbIndex > 0)
	    //切换数据库
            select(dbIndex);
    }
}

//Transaction
public class Transaction extends BinaryTransaction
{
 public Transaction(Client client)
    {
        super(client);
    }
    //设置键过期时间
    public Response expire(String key, int seconds)
    {
        client.expire(key, seconds);
        return getResponse(BuilderFactory.LONG);
    }
    //获取键值
    public Response get(String key)
    {
        client.get(key);
        return getResponse(BuilderFactory.STRING);
    }
}

再看BinaryTransaction
public class BinaryTransaction extends Queable
{
   protected Client client;//redis客户端
   protected boolean inTransaction;//是否为事务
   public BinaryTransaction(Client client)
    {
        this.client = null;
        inTransaction = true;
        this.client = client;
    }
     public Response setnx(byte key[], byte value[])
    {
        client.setnx(key, value);
        return getResponse(BuilderFactory.LONG);
    }
}

//Queable
public class Queable
{
    private Queue pipelinedResponses;//实际为LinkedList
    public Queable()
    {
        pipelinedResponses = new LinkedList();
    }
    protected void clean()
    {
        pipelinedResponses.clear();
    }
    protected Response generateResponse(Object data)
    {
        Response response = (Response)pipelinedResponses.poll();
        if(response != null)
            response.set(data);
        return response;
    }
    //事务开启的情况下,将Redis返回结果添加到队列中
    protected Response getResponse(Builder builder)
    {
        Response lr = new Response(builder);
        pipelinedResponses.add(lr);
        return lr;
    }

}

下面来看一下JedisConnection的相关方法
//是否为事务
 public boolean isQueueing()
    {
        return client.isInMulti();
    }
//打开管道
public void openPipeline()
    {
        if(pipeline == null)
            pipeline = jedis.pipelined();
    }
//刷新DB
 public void flushDb()
    {
        try
        {
            if(isQueueing())
                transaction.flushDB();
            if(isPipelined())
                pipeline.flushDB();
            jedis.flushDB();
        }
        catch(Exception ex)
        {
            throw convertJedisAccessException(ex);
        }
    }
//Dump 数据库
public void bgSave()
    {
        try
        {
            if(isQueueing())
                throw new UnsupportedOperationException();
            if(isPipelined())
            {
                pipeline.bgsave();
                return;
            }
        }
        catch(Exception ex)
        {
            throw convertJedisAccessException(ex);
        }
        jedis.bgsave();
    }
//写AOP
 public void bgWriteAof()
    {
        try
        {
            if(isQueueing())
                throw new UnsupportedOperationException();
            if(isPipelined())
            {
                pipeline.bgrewriteaof();
                return;
            }
        }
        catch(Exception ex)
        {
            throw convertJedisAccessException(ex);
        }
        jedis.bgrewriteaof();
    }
//开启事务
 public void multi()
    {
        if(isQueueing())
            return;
        try
        {
            if(isPipelined())
            {
                pipeline.multi();
                return;
            }
        }
        catch(Exception ex)
        {
            throw convertJedisAccessException(ex);
        }
        jedis.multi();
    }
//key不存在则设置
public Boolean setNX(byte key[], byte value[])
    {
        if(!isQueueing())
            break MISSING_BLOCK_LABEL_19;
        transaction.setnx(key, value);
        return null;
        if(!isPipelined())
            break MISSING_BLOCK_LABEL_38;
        pipeline.setnx(key, value);
        return null;
        return JedisUtils.convertCodeReply(jedis.setnx(key, value));
        Exception ex;
        ex;
        throw convertJedisAccessException(ex);
    }

从分析JedisConnection方法可以看出,JedisConnection相关方法都是依托于Jedis,Cclient和Transaction;
总结:
RedisTemplate的关于key的相关操作都是封装在Redis回调接口中,然后再执行;
JedisConnection相关方法都是依托于Jedis,Cclient和Transaction。


//Response
class Response
{
    protected Object response;
    private boolean built;
    private boolean set;
    private Builder builder;
    private Object data;
    public Response(Builder b)
    {
        response = null;
        built = false;
        set = false;
        builder = b;
    }
    public void set(Object data)
    {
        this.data = data;
        set = true;
    }
    public Object get()
    {
        if(!set)
            throw new JedisDataException("Please close pipeline or multi block before calling this method.");
        if(!built)
        {
            if(data != null)
            {
                if(data instanceof JedisDataException)
                    throw new JedisDataException((JedisDataException)data);
                response = builder.build(data);
            }
            data = null;
            built = true;
        }
        return response;
    }
    public String toString()
    {
        return (new StringBuilder()).append("Response ").append(builder.toString()).toString();
    }
}

猜你喜欢

转载自donald-draper.iteye.com/blog/2347349
今日推荐