diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java
index d57ba4e65..41a2bdc17 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java
@@ -4,6 +4,7 @@ import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.dromara.common.redis.manager.PlusSpringCacheManager;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
@@ -38,6 +39,7 @@ public class CacheConfig {
* 自定义缓存管理器 整合spring-cache
*/
@Bean
+ @ConditionalOnMissingBean(CacheManager.class)
public CacheManager cacheManager() {
return new PlusSpringCacheManager();
}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/AbstractPlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/AbstractPlusSpringCacheManager.java
new file mode 100644
index 000000000..57a89dedc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/AbstractPlusSpringCacheManager.java
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2024-2024 supreme
+ *
+ * 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 org.dromara.common.redis.manager;
+
+import org.dromara.common.redis.utils.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 CacheManager} implementation
+ * backed by Redisson instance.
+ *
+ * 修改 RedissonSpringCacheManager 源码
+ * 重写 cacheName 处理方法 支持多参数
+ *
+ * @author Nikita Koksharov
+ *
+ */
+@SuppressWarnings("unchecked")
+public abstract class AbstractPlusSpringCacheManager implements CacheManager {
+
+ private boolean dynamic = true;
+
+ private boolean allowNullValues = true;
+
+ private boolean transactionAware = true;
+
+ Map configMap = new ConcurrentHashMap<>();
+ ConcurrentMap instanceMap = new ConcurrentHashMap<>();
+
+ /**
+ * Creates CacheManager supplied by Redisson instance
+ */
+ public AbstractPlusSpringCacheManager() {
+ }
+
+
+ /**
+ * Defines possibility of storing {@code null} values.
+ *
+ * Default is true
+ *
+ * @param allowNullValues stores if true
+ */
+ 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.
+ *
+ * Default is false
+ *
+ * @param transactionAware cache is transaction aware if true
+ */
+ 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.
+ *
+ * `null` parameter setups dynamic mode
+ *
+ * @param names of caches
+ */
+ public void setCacheNames(Collection 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 config) {
+ this.configMap = (Map) config;
+ }
+
+ protected CacheConfig createDefaultConfig() {
+ return new CacheConfig();
+ }
+
+ @Override
+ public Cache getCache(String name) {
+ name = getCacheNameWrapper(name);
+
+ // 重写 cacheName 支持多参数
+ String[] array = StringUtils.delimitedListToStringArray(name, "#");
+ name = array[0];
+
+ 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);
+ }
+
+ 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 map = RedisUtils.getClient().getMap(name);
+
+ Cache cache = getCaffeineCacheDecorator(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 map = RedisUtils.getClient().getMapCache(name);
+
+ Cache cache = getCaffeineCacheDecorator(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 getCacheNames() {
+ return Collections.unmodifiableSet(configMap.keySet());
+ }
+
+
+ /**
+ * 获取缓存名称包装
+ *
+ * @param cacheName 缓存名称
+ * @return {@link String }
+ */
+ public abstract String getCacheNameWrapper(String cacheName);
+
+ /**
+ * 获取Caffeine缓存装饰器
+ *
+ * @param cache 缓存
+ * @return {@link Cache }
+ */
+ public abstract Cache getCaffeineCacheDecorator(Cache cache);
+}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java
index ee1d405f2..d72954cd8 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java
@@ -32,7 +32,7 @@ public class CaffeineCacheDecorator implements Cache {
}
public String getUniqueKey(Object key) {
- return cache.getName() + ":" + key;
+ return getName() + ":" + key;
}
@Override
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java
index a48cb1422..cb4dc4f3e 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2013-2021 Nikita Koksharov
+ * Copyright (c) 2024-2024 supreme
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,178 +15,26 @@
*/
package org.dromara.common.redis.manager;
-import org.dromara.common.redis.utils.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
+ * A {@link org.dromara.common.redis.manager.AbstractPlusSpringCacheManager} extends
* backed by Redisson instance.
*
- * 修改 RedissonSpringCacheManager 源码
- * 重写 cacheName 处理方法 支持多参数
- *
- * @author Nikita Koksharov
+ * 重写 cacheName 处理方法
+ * 重写 获取Caffeine缓存装饰器
*
+ * @author supreme
*/
-@SuppressWarnings("unchecked")
-public class PlusSpringCacheManager implements CacheManager {
+public class PlusSpringCacheManager extends AbstractPlusSpringCacheManager {
- private boolean dynamic = true;
-
- private boolean allowNullValues = true;
-
- private boolean transactionAware = true;
-
- Map configMap = new ConcurrentHashMap<>();
- ConcurrentMap instanceMap = new ConcurrentHashMap<>();
-
- /**
- * Creates CacheManager supplied by Redisson instance
- */
- public PlusSpringCacheManager() {
- }
-
-
- /**
- * Defines possibility of storing {@code null} values.
- *
- * Default is true
- *
- * @param allowNullValues stores if true
- */
- 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.
- *
- * Default is false
- *
- * @param transactionAware cache is transaction aware if true
- */
- 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.
- *
- * `null` parameter setups dynamic mode
- *
- * @param names of caches
- */
- public void setCacheNames(Collection 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 config) {
- this.configMap = (Map) config;
- }
-
- protected CacheConfig createDefaultConfig() {
- return new CacheConfig();
+ @Override
+ public String getCacheNameWrapper(String cacheName) {
+ return cacheName;
}
@Override
- public Cache getCache(String name) {
- // 重写 cacheName 支持多参数
- String[] array = StringUtils.delimitedListToStringArray(name, "#");
- name = array[0];
-
- 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);
- }
-
- 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);
+ public Cache getCaffeineCacheDecorator(Cache cache) {
+ return new CaffeineCacheDecorator(cache);
}
-
- private Cache createMap(String name, CacheConfig config) {
- RMap map = RedisUtils.getClient().getMap(name);
-
- Cache cache = new CaffeineCacheDecorator(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 map = RedisUtils.getClient().getMapCache(name);
-
- Cache cache = new CaffeineCacheDecorator(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 getCacheNames() {
- return Collections.unmodifiableSet(configMap.keySet());
- }
-
-
}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
index 07302bc81..923e4d96c 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
@@ -71,7 +71,6 @@ public class TenantConfig {
/**
* 多租户缓存管理器
*/
- @Primary
@Bean
public CacheManager tenantCacheManager() {
return new TenantSpringCacheManager();
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantCaffeineCacheDecorator.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantCaffeineCacheDecorator.java
new file mode 100644
index 000000000..9898c876d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantCaffeineCacheDecorator.java
@@ -0,0 +1,34 @@
+package org.dromara.common.tenant.manager;
+
+import cn.hutool.core.text.StrPool;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.manager.CaffeineCacheDecorator;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.springframework.cache.Cache;
+
+/**
+ * 重写 CaffeineCacheDecorator Name处理方法 支持多租户
+ *
+ * @author Supreme
+ * @since 2024/07/25
+ */
+public class TenantCaffeineCacheDecorator extends CaffeineCacheDecorator {
+ public TenantCaffeineCacheDecorator(Cache cache) {
+ super(cache);
+ }
+
+ @Override
+ public String getName() {
+ String cacheName = super.getName();
+ if (StringUtils.contains(cacheName, GlobalConstants.GLOBAL_REDIS_KEY)) {
+ return cacheName;
+ }
+ String tenantId = TenantHelper.getTenantId();
+ if (StringUtils.startsWith(cacheName, tenantId)) {
+ // 如果存在则直接返回
+ return cacheName;
+ }
+ return tenantId + StrPool.COLON + cacheName;
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java
index d230afc1a..9d837b5e6 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java
@@ -1,32 +1,40 @@
package org.dromara.common.tenant.manager;
+import cn.hutool.core.text.StrPool;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.redis.manager.PlusSpringCacheManager;
+import org.dromara.common.redis.manager.AbstractPlusSpringCacheManager;
import org.dromara.common.tenant.helper.TenantHelper;
import org.springframework.cache.Cache;
/**
* 重写 cacheName 处理方法 支持多租户
+ * 重写 CaffeineCacheDecorator 获取方法 支持多租户
*
- * @author Lion Li
+ * @author Supreme
+ * @since 2024/07/25
*/
-public class TenantSpringCacheManager extends PlusSpringCacheManager {
+public class TenantSpringCacheManager extends AbstractPlusSpringCacheManager {
public TenantSpringCacheManager() {
}
+
@Override
- public Cache getCache(String name) {
- if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
- return super.getCache(name);
+ public String getCacheNameWrapper(String cacheName) {
+ if (StringUtils.contains(cacheName, GlobalConstants.GLOBAL_REDIS_KEY)) {
+ return cacheName;
}
String tenantId = TenantHelper.getTenantId();
- if (StringUtils.startsWith(name, tenantId)) {
+ if (StringUtils.startsWith(cacheName, tenantId)) {
// 如果存在则直接返回
- return super.getCache(name);
+ return cacheName;
}
- return super.getCache(tenantId + ":" + name);
+ return tenantId + StrPool.COLON + cacheName;
}
+ @Override
+ public Cache getCaffeineCacheDecorator(Cache cache) {
+ return new TenantCaffeineCacheDecorator(cache);
+ }
}