Spring Data Redis 項目源碼框架分析
redis是由Salvatore Sanfilippo用C語言編寫的一個緩存系統,與memcached相比,提供了更多的處理復雜數據結構的方法;性能也非常的突出。
由于項目需要,自己簡單地看了下spring新加入的模塊 spring data redis,spring data redis對jedis, jredis, rjc等redis的java客戶端接口進行了進一部的抽象,類似于jdbcTemplate的實現。具體spring配置方式如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"/> <!-- Configurer that replaces ${...} placeholders with values from a properties file --> <context:property-placeholder location="classpath:redis.properties"/> <context:annotation-config /> <context:component-scan base-package="org.springframework.data.redis.samples"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="connectionFactory"/>
</beans></pre>
connectionFactory功能類似于spring 數據庫連接的datasource,提供對遠程redis server的連接訪問; redisTemplate類似于SqlMapClientTemplate,提供對數據庫訪問的模板方法。
下面是spring data redis class diagram
結合下面的代碼我們進行分析:public class Example{ @autowired private RedisTemplate<String,String> template;public void addLink(String userId, URL url){ template.opsForList.leftPush(userId, url.toExternalForm); }
}</pre> spring data redis根據數據的類型進行了接口方法的拆分,如 ValueOperations,ListOperations,SetOperations,ZSetOperations。template調用 opsForList拿到具體的對哪種數據結構進行操作的對象,進而調用相應的操作方法。DefaultListOperations等對象使用回調函數的方法向redis server進行請求。
public Long leftPush(K key, V value) { final byte[] rawKey = rawKey(key); final byte[] rawValue = rawValue(value); return execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection) { return connection.lPush(rawKey, rawValue); } }, true); }</pre> 在RedisTemplate中,有一個重要的方法execute對connection進行預處理,包括是否使用pipeline,是否expose(暴露)connection等,對server進行請求后的返回結果進行后續的處理等。
/*** Executes the given action object within a connection that can be exposed or not. Additionally, the connection * can be pipelined. Note the results of the pipeline are discarded (making it suitable for write-only scenarios). * * @param <T> return type * @param action callback object to execute * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code * @param pipeline whether to pipeline or not the connection for the execution * @return object returned by the action */ public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { Assert.notNull(action, "Callback object must not be null"); RedisConnectionFactory factory = getConnectionFactory(); //由spring中配置的JedisConnectionFactory創建連接 RedisConnection conn = RedisConnectionUtils.getConnection(factory); boolean existingConnection = TransactionSynchronizationManager.hasResource(factory); preProcessConnection(conn, existingConnection); boolean pipelineStatus = conn.isPipelined();//判斷是否打開pipeline if (pipeline && !pipelineStatus) { conn.openPipeline(); } try { RedisConnection connToExpose = (exposeConnection ? conn : createRedisConnectionProxy(conn)); T result = action.doInRedis(connToExpose); // TODO: any other connection processing? // 對后續結果進行處理,但postProcessResult還是直接返回result的,不知為何? return postProcessResult(result, conn, existingConnection); } finally { try { if (pipeline && !pipelineStatus) { conn.closePipeline(); } } finally { RedisConnectionUtils.releaseConnection(conn, factory); } } }</pre>
本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!