Java 自定義緩存模板

在日常開發中,我們會用到進程內緩存(Map)和分佈式緩存(Redis),緩存能夠很大程度降低數據庫的壓力.但是在日常開發中,每個人都寫自己的緩存,沒有統一的標準.導致整個項目內部全是單個成員自定義的緩存.所以需要在程序內部定義一套緩存模板規範化使用緩存.
緩存模板開發思路:

  • 緩存我們常用的操作就和數據庫操作一樣,包括 增刪改查,所以這裏定義緩存的api參考數據庫的acid操作,但是緩存操作需要加鎖,不然會讀到髒數據.所以這裏我們使用讀寫鎖來做一致性操作處理.
  • 緩存管理器,在整個服務中緩存管理器是一個唯一的.就像Redis的StringTemplate一樣.所以緩存管理器需要寫成雙重加鎖單例類.
  • 緩存主鍵,自定義緩存主鍵常量,緩存的唯一性標識

代碼實現

  • Cache類,緩存模板
/**
 * @author caishen
 * @version 1.0
 * @className Cache
 * @date 2019/10/26 1:58
 * 自分で書いたコードの各行を擔當する
 * 緩存模板
 **/
public abstract class Cache<K,V> {
    final Map<K, V> m = new HashMap<>();

    final ReadWriteLock rwl = new ReentrantReadWriteLock();
    final Lock r = rwl.readLock();
    final Lock w = rwl.writeLock();
    /**
     * get key
     * @param key
     * @return
     */
    public V get(K key) {
        r.lock();
        try {
            return m.get(key);
        } finally {
            r.unlock();
        }
    }

    /**
     * 獲取當前緩存下面所有的key
     * @return
     */
    public Set<K> keys(){
        return m.keySet();
    }


    /**
     * 返回當前緩存下面的entrySet
     * @return
     */
    public Set<Map.Entry<K,V>> getEntrySet(){
        r.lock();
        try{
            return m.entrySet();
        } finally {
            r.unlock();
        }
    }
    /**
     * put key
     * @param key
     * @param value
     * @return
     */
    public V put(K key, V value) {
        w.lock();
        try {
            return m.put(key, value);
        } finally {
            w.unlock();
        }
    }
    /**
     * remove key
     * @param key
     * @return
     */
    public V remove(K key) {
        w.lock();
        try {
            return m.remove(key);
        } finally {
            w.unlock();
        }
    }
    /**
     * 模板方法,調用子類實現的init方法
     */
    void _init() {
        w.lock();
        try {
            init();
        } finally {
            w.unlock();
        }
    }
    /**
     * 緩存初始化,子類實現
     */
    protected abstract void init();
}
  • CacheManager 緩存管理器
/**
 * @author caishen
 * @version 1.0
 * @className CacheManager
 * @date 2019/10/26 2:00
 * 自分で書いたコードの各行を擔當する
 * 緩存管理類
 **/
public class CacheManager<K,V> {

    private final Map<String,Cache<K,V>> cacheMap = new ConcurrentHashMap<>();

    private CacheManager(){}

    public static volatile CacheManager cacheManager;

    /**
     * 單例模式 雙重加鎖
     * @return
     */
    public static CacheManager getInstance() {
        if (null == cacheManager) {
            synchronized (CacheManager.class) {
                if (null == cacheManager) {
                    cacheManager = new CacheManager();
                }
            }
        }
        return cacheManager;
    }

    /**
     * 判斷該key的緩存是否存在
     * @param cacheKey
     * @return
     */
    public Boolean containsCacheKey(String cacheKey){
        return cacheMap.containsKey(cacheKey);
    }

    /**
     * 註冊緩存
     * @param cacheKey 緩存key
     * @param cache
     */
    public void registerCache(String cacheKey, Cache<K, V> cache) {
        cache._init();
        cacheMap.put(cacheKey, cache);
    }

    /**
     * 從指定緩存中獲取數據
     * @param cacheKey 緩存Key
     * @param key
     * @return
     */
    public V getValue(String cacheKey, K key) {
        Cache<K, V> cache = cacheMap.get(cacheKey);
        if(!Assert.isNull(cache)) {
            return cache.get(key);
        }
        return null;
    }

    /**
     * 獲取指定的緩存
     * @param cacheKey
     * @return
     */
    public Cache<K,V> getCache(String cacheKey){
        return cacheMap.get(cacheKey);
    }


    /**
     * 設置緩存
     * @param cacheKey 緩存Key
     * @param key
     * @param value
     */
    public void put(String cacheKey, K key, V value) {
        Cache<K, V> cache = cacheMap.get(cacheKey);
        if(!Assert.isNull(cache)){
            cache.put(key, value);
        }
    }

    /**
     * 設置緩存 並返回修改值
     * @param cacheKey 緩存Key
     * @param key
     * @param value
     */
    public V putAndSet(String cacheKey, K key, V value) {
        Cache<K, V> cache = cacheMap.get(cacheKey);
        if(!Assert.isNull(cache)) {
            cache.put(key, value);
        }
        return value;
    }

    /**
     * 從指定緩存中刪除數據
     * @param cacheKey 緩存Key
     * @param key
     */
    public V remove(String cacheKey, K key) {
        Cache<K, V> cache = cacheMap.get(cacheKey);
        if(!Assert.isNull(cache)) {
            return cache.remove(key);
        }
        return null;
    }
}
  • 調用示例
/**
 * @author caishen
 * @version 1.0
 * @className TestCache
 * @date 2019/12/19 11:53
 * 自分で書いたコードの各行を擔當する
 **/
public class TestCache extends Cache {

    @Override
    protected void init() {
        //do something
    }
    // 直接調用這個方法就註冊了
    public void register() {
        CacheManager.getInstance().registerCache("TEST_CACHE_KEY", this);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章