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);
    }
}

你可能感兴趣的:(缓存)