无论是mysql数据库、redis数据库、activeMq,我们都需要创建客户端连接、根据业务逻辑进行增删改查、关闭客户端连接等操作。在Spring中为例简化这一系列的操作。提供了模板类。
将数据访问中的固定和变化部分分开,将相同的数据访问流程固话到模板类中,变化的部分通过回调接口开放出来,用于具体定义数据访问和结果返回的操作,同时保证模板类是线程安全的,以便多个数据访问线程共享同一个模板实例。
在S平日那个中有很多模板类,比如HibernateTemplate、JdbcTemplate、RedisTemplate等等。本文将以RedisTemplate、JdbcTemplate为例,讲解创建连接、执行操作、释放连接这一系列操作;
一、RedisTemplate
对于单个使用线程池的jedis操作步骤请看java操作redis的章节,对于spring整合redis也请看前面章节。本章主要讲解源码!
List<String> list=new ArrayList<String>(); list.add("value1"); list.add("value2"); ListOperations<String, String> 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<V> values) { //序列化对象key、value //调用RedisTemplate的keySerializer、valueSerializer的serialize() final byte[] rawKey = rawKey(key); final byte[][] rawValues = rawValues(values); //调用RedisTemplate的方法execute,实现对Redis操作 return execute(new RedisCallback<Long>(){ //实现回调接口 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> T execute(RedisCallback<T> callback, boolean b) { return template.execute(callback, b); } /***** **RedisTemplate类中主要的调用 ***主要成员变量:JedisConnectionFactory ******/ public <T> T execute(RedisCallback<T> 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); } } }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。