From 89c1e4f91de2a527ec825c76b0de5dd2fd42cc59 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期六, 13 八月 2022 11:30:33 +0800
Subject: [PATCH] update 重写 spring-cache 实现 更人性化的操作 支持注解指定ttl等一些参数

---
 ruoyi-framework/src/main/java/com/ruoyi/framework/manager/PlusSpringCacheManager.java       |  191 +++++++++++++++++++++++++++++++
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java                   |   21 --
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java                |   19 +-
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RedissonProperties.java |   37 -----
 ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java                        |   23 +++
 ruoyi-admin/src/main/resources/application.yml                                              |   15 --
 6 files changed, 230 insertions(+), 76 deletions(-)

diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 4c54de5..aef309e 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -233,21 +233,6 @@
   # 绾跨▼姹犵淮鎶ょ嚎绋嬫墍鍏佽鐨勭┖闂叉椂闂�
   keepAliveSeconds: 300
 
---- # redisson 缂撳瓨閰嶇疆
-redisson:
-  cacheGroup:
-    # 鐢ㄤ緥: @Cacheable(cacheNames="groupId", key="#XXX") 鏂瑰彲浣跨敤缂撳瓨缁勯厤缃�
-    - groupId: redissonCacheMap
-      # 缁勮繃鏈熸椂闂�(鑴氭湰鐩戞帶)
-      ttl: 60000
-      # 缁勬渶澶х┖闂叉椂闂�(鑴氭湰鐩戞帶)
-      maxIdleTime: 60000
-      # 缁勬渶澶ч暱搴�
-      maxSize: 0
-    - groupId: testCache
-      ttl: 1000
-      maxIdleTime: 500
-
 --- # 鍒嗗竷寮忛攣 lock4j 鍏ㄥ眬閰嶇疆
 lock4j:
   # 鑾峰彇鍒嗗竷寮忛攣瓒呮椂鏃堕棿锛岄粯璁や负 3000 姣
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java
new file mode 100644
index 0000000..892de00
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheNames.java
@@ -0,0 +1,23 @@
+package com.ruoyi.common.constant;
+
+/**
+ * 缂撳瓨缁勫悕绉板父閲�
+ * <p>
+ * key 鏍煎紡涓� cacheNames#ttl#maxIdleTime#maxSize
+ * <p>
+ * ttl 杩囨湡鏃堕棿 濡傛灉璁剧疆涓�0鍒欎笉杩囨湡 榛樿涓�0
+ * maxIdleTime 鏈�澶х┖闂叉椂闂� 鏍规嵁LRU绠楁硶娓呯悊绌洪棽鏁版嵁 濡傛灉璁剧疆涓�0鍒欎笉妫�娴� 榛樿涓�0
+ * maxSize 缁勬渶澶ч暱搴� 鏍规嵁LRU绠楁硶娓呯悊婧㈠嚭鏁版嵁 濡傛灉璁剧疆涓�0鍒欐棤闄愰暱 榛樿涓�0
+ * <p>
+ * 渚嬪瓙: test#60s銆乼est#0#60s銆乼est#0#1m#1000銆乼est#1h#0#500
+ *
+ * @author Lion Li
+ */
+public interface CacheNames {
+
+    /**
+     * 婕旂ず妗堜緥
+     */
+    String DEMO_CACHE = "demo:cache#60s#10m#20";
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
index 2312aab..7342cba 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
@@ -1,5 +1,6 @@
 package com.ruoyi.demo.controller;
 
+import com.ruoyi.common.constant.CacheNames;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.utils.redis.RedisUtils;
 import lombok.RequiredArgsConstructor;
@@ -18,7 +19,7 @@
  * @author Lion Li
  */
 // 绫荤骇鍒� 缂撳瓨缁熶竴閰嶇疆
-//@CacheConfig(cacheNames = "redissonCacheMap")
+//@CacheConfig(cacheNames = CacheNames.DEMO_CACHE)
 @RequiredArgsConstructor
 @RestController
 @RequestMapping("/demo/cache")
@@ -36,9 +37,9 @@
      * 閲嶇偣璇存槑: 缂撳瓨娉ㄨВ涓ヨ皑涓庡叾浠栫瓫閫夋暟鎹姛鑳戒竴璧蜂娇鐢�
      * 渚嬪: 鏁版嵁鏉冮檺娉ㄨВ 浼氶�犳垚 缂撳瓨鍑荤┛ 涓� 鏁版嵁涓嶄竴鑷撮棶棰�
      * <p>
-     * cacheNames 涓洪厤缃枃浠跺唴 groupId
+     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
      */
-    @Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
+    @Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null")
     @GetMapping("/test1")
     public R<String> test1(String key, String value) {
         return R.ok("鎿嶄綔鎴愬姛", value);
@@ -48,11 +49,11 @@
      * 娴嬭瘯 @CachePut
      * <p>
      * 鍔犱簡@CachePut娉ㄨВ鐨勬柟娉�,浼氭妸鏂规硶鐨勮繑鍥炲�紁ut鍒扮紦瀛橀噷闈㈢紦瀛樿捣鏉�,渚涘叾瀹冨湴鏂逛娇鐢�
-     * 瀹冦�岄�氬父鐢ㄥ湪鏂板鏂规硶涓娿��
+     * 瀹冦�岄�氬父鐢ㄥ湪鏂板鎴栬�呭疄鏃舵洿鏂版柟娉曚笂銆�
      * <p>
-     * cacheNames 涓� 閰嶇疆鏂囦欢鍐� groupId
+     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
      */
-    @CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
+    @CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
     @GetMapping("/test2")
     public R<String> test2(String key, String value) {
         return R.ok("鎿嶄綔鎴愬姛", value);
@@ -62,11 +63,11 @@
      * 娴嬭瘯 @CacheEvict
      * <p>
      * 浣跨敤浜咰acheEvict娉ㄨВ鐨勬柟娉�,浼氭竻绌烘寚瀹氱紦瀛�
-     * 銆屼竴鑸敤鍦ㄦ洿鏂版垨鑰呭垹闄ょ殑鏂规硶涓娿��
+     * 銆屼竴鑸敤鍦ㄥ垹闄ょ殑鏂规硶涓娿��
      * <p>
-     * cacheNames 涓� 閰嶇疆鏂囦欢鍐� groupId
+     * cacheNames 鍛藉悕瑙勫垯 鏌ョ湅 {@link CacheNames} 娉ㄩ噴 鏀寔澶氬弬鏁�
      */
-    @CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
+    @CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
     @GetMapping("/test3")
     public R<String> test3(String key, String value) {
         return R.ok("鎿嶄綔鎴愬姛", value);
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java
index c869528..9a7938a 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java
@@ -4,11 +4,9 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.ruoyi.framework.config.properties.RedissonProperties;
 import com.ruoyi.framework.handler.KeyPrefixHandler;
+import com.ruoyi.framework.manager.PlusSpringCacheManager;
 import lombok.extern.slf4j.Slf4j;
-import org.redisson.api.RedissonClient;
 import org.redisson.codec.JsonJacksonCodec;
-import org.redisson.spring.cache.CacheConfig;
-import org.redisson.spring.cache.RedissonSpringCacheManager;
 import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -17,10 +15,6 @@
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 /**
  * redis閰嶇疆
@@ -80,18 +74,11 @@
     }
 
     /**
-     * 鏁村悎spring-cache
+     * 鑷畾涔夌紦瀛樼鐞嗗櫒 鏁村悎spring-cache
      */
     @Bean
-    public CacheManager cacheManager(RedissonClient redissonClient) {
-        List<RedissonProperties.CacheGroup> cacheGroup = redissonProperties.getCacheGroup();
-        Map<String, CacheConfig> config = new HashMap<>();
-        for (RedissonProperties.CacheGroup group : cacheGroup) {
-            CacheConfig cacheConfig = new CacheConfig(group.getTtl(), group.getMaxIdleTime());
-            cacheConfig.setMaxSize(group.getMaxSize());
-            config.put(group.getGroupId(), cacheConfig);
-        }
-        return new RedissonSpringCacheManager(redissonClient, config, new JsonJacksonCodec(objectMapper));
+    public CacheManager cacheManager() {
+        return new PlusSpringCacheManager();
     }
 
     /**
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RedissonProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RedissonProperties.java
index eab746c..b0bf285 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RedissonProperties.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/RedissonProperties.java
@@ -7,8 +7,6 @@
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-
 /**
  * Redisson 閰嶇疆灞炴��
  *
@@ -18,12 +16,12 @@
 @Component
 @ConfigurationProperties(prefix = "redisson")
 public class RedissonProperties {
-    
+
     /**
      * redis缂撳瓨key鍓嶇紑
      */
     private String keyPrefix;
-    
+
     /**
      * 绾跨▼姹犳暟閲�,榛樿鍊� = 褰撳墠澶勭悊鏍告暟閲� * 2
      */
@@ -43,11 +41,6 @@
      * 闆嗙兢鏈嶅姟閰嶇疆
      */
     private ClusterServersConfig clusterServersConfig;
-
-    /**
-     * 缂撳瓨缁�
-     */
-    private List<CacheGroup> cacheGroup;
 
     @Data
     @NoArgsConstructor
@@ -138,32 +131,6 @@
          * 璁㈤槄妯″紡
          */
         private SubscriptionMode subscriptionMode;
-
-    }
-
-    @Data
-    @NoArgsConstructor
-    public static class CacheGroup {
-
-        /**
-         * 缁刬d
-         */
-        private String groupId;
-
-        /**
-         * 缁勮繃鏈熸椂闂�
-         */
-        private long ttl;
-
-        /**
-         * 缁勬渶澶х┖闂叉椂闂�
-         */
-        private long maxIdleTime;
-
-        /**
-         * 缁勬渶澶ч暱搴�
-         */
-        private int maxSize;
 
     }
 
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/PlusSpringCacheManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/PlusSpringCacheManager.java
new file mode 100644
index 0000000..d8bfce7
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/PlusSpringCacheManager.java
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2013-2021 Nikita Koksharov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ruoyi.framework.manager;
+
+import com.ruoyi.common.utils.redis.RedisUtils;
+import org.redisson.api.RMap;
+import org.redisson.api.RMapCache;
+import org.redisson.spring.cache.CacheConfig;
+import org.redisson.spring.cache.RedissonCache;
+import org.springframework.boot.convert.DurationStyle;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
+import org.springframework.util.StringUtils;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A {@link org.springframework.cache.CacheManager} implementation
+ * backed by Redisson instance.
+ * <p>
+ * 淇敼 RedissonSpringCacheManager 婧愮爜
+ * 閲嶅啓 cacheName 澶勭悊鏂规硶 鏀寔澶氬弬鏁�
+ *
+ * @author Nikita Koksharov
+ *
+ */
+@SuppressWarnings("unchecked")
+public class PlusSpringCacheManager implements CacheManager {
+
+    private boolean dynamic = true;
+
+    private boolean allowNullValues = true;
+
+    private boolean transactionAware = true;
+
+    Map<String, CacheConfig> configMap = new ConcurrentHashMap<>();
+    ConcurrentMap<String, Cache> instanceMap = new ConcurrentHashMap<>();
+
+    /**
+     * Creates CacheManager supplied by Redisson instance
+     */
+    public PlusSpringCacheManager() {
+    }
+
+
+    /**
+     * Defines possibility of storing {@code null} values.
+     * <p>
+     * Default is <code>true</code>
+     *
+     * @param allowNullValues stores if <code>true</code>
+     */
+    public void setAllowNullValues(boolean allowNullValues) {
+        this.allowNullValues = allowNullValues;
+    }
+
+    /**
+     * Defines if cache aware of Spring-managed transactions.
+     * If {@code true} put/evict operations are executed only for successful transaction in after-commit phase.
+     * <p>
+     * Default is <code>false</code>
+     *
+     * @param transactionAware cache is transaction aware if <code>true</code>
+     */
+    public void setTransactionAware(boolean transactionAware) {
+        this.transactionAware = transactionAware;
+    }
+
+    /**
+     * Defines 'fixed' cache names.
+     * A new cache instance will not be created in dynamic for non-defined names.
+     * <p>
+     * `null` parameter setups dynamic mode
+     *
+     * @param names of caches
+     */
+    public void setCacheNames(Collection<String> names) {
+        if (names != null) {
+            for (String name : names) {
+                getCache(name);
+            }
+            dynamic = false;
+        } else {
+            dynamic = true;
+        }
+    }
+
+    /**
+     * Set cache config mapped by cache name
+     *
+     * @param config object
+     */
+    public void setConfig(Map<String, ? extends CacheConfig> config) {
+        this.configMap = (Map<String, CacheConfig>) config;
+    }
+
+    protected CacheConfig createDefaultConfig() {
+        return new CacheConfig();
+    }
+
+    @Override
+    public Cache getCache(String name) {
+        Cache cache = instanceMap.get(name);
+        if (cache != null) {
+            return cache;
+        }
+        if (!dynamic) {
+            return cache;
+        }
+
+        CacheConfig config = configMap.get(name);
+        if (config == null) {
+            config = createDefaultConfig();
+            configMap.put(name, config);
+        }
+
+        // 閲嶅啓 cacheName 鏀寔澶氬弬鏁�
+        String[] array = StringUtils.delimitedListToStringArray(name, "#");
+        name = array[0];
+        if (array.length > 1) {
+            config.setTTL(DurationStyle.detectAndParse(array[1]).toMillis());
+        }
+        if (array.length > 2) {
+            config.setMaxIdleTime(DurationStyle.detectAndParse(array[2]).toMillis());
+        }
+        if (array.length > 3) {
+            config.setMaxSize(Integer.parseInt(array[3]));
+        }
+
+        if (config.getMaxIdleTime() == 0 && config.getTTL() == 0 && config.getMaxSize() == 0) {
+            return createMap(name, config);
+        }
+
+        return createMapCache(name, config);
+    }
+
+    private Cache createMap(String name, CacheConfig config) {
+        RMap<Object, Object> map = RedisUtils.getClient().getMap(name);
+
+        Cache cache = new RedissonCache(map, allowNullValues);
+        if (transactionAware) {
+            cache = new TransactionAwareCacheDecorator(cache);
+        }
+        Cache oldCache = instanceMap.putIfAbsent(name, cache);
+        if (oldCache != null) {
+            cache = oldCache;
+        }
+        return cache;
+    }
+
+    private Cache createMapCache(String name, CacheConfig config) {
+        RMapCache<Object, Object> map = RedisUtils.getClient().getMapCache(name);
+
+        Cache cache = new RedissonCache(map, config, allowNullValues);
+        if (transactionAware) {
+            cache = new TransactionAwareCacheDecorator(cache);
+        }
+        Cache oldCache = instanceMap.putIfAbsent(name, cache);
+        if (oldCache != null) {
+            cache = oldCache;
+        } else {
+            map.setMaxSize(config.getMaxSize());
+        }
+        return cache;
+    }
+
+    @Override
+    public Collection<String> getCacheNames() {
+        return Collections.unmodifiableSet(configMap.keySet());
+    }
+
+
+}

--
Gitblit v1.9.3