Javaカスタムキャッシュテンプレート

25267 ワード

日常的な開発では、プロセス内キャッシュ(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);
        }
    }