spring data redis源码框架分析

    redis是由Salvatore Sanfilippo用C语言编写的一个缓存系统,与memcached相比,提供了更多的处理复杂数据结构的方法;性能也非常的突出。

  由于项目需要,自己简单地看了下spring新加入的模块spring data redis,spring data redis对jedis, jredis, rjc等redis的java客户端接口进行了进一部的抽象,类似于jdbcTemplate的实现。具体spring配置方式如下:

 

  
  
  
  
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  3.         xmlns:p="http://www.springframework.org/schema/p" 
  4.         xmlns:context="http://www.springframework.org/schema/context"  
  5.         xsi:schemaLocation=" 
  6.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
  7.             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
  8.  
  9.     <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
  10.         p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"/> 
  11.     <!-- Configurer that replaces ${...} placeholders with values from a properties file --> 
  12.     <context:property-placeholder location="classpath:redis.properties"/> 
  13.      
  14.     <context:annotation-config /> 
  15.  
  16.     <context:component-scan base-package="org.springframework.data.redis.samples"/> 
  17.  
  18.     <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"  
  19.         p:connection-factory-ref="connectionFactory"/> 
  20.      
  21. </beans> 

 

 connectionFactory功能类似于spring 数据库连接的datasource,提供对远程redis server的连接访问;  redisTemplate类似于SqlMapClientTemplate,提供对redis server访问的模板方法。 

下面是spring data redis class diagram :

 

 

结合下面的代码我们进行分析:

 

  
  
  
  
  1. public class Example{ 
  2.     @autowired 
  3.     private RedisTemplate<String,String> template; 
  4.      
  5.     public void addLink(String userId, URL url){ 
  6.         template.opsForList.leftPush(userId, url.toExternalForm); 
  7.     } 

 spring data redis根据数据的类型进行了接口方法的拆分,如ValueOperations,ListOperations,SetOperations,ZSetOperations。template调用opsForList拿到具体的对哪种数据结构进行操作的对象,进而调用相应的操作方法。DefaultListOperations等对象使用回调函数的方法向redis server进行请求。 

 

  
  
  
  
  1. public Long leftPush(K key, V value) { 
  2.     final byte[] rawKey = rawKey(key); 
  3.     final byte[] rawValue = rawValue(value); 
  4.     return execute(new RedisCallback<Long>() { 
  5.          
  6.         public Long doInRedis(RedisConnection connection) { 
  7.             return connection.lPush(rawKey, rawValue); 
  8.         } 
  9.     }, true); 

 在RedisTemplate中,有一个重要的方法execute对connection进行预处理,包括是否使用pipeline,是否expose(暴露)connection等,对server进行请求后的返回结果进行后续的处理等。 

 

  
  
  
  
  1. /** 
  2.  * Executes the given action object within a connection that can be exposed or not. Additionally, the connection 
  3.  * can be pipelined. Note the results of the pipeline are discarded (making it suitable for write-only scenarios). 
  4.  *  
  5.  * @param <T> return type 
  6.  * @param action callback object to execute 
  7.  * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code 
  8.  * @param pipeline whether to pipeline or not the connection for the execution  
  9.  * @return object returned by the action 
  10.  */ 
  11. public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { 
  12.     Assert.notNull(action, "Callback object must not be null"); 
  13.  
  14.     RedisConnectionFactory factory = getConnectionFactory(); 
  15.     //由spring中配置的JedisConnectionFactory创建连接  
  16.     RedisConnection conn = RedisConnectionUtils.getConnection(factory); 
  17.  
  18.     boolean existingConnection = TransactionSynchronizationManager.hasResource(factory); 
  19.     preProcessConnection(conn, existingConnection);//调用StringRedisTemplate的preProcessConnection方法 
  20.                                                                                              //拿到了DefaultStringRedisConnection 
  21.     boolean pipelineStatus = conn.isPipelined();//判断是否打开pipeline  
  22.     if (pipeline && !pipelineStatus) { 
  23.         conn.openPipeline(); 
  24.     } 
  25.  
  26.     try { 
  27.         RedisConnection connToExpose = (exposeConnection ? conn : createRedisConnectionProxy(conn)); 
  28.         T result = action.doInRedis(connToExpose); 
  29.         // TODO: any other connection processing? 
  30.         // 对后续结果进行处理,但postProcessResult还是直接返回result的,不知为何?  
  31.         return postProcessResult(result, conn, existingConnection); 
  32.     } finally { 
  33.         try { 
  34.             if (pipeline && !pipelineStatus) { 
  35.                 conn.closePipeline(); 
  36.             } 
  37.         } finally { 
  38.             RedisConnectionUtils.releaseConnection(conn, factory); 
  39.         } 
  40.     } 

 

你可能感兴趣的:(java,redis,redis,spring,NoSQL,Data,休闲)