|
@@ -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());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|