|
@@ -0,0 +1,112 @@
|
|
|
+package cn.com.qmth.examcloud.web.cache;
|
|
|
+
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.assertj.core.util.Arrays;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.exception.ExamCloudRuntimeException;
|
|
|
+import cn.com.qmth.examcloud.commons.helpers.ObjectHolder;
|
|
|
+import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
+import cn.com.qmth.examcloud.web.support.SpringContextHolder;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 全量reids缓存
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @date 2019年3月13日
|
|
|
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
+ * @param <T>
|
|
|
+ */
|
|
|
+public abstract class FullObjectRedisCache<T> implements FullObjectCache<T> {
|
|
|
+
|
|
|
+ protected abstract String getKeyPrefix();
|
|
|
+
|
|
|
+ private RedisClient redisClient;
|
|
|
+
|
|
|
+ private FullObjectCacheController fullObjectCacheController = new DefaultFullObjectCacheController();
|
|
|
+
|
|
|
+ private RedisClient getRedisClient() {
|
|
|
+ if (null == redisClient) {
|
|
|
+ redisClient = SpringContextHolder.getBean(RedisClient.class);
|
|
|
+ }
|
|
|
+ return redisClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected String buildKey(Object... keys) {
|
|
|
+ String key = getKeyPrefix() + StringUtils.join(Arrays.asList(keys), '_');
|
|
|
+ return key;
|
|
|
+ }
|
|
|
+
|
|
|
+ private T getFromCache(String key) {
|
|
|
+ Object object = getRedisClient().get(key, Object.class);
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ T t = (T) object;
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public T get(Object... keys) {
|
|
|
+ String key = buildKey(keys);
|
|
|
+ T t = getFromCache(key);
|
|
|
+ if (null == t) {
|
|
|
+ if (getFullObjectCacheController().allLoaded()) {
|
|
|
+ return t;
|
|
|
+ } else {
|
|
|
+ refresh(keys);
|
|
|
+ t = getFromCache(key);
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void remove(Object... keys) {
|
|
|
+ String key = buildKey(keys);
|
|
|
+ getRedisClient().delete(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void refresh(Object... keys) {
|
|
|
+ String key = buildKey(keys);
|
|
|
+ T t = null;
|
|
|
+ try {
|
|
|
+ t = loadFromResource(keys);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new ExamCloudRuntimeException("fail to load data. key=" + key, e);
|
|
|
+ }
|
|
|
+ if (null != t) {
|
|
|
+ getRedisClient().set(key, t);
|
|
|
+ } else {
|
|
|
+ getRedisClient().delete(key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected abstract List<Object[]> getKeys(final ObjectHolder<Long> beginIndex,
|
|
|
+ final ObjectHolder<Boolean> empty);
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public long loadAllFromResource() {
|
|
|
+ final ObjectHolder<Long> beginIndex = new ObjectHolder<Long>(null);
|
|
|
+ final ObjectHolder<Boolean> empty = new ObjectHolder<Boolean>(false);
|
|
|
+ while (true) {
|
|
|
+ List<Object[]> keysList = getKeys(beginIndex, empty);
|
|
|
+ if (empty.get()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ for (Object[] keys : keysList) {
|
|
|
+ this.refresh(keys);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ getFullObjectCacheController().setAllLoaded(true);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FullObjectCacheController getFullObjectCacheController() {
|
|
|
+ return fullObjectCacheController;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|