`
Donald_Draper
  • 浏览: 981398 次
社区版块
存档分类
最新评论

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();
    }
}
0
0
分享到:
评论

相关推荐

    Spring集成redis集群

    **Spring集成Redis集群详解** 在现代的Web应用程序开发中,数据缓存扮演着至关重要的角色,而Redis作为一款高性能的键值数据存储系统,被广泛应用于缓存、消息队列等多个场景。当业务规模扩大,单机Redis可能无法...

    spring redis集成

    **Spring Redis 集成详解** 在现代的Java开发中,Spring框架因其强大的功能和灵活性而备受青睐。随着数据存储技术的发展,Redis作为一款高性能的键值存储系统,被广泛应用于缓存、消息队列等多个场景。Spring为...

    Spring+redis5.05配置过程.docx

    Spring+Redis 5.05 配置过程详解 Spring 和 Redis 配置概述 在本文档中,我们将详细介绍如何配置 Spring 和 Redis 5.05,以实现高效的缓存和数据存储。Redis 作为一个高性能的 NoSQL 数据库,广泛应用于缓存、消息...

    Spring Data Redis中文参考文档

    2. **集成Spring生态**:该模块与Spring框架紧密结合,可以无缝集成到基于Spring的应用程序中,简化了配置和依赖管理过程。 3. **模板和便捷类**:提供`RedisTemplate`和一系列便捷类,如`StringRedisTemplate`等,...

    spring集成redis

    **Spring 集成 Redis 知识点详解** 在现代Web开发中,Redis作为一个高性能的键值对数据存储系统,常被用作缓存、消息队列等多种场景。Spring框架提供了方便的集成方式,使得我们可以轻松地在Java应用中利用Redis的...

    Spring整合Redis

    **Spring 整合 Redis 知识点详解** 在现代Web应用开发中,缓存系统扮演着至关重要的角色,其中Redis作为一个高性能的键值对数据存储系统,被广泛应用于缓存、消息队列等多个场景。Spring作为Java领域的主流框架,与...

    Spring Boot Redis 集成配置详解

    Spring Boot Redis 集成配置详解 Spring Boot 是一个基于Java的开源框架,旨在简化基于Spring的应用程序的搭建过程。Redis 是一个开源的、基于内存的数据结构存储系统,可以用作数据库、消息队列、 Cache 等。集成 ...

    spring集成redis cluster详解

    主要介绍了spring集成redis cluster详解,分享了maven依赖,Spring配置,增加connect-redis.properties 配置文件等相关内容,具有一定参考价值,需要的朋友可以了解下。

    Spring-data-redis使用指南

    ### Spring Data Redis 使用指南知识点详解 #### 一、Spring Data Redis 概览 **Spring Data Redis** 是 **Spring Data** 家族中的一个模块,它为 **Redis** 提供了一套方便的操作接口,使得开发人员可以更加高效...

    spring-redis jar

    《Spring与Redis的集成应用详解》 在现代的Web开发中,数据缓存技术起着至关重要的作用,它能够显著提升应用的性能和响应速度。Spring框架作为Java领域中的主流开发框架,提供了丰富的扩展性,使得与其他技术的集成...

    spring-redis.txt

    ### Spring 整合 Redis 配置详解 在现代软件开发中,Redis 作为一种高性能的键值存储数据库,常被用于缓存、会话管理、消息队列等多种应用场景。Spring 框架则提供了丰富的功能来简化 Java 应用程序的开发。本文将...

    详解SSH框架和Redis的整合

    1. **相关Jar文件**:为了实现SSH与Redis的整合,需要引入Redis客户端Jedis的jar包(如jedis-2.3.1.jar)以及Spring对Redis支持的相关jar包(如spring-data-redis-1.3.4.RELEASE.jar)。此外,还需要连接池管理的库...

    spring-data-redis实例

    二、集成Spring Data Redis 在Java项目中集成Spring Data Redis,首先需要在pom.xml文件中添加Spring Data Redis的依赖。接着,在Spring配置文件中定义RedisConnectionFactory和RedisTemplate,这两者是操作Redis的...

    spring-boot2集成redis

    **Spring Boot 2 集成 Redis 知识点详解** Spring Boot 2 提供了对 Redis 的便捷集成,使得开发者能够快速地在 Spring 应用中利用 Redis 的高性能存储特性。以下将详细介绍如何在 Spring Boot 2 项目中集成 Redis,...

    Spring Redis缓存实例

    **Spring Redis 缓存实例详解** 在现代的Web应用程序开发中,缓存是提高系统性能的关键技术之一。Spring框架提供了一种优雅的方式来整合缓存管理,其中包括对Redis的支持。Redis是一个开源的、高性能的键值数据库,...

    Spring Boot整合redis

    **Spring Boot 整合 Redis 知识点详解** 在现代Web开发中,Spring Boot因其便捷的配置、快速的启动和强大的功能集而受到广泛的欢迎。其中,数据存储和缓存是系统性能优化的关键部分,而Redis作为一个高性能的键值...

    springmvc集成redis的Demo基于maven(内有redis)

    **Spring MVC 集成 Redis 知识点详解** 在当今的互联网开发中,缓存技术扮演着至关重要的角色,而 Redis 作为一款高效的内存数据结构存储系统,被广泛应用于缓存、消息队列等场景。Spring MVC 是一个成熟的、广泛...

    spring boot - redis-1

    **Spring Boot 集成 Redis 知识点详解** ...在"spring boot - redis-1"的示例代码中,开发者可能已经演示了这些基本操作,进一步了解和学习这个示例将有助于加深对Spring Boot与Redis集成的理解。

    Spring Boot Redis 实现分布式锁的方法详解.docx

    Spring Boot 提供了与 Redis 集成的便捷方式,使得开发者能够快速实现分布式锁功能。本篇文章将详细讲解如何利用 Spring Boot 结合 Redis 实现分布式锁。 首先,理解分布式锁的基本概念。分布式锁是在分布式系统中...

Global site tag (gtag.js) - Google Analytics