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