RedisTemplate大量使用的callback機制

假如要讓你封裝jedis以便讓外界調用你大概率會像下面方法一樣實現。

@Service
public class JedisSpringDemo {
    @Resource(name = "shardedJedisPool")
    private ShardedJedisPool shardedJedisPool;
    
    public String set(String key, String value){
        ShardedJedis shardedJedis = null;
        try{
            // 從連接池中獲取jedis分片對象
            shardedJedis = shardedJedisPool.getResource();
            // 設置值到redis中
            return shardedJedis.set(key, value);
        }catch (Exception e){
            System.out.println(e.getMessage());
        }finally {
            if(null != shardedJedis){
                shardedJedis.close();
            }
        }
        return null;
    }

    public String get(String key){
        ShardedJedis shardedJedis = null;
        try{
            // 從連接池中獲取jedis分片對象
            shardedJedis = shardedJedisPool.getResource();
            // 從redis中獲取key對應value
            return shardedJedis.get(key);
        }catch (Exception e){
            System.out.println(e.getMessage());
        }finally {
            if(null != shardedJedis){
                shardedJedis.close();
            }
        }
        return null;
    }
}

上面的這段代碼違反了DRY原則,兩個方法get()和set()大部分代碼是相同的(try,catch,finally這部分代碼),唯一不同的就是我們return的那一行具體的調用方法,如果像這種方法很多的話(jedis提供了幾十種類似的方法),我們的代碼重復率是很高的,代碼重復率一旦高起來,相應的維護成本也會提高,下面我們就來引進一種改進方法--回調機制。

首先,我們創建一個接口類,該接口定義Jedis的操作,代碼如下:

public interface RedisOperations {
    <T> T execute(ConnectionCallback<T> action);
   String set(final String key, final String value);
   String get(final String key);
}

其次,定義連接Redis服務器的回調接口,代碼如下:

public interface ConnectionCallback<T> {
    T doInRedis(ShardedJedis shardedJedis);
}

最后定義具體的操作服務類,代碼如下:

@Service("redisTemplate")
public class RedisTemplate implements RedisOperations{
    @Resource(name = "shardedJedisPool")
    private ShardedJedisPool shardedJedisPool;
    
    @Override
    public <T> T execute(ConnectionCallback<T> action) {
        ShardedJedis shardedJedis = null;
        try{
            // 從連接池中獲取jedis分片對象
            shardedJedis = shardedJedisPool.getResource();
            
            return action.doInRedis(shardedJedis);
            
        }catch (Exception e){
            System.out.println(e.getMessage());
        }finally {
            if(null != shardedJedis){
                shardedJedis.close();
            }
        }
        return null;
    }
    
   /**
     * attention:真正封裝的方法,非常的簡潔干脆
     */
    public String set(final String key, final String value){
        return execute(new ConnectionCallback<String>() {
            @Override
            public String doInRedis(
                    ShardedJedis shardedJedis) {
                return shardedJedis.set(key, value);
            }
        });
    }
    
    public String get(final String key){
        return execute(new ConnectionCallback<String>(){
            @Override
            public String doInRedis(ShardedJedis shardedJedis) {
                return shardedJedis.get(key);
            }
        });
    }
}

通過上面的代碼,我們可以清晰的看到,將try,catch,finally部分的公共代碼都封裝到了execute()函數中,在具體方法內實現回調方法的具體業務邏輯即可,代碼的復用率更高了。
如果大家對spring jdbc或者是spring data redis的源碼研究過,就應該知道JdbcTemplate和RedisTemplate這兩個類,這兩個框架中用到了大量的callback機制。
一言以蔽之--如果你調用我,那么我就回調你傳給我的對象的方法。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Java客戶端Jedis Java有很多優秀的Redis客戶端(詳見:http://redis.io/client...
    linuxzw閱讀 1,534評論 1 5
  • NOSQL類型簡介鍵值對:會使用到一個哈希表,表中有一個特定的鍵和一個指針指向特定的數據,如redis,volde...
    MicoCube閱讀 4,056評論 2 27
  • 原文地址:http://es6.ruanyifeng.com/#docs/promise Promise 的含義 ...
    AI云棧閱讀 896評論 0 7
  • 2019.1.7 見 今天打掃了家里的衛生,第一次嘗試做了水餃,從切菜,到調味,再到包餃子,味道還挺好吃的。鍛煉身...
    妍靜的時光紀閱讀 147評論 0 1
  • 我立志從自然型父母到有效型父母的蛻變 ——讀《愛是一次共同的成長》有感2 參加家庭教育學習?幾年的時間,我...
    快樂天使_快樂飛翔閱讀 77評論 0 0