Spring-RedisTemplate原理
admin
2023-08-01 03:20:17
0


    无论是mysql数据库、redis数据库、activeMq,我们都需要创建客户端连接、根据业务逻辑进行增删改查、关闭客户端连接等操作。在Spring中为例简化这一系列的操作。提供了模板类。

    将数据访问中的固定和变化部分分开,相同的数据访问流程固话到模板类中变化的部分通过回调接口开放出来,用于具体定义数据访问和结果返回的操作,同时保证模板类是线程安全的,以便多个数据访问线程共享同一个模板实例。

 


在S平日那个中有很多模板类,比如HibernateTemplate、JdbcTemplate、RedisTemplate等等。本文将以RedisTemplate、JdbcTemplate为例,讲解创建连接、执行操作、释放连接这一系列操作;

一、RedisTemplate

对于单个使用线程池的jedis操作步骤请看java操作redis的章节,对于spring整合redis也请看前面章节。本章主要讲解源码!

List list=new ArrayList();
list.add("value1");
list.add("value2");
ListOperations listOperations=redisTemplate.opsForList();
listOperations.rightPushAll("listCol", list);


上面的代码是一段向队列中添加List的操作。我们以此为例讲解:


1)首先涉及到的类有:

DefaultListOperation //主要用于封装对List的操作,主要是调用RedisTemplate中的execute方法

StringRedisSerializer //key的序列化和反序列化的工具类

JdkSerializationRedisSerializer //value的序列化和反序列化的工具类

RedisCallback //回调接口,具体定义数据访问和结果返回的操作

RedisTemplate //redis操作模板类,用于封装redis的操作数据流程

RedisConnectionUtils //用于管理redis客户端连接

TransactionSynchronizationManager //线程同步管理

JedisConnectionFactory //创建Jedis的工厂类

Jedis //redis的客户端连接对象

JedisConnection //用于封装真正的Jedis连接对象


2)分析上面代码的源码

redisTemplate.opsForList();//会创建DefaultListOperation 对象,该对象中封装了RedisTemplate。

listOperations.rightPushAll("listCol", list);//具体方法代码如下图

/*****
**DefaultListOperation类中主要的调用
***主要成员变量:RedisTemplate
******/
@Override
public Long rightPushAll(K key, Collection values) {

//序列化对象key、value
//调用RedisTemplate的keySerializer、valueSerializer的serialize()
final byte[] rawKey = rawKey(key);
final byte[][] rawValues = rawValues(values);

//调用RedisTemplate的方法execute,实现对Redis操作
return execute(new RedisCallback(){ 

    //实现回调接口
    public Long doInRedis(RedisConnection connection) {
        return connection.rPush(rawKey, rawValues);
    }
  }, true); //参数exposeConnection(公开连接):true
}


@SuppressWarnings("unchecked")
byte[] rawKey(Object key) {
    Assert.notNull(key, "non null key required");
    if (keySerializer() == null && key instanceof byte[]) {
        return (byte[]) key;
    }
    //实际调用RedisTemplate来序列化key
    return keySerializer().serialize(key);
}

//调用RedisTemplate的方法
RedisSerializer keySerializer() {
    return template.getKeySerializer();
}

//调用RedisTemplate的方法
 T execute(RedisCallback callback, boolean b) {
    return template.execute(callback, b);
}


/*****
**RedisTemplate类中主要的调用
***主要成员变量:JedisConnectionFactory
******/
public  T execute(RedisCallback action, boolean exposeConnection, boolean pipeline) {

    //redis连接工厂,用于创建、关闭redis连接
    RedisConnectionFactory factory = getConnectionFactory();
   
    //内部封装真正的redis连接,用于实现各种操作
    RedisConnection conn = null;
    
    try {
    
        //默认不启动事务,redis连接是通过RedisConnectionUtils获得的
        if (enableTransactionSupport) {
            // only bind resources in case of potential transaction synchronization
            conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
        } else {
            conn = RedisConnectionUtils.getConnection(factory);
        }
        
        //是否和当事务同步管理器程绑定
        boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
        //
        RedisConnection connToUse = preProcessConnection(conn, existingConnection);
        
        //管道状态:用于批量操作
        boolean pipelineStatus = connToUse.isPipelined();
        if (pipeline && !pipelineStatus) {
            connToUse.openPipeline();
        }
        
        //是否为jedisConnection,创建动态代理对象(jdk动态代理技术)
        RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
       
        //调用回调函数,执行数据库操作,之部分是动态的,可以由用户自己指定操作
        T result = action.doInRedis(connToExpose);
        
        // close pipeline
        if (pipeline && !pipelineStatus) {
            connToUse.closePipeline();
        }
        
        // TODO: any other connection processing?
        return postProce***esult(result, connToUse, existingConnection);
    
    } finally {
    
        //非事务操作,释放连接
        if (!enableTransactionSupport) {
            RedisConnectionUtils.releaseConnection(conn, factory);
        }
    }
}


上一篇:OPC UA Server demo

下一篇:开启ssh服务

相关内容

热门资讯

韩国股市,正走向现实版“鱿鱼游... (文/观察者网 柳白)韩国股市,把韩国政府吓到了。就在韩国综合股价指数(KOSPI)年内第六次触发熔...
伊朗首次公开哈梅内伊官邸遇袭后... 7月8日,伊朗最高领袖的网站发布了一段视频,首次展示已故最高领袖阿里·哈梅内伊官邸被美以袭击后的画面...
特朗普威胁发动新的袭击后,伊朗... 7月8日,美国总统特朗普威胁要对伊朗发动新的袭击后,伊朗副外长卡齐姆·加里巴巴迪怒斥特朗普是“凶残的...
美中央司令部:超20艘美军舰艇... 当地时间7月8日,美军中央司令部在社交媒体发文称,目前有20多艘美国海军军舰正在中东各水域巡逻。美军...
伊朗称美军袭击造成8名军人死亡 总台记者8日自伊朗方面获悉,美军当天凌晨对伊朗南部部分地区发动袭击,造成伊朗军方8人死亡。据了解,死...
伊朗军方:若美国真的发动大规模... 美国对伊朗发动新一轮袭击,特朗普称美伊谅解备忘录失效,伊朗方面有何回应?凤凰卫视驻伊朗记者李睿从德黑...
河南社旗县近亿元高标准农田项目... 河南省社旗县地处南阳盆地东缘,有121万亩耕地,是全国产粮大县。2025年,这个常住人口约54万人口...
湖北鄂州一家3人被大风卷走身亡... 澎湃新闻记者 魏凡7月6日晚,湖北东部多地遭遇强对流天气袭击,部分乡镇出现龙卷风。鄂州名门世家小区6...
走访茉莉花都横州:大片花田浸泡... 受今年第10号台风“美莎克”持续影响,广西南宁横州市遭遇极端强降雨,境内多座水库出现漫顶及缺口情况、...
这场震惊世人的中国在德留学生性... “大多数人读起这个事情,他们会觉得这些人(加害者)一定是很可怕的人吧?但是其实不是,他们在生活中是非...