CacheManager
This commit is contained in:
@@ -45,8 +45,9 @@
|
||||
【节点全局唯一】 @since 2.8.0
|
||||
全局Serivce的缓存设置,没配置该节点将自动创建一个。
|
||||
enabled: 是否开启缓存功能。默认: true
|
||||
source: 远程CacheSource的资源名
|
||||
-->
|
||||
<caching enabled="true"/>
|
||||
<caching enabled="true" source="xxx"/>
|
||||
|
||||
<!--
|
||||
【节点全局唯一】
|
||||
|
||||
@@ -17,6 +17,7 @@ module org.redkale {
|
||||
exports org.redkale.asm;
|
||||
exports org.redkale.boot;
|
||||
exports org.redkale.boot.watch;
|
||||
exports org.redkale.caching;
|
||||
exports org.redkale.cluster;
|
||||
exports org.redkale.convert;
|
||||
exports org.redkale.convert.bson;
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* //TODO 待实现
|
||||
*
|
||||
* 标记在Service的缓存接口, 方法有以下限制: <br>
|
||||
* 1、方法返回类型不能是void
|
||||
* 1、方法返回类型不能是void/CompletableFuture<Void>
|
||||
* 2、方法必须是protected/public
|
||||
* 3、方法不能是final
|
||||
*
|
||||
|
||||
@@ -14,10 +14,15 @@ import java.lang.annotation.Target;
|
||||
* //TODO 待实现
|
||||
*
|
||||
* 标记在Service的锁接口, 方法有以下限制: <br>
|
||||
* 1、方法返回类型不能是void
|
||||
* 1、方法返回类型不能是void/CompletableFuture<Void>
|
||||
* 2、方法必须是protected/public
|
||||
* 3、方法不能是final
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
@Inherited
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
|
||||
35
src/main/java/org/redkale/caching/CacheConfig.java
Normal file
35
src/main/java/org/redkale/caching/CacheConfig.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.caching;
|
||||
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
|
||||
/**
|
||||
*
|
||||
* 缓存配置
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public class CacheConfig {
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return JsonConvert.root().convertTo(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.caching;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import org.redkale.source.CacheMemorySource;
|
||||
import org.redkale.source.CacheSource;
|
||||
|
||||
/**
|
||||
* //TODO 待实现
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class CacheFactory {
|
||||
|
||||
protected CacheSource localSource = new CacheMemorySource("caching");
|
||||
|
||||
protected CacheSource remoteSource;
|
||||
|
||||
protected CacheFactory(CacheSource remoteSource) {
|
||||
this.remoteSource = remoteSource;
|
||||
}
|
||||
|
||||
public static CacheFactory create(CacheSource remoteSource) {
|
||||
return new CacheFactory(remoteSource);
|
||||
}
|
||||
|
||||
protected long hdelLocal(String map, String key) {
|
||||
return localSource.hdel(map, key);
|
||||
}
|
||||
|
||||
protected <T> void hsetLocal(final String map, final String key, final Type type, final T value) {
|
||||
localSource.hset(map, key, type, value);
|
||||
}
|
||||
|
||||
protected <T> T hgetLocal(final String map, final String key, final Type type) {
|
||||
return localSource.hget(map, key, type);
|
||||
}
|
||||
}
|
||||
359
src/main/java/org/redkale/caching/CacheManager.java
Normal file
359
src/main/java/org/redkale/caching/CacheManager.java
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.caching;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.redkale.annotation.Nonnull;
|
||||
import org.redkale.annotation.Nullable;
|
||||
import org.redkale.source.CacheMemorySource;
|
||||
import org.redkale.source.CacheSource;
|
||||
import org.redkale.util.TypeToken;
|
||||
|
||||
/**
|
||||
* //TODO 待实现
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public class CacheManager {
|
||||
|
||||
//缓存配置项
|
||||
protected final CacheConfig config;
|
||||
|
||||
//数据类型与CacheValue泛型的对应关系
|
||||
private final ConcurrentHashMap<Type, Type> cacheValueTypes = new ConcurrentHashMap<>();
|
||||
|
||||
//本地缓存Source
|
||||
protected final CacheSource localSource = new CacheMemorySource("caching");
|
||||
|
||||
//远程缓存Source
|
||||
protected CacheSource remoteSource;
|
||||
|
||||
protected CacheManager(@Nonnull CacheConfig config, @Nullable CacheSource remoteSource) {
|
||||
this.config = Objects.requireNonNull(config);
|
||||
this.remoteSource = remoteSource;
|
||||
}
|
||||
|
||||
public static CacheManager create(@Nonnull CacheConfig config, @Nullable CacheSource remoteSource) {
|
||||
return new CacheManager(config, remoteSource);
|
||||
}
|
||||
|
||||
//-------------------------------------- 本地缓存 --------------------------------------
|
||||
/**
|
||||
* 本地获取缓存数据, 过期返回null
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
public <T> T localGet(final String map, final String key, final Type type) {
|
||||
return get(localSource, map, key, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地获取字符串缓存数据, 过期返回null
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
public final String localGetString(final String map, final String key) {
|
||||
return get(localSource, map, key, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地缓存数据
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
public <T> void localSet(final String map, final String key, final Type type, final T value, Duration expire) {
|
||||
set(localSource, map, key, type, value, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地缓存字符串数据
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
public void localSetString(final String map, final String key, final String value, Duration expire) {
|
||||
set(localSource, map, key, String.class, value, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地删除缓存数据
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 删除数量
|
||||
*/
|
||||
public long localDel(String map, String key) {
|
||||
return del(localSource, map, key);
|
||||
}
|
||||
|
||||
//-------------------------------------- 远程缓存 --------------------------------------
|
||||
/**
|
||||
* 远程获取缓存数据, 过期返回null
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
public <T> T remoteGet(final String map, final String key, final Type type) {
|
||||
return get(remoteSource, map, key, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程异步获取缓存数据, 过期返回null
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
public <T> CompletableFuture<T> remoteGetAsync(final String map, final String key, final Type type) {
|
||||
return getAsync(remoteSource, map, key, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程获取字符串缓存数据, 过期返回null
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
public final String remoteGetString(final String map, final String key) {
|
||||
return get(remoteSource, map, key, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程异步获取字符串缓存数据, 过期返回null
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
public final CompletableFuture<String> remoteGetStringAsync(final String map, final String key) {
|
||||
return getAsync(remoteSource, map, key, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程缓存数据
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
public <T> void remoteSet(final String map, final String key, final Type type, final T value, Duration expire) {
|
||||
set(remoteSource, map, key, type, value, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程异步缓存数据
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
public <T> CompletableFuture<Void> remoteSetAsync(final String map, final String key, final Type type, final T value, Duration expire) {
|
||||
return setAsync(remoteSource, map, key, type, value, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程缓存字符串数据
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
public void remoteSetString(final String map, final String key, final String value, Duration expire) {
|
||||
set(remoteSource, map, key, String.class, value, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程异步缓存字符串数据
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
public CompletableFuture<Void> remoteSetStringAsync(final String map, final String key, final String value, Duration expire) {
|
||||
return setAsync(remoteSource, map, key, String.class, value, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程删除缓存数据
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 删除数量
|
||||
*/
|
||||
public long remoteDel(String map, String key) {
|
||||
return del(remoteSource, map, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程异步删除缓存数据
|
||||
*
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 删除数量
|
||||
*/
|
||||
public CompletableFuture<Long> remoteDelAsync(String map, String key) {
|
||||
return delAsync(remoteSource, map, key);
|
||||
}
|
||||
|
||||
//-------------------------------------- 内部方法 --------------------------------------
|
||||
/**
|
||||
* 获取缓存数据, 过期返回null
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param source 缓存源
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
protected <T> T get(final CacheSource source, final String map, final String key, final Type type) {
|
||||
CacheValue<T> val = source.hget(map, key, loadCacheType(type));
|
||||
return val != null && !val.isExpired() ? val.getValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存数据, 过期返回null
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param source 缓存源
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
*
|
||||
* @return 数据值
|
||||
*/
|
||||
protected <T> CompletableFuture<T> getAsync(final CacheSource source, final String map, final String key, final Type type) {
|
||||
return source.hgetAsync(map, key, loadCacheType(type)).thenApply(v -> {
|
||||
CacheValue<T> val = (CacheValue) v;
|
||||
return val != null && !val.isExpired() ? (T) val.getValue() : null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存数据
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param source 缓存源
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
protected <T> void set(final CacheSource source, final String map, final String key, final Type type, final T value, Duration expire) {
|
||||
Type t = loadCacheType(type, value);
|
||||
source.hset(map, key, t, CacheValue.create(value, expire));
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存数据
|
||||
*
|
||||
* @param <T> 泛型
|
||||
* @param source 缓存源
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
* @param type 数据类型
|
||||
* @param value 数据值
|
||||
* @param expire 过期时长,为null表示永不过期
|
||||
*/
|
||||
protected <T> CompletableFuture<Void> setAsync(final CacheSource source, final String map, final String key, final Type type, final T value, Duration expire) {
|
||||
Type t = loadCacheType(type, value);
|
||||
return source.hsetAsync(map, key, t, CacheValue.create(value, expire));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存数据
|
||||
*
|
||||
* @param source 缓存源
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 删除数量
|
||||
*/
|
||||
protected long del(final CacheSource source, String map, String key) {
|
||||
return source.hdel(map, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存数据
|
||||
*
|
||||
* @param source 缓存源
|
||||
* @param map 缓存hash
|
||||
* @param key 缓存键
|
||||
*
|
||||
* @return 删除数量
|
||||
*/
|
||||
protected CompletableFuture<Long> delAsync(final CacheSource source, String map, String key) {
|
||||
return source.hdelAsync(map, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据类型创建对应CacheValue泛型
|
||||
*
|
||||
* @param type 数据类型,为null则取value的类型
|
||||
* @param value 数据值
|
||||
*
|
||||
* @return CacheValue泛型
|
||||
*/
|
||||
protected Type loadCacheType(Type type, final Object value) {
|
||||
return loadCacheType(type == null ? value.getClass() : type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据类型创建对应CacheValue泛型
|
||||
*
|
||||
* @param type 数据类型
|
||||
*
|
||||
* @return CacheValue泛型
|
||||
*/
|
||||
protected Type loadCacheType(Type type) {
|
||||
return cacheValueTypes.computeIfAbsent(type, t -> TypeToken.createParameterizedType(null, CacheValue.class, type));
|
||||
}
|
||||
}
|
||||
68
src/main/java/org/redkale/caching/CacheValue.java
Normal file
68
src/main/java/org/redkale/caching/CacheValue.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.caching;
|
||||
|
||||
import java.time.Duration;
|
||||
import org.redkale.convert.ConvertColumn;
|
||||
import org.redkale.convert.ConvertDisabled;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
|
||||
/**
|
||||
*
|
||||
* 缓存对象
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
* @param <T> 泛型
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public class CacheValue<T> {
|
||||
|
||||
@ConvertColumn(index = 1)
|
||||
private T value;
|
||||
|
||||
//为0表示不过期
|
||||
@ConvertColumn(index = 2)
|
||||
private long time;
|
||||
|
||||
public CacheValue() {
|
||||
}
|
||||
|
||||
protected CacheValue(T value, Duration expire) {
|
||||
this.value = value;
|
||||
this.time = expire == null ? 0 : (System.currentTimeMillis() + expire.toMillis());
|
||||
}
|
||||
|
||||
public static <T> CacheValue<T> create(T value, Duration expire) {
|
||||
return new CacheValue(value, expire);
|
||||
}
|
||||
|
||||
@ConvertDisabled
|
||||
public boolean isExpired() {
|
||||
return time > 0 && System.currentTimeMillis() > time;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return JsonConvert.root().convertTo(this);
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
"org.redkale.asm",
|
||||
"org.redkale.boot",
|
||||
"org.redkale.boot.watch",
|
||||
"org.redkale.caching",
|
||||
"org.redkale.cluster",
|
||||
"org.redkale.convert",
|
||||
"org.redkale.convert.bson",
|
||||
|
||||
Reference in New Issue
Block a user