🏗️ 将缓存框架由 Spring Boot Cache 改为 Alibaba JetCache, 支持缓存自动刷新

This commit is contained in:
zhaojun1998
2019-12-29 19:09:50 +08:00
parent 099c09b625
commit 6a54150868
13 changed files with 79 additions and 115 deletions

View File

@@ -134,6 +134,12 @@
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>2.5.14</version>
</dependency>
</dependencies>
<repositories>

View File

@@ -1,8 +1,9 @@
package im.zhaojun;
import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
@@ -11,7 +12,8 @@ import org.springframework.scheduling.annotation.EnableAsync;
*/
@EnableAsync
@SpringBootApplication
@EnableCaching
@EnableMethodCache(basePackages = "im.zhaojun", proxyTargetClass = true)
@EnableCreateCacheAnnotation
@EnableAspectJAutoProxy(exposeProxy = true)
public class ZfileApplication {

View File

@@ -1,76 +0,0 @@
package im.zhaojun.common.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.util.Collections;
/**
* 缓存配置类, 用于根据配置决定使用 redis 缓存还是 caffeine (内存).
* @author zhaojun
*/
@Configuration
public class ZFileCacheConfiguration {
public static final String CACHE_NAME = "zfile";
/**
* 个性化配置缓存
*/
@Bean
@ConditionalOnProperty(value = "spring.cache.type", havingValue = "caffeine")
public CaffeineCacheManager caffeineCacheManager() {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCacheNames(Collections.singletonList(CACHE_NAME));
return caffeineCacheManager;
}
@Bean
@ConditionalOnProperty(value = "spring.cache.type", havingValue = "redis")
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
GenericJackson2JsonRedisSerializer jsonRedisSerializer
= new GenericJackson2JsonRedisSerializer();
RedisSerializationContext.SerializationPair<Object> pair
= RedisSerializationContext.SerializationPair.fromSerializer(jsonRedisSerializer);
RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
}
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
char separator = ':';
StringBuilder strBuilder = new StringBuilder();
// 类名
strBuilder.append(target.getClass().getSimpleName());
strBuilder.append(separator);
// 方法名
strBuilder.append(method.getName());
strBuilder.append(separator);
// 参数值
for (int i = 0; i < params.length; i++) {
if (i == params.length - 1) {
strBuilder.append(params[i]);
} else {
strBuilder.append(params[i]).append(",");
}
}
return strBuilder.toString();
};
}
}

View File

@@ -13,6 +13,8 @@ public class SystemConfigConstant {
public static final String SEARCH_IGNORE_CASE = "searchIgnoreCase";
public static final String ENABLE_CACHE = "enableCache";
public static final String STORAGE_STRATEGY = "storageStrategy";
public static final String USERNAME = "username";

View File

@@ -35,4 +35,6 @@ public class SystemConfigDTO {
private String password;
private String domain;
private Boolean enableCache;
}

View File

@@ -1,35 +1,56 @@
package im.zhaojun.common.service;
import im.zhaojun.common.config.ZFileCacheConfiguration;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheRefresh;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.alicp.jetcache.anno.CreateCache;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.util.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author zhaojun
* @date 2019/12/28 19:27
*/
@CacheConfig(cacheNames = ZFileCacheConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
public abstract class AbstractFileService implements FileService {
@Value("${zfile.cache.timeout}")
protected Long timeout;
protected boolean isInitialized;
@CreateCache(name = "zfile-cache:")
private Cache<String, Object> userCache;
@Override
@Cached(name = "zfile-cache:", key = "#path", cacheType = CacheType.LOCAL, condition = "mvel{bean('systemConfigService').enableCache}")
@CacheRefresh(refresh = 30, timeUnit = TimeUnit.MINUTES)
public abstract List<FileItemDTO> fileList(String path) throws Exception;
/**
* 清理当前存储引擎的缓存
*/
public void clearCache() {
}
/**
* 初始化方法, 启动时自动调用实现类的此方法进行初始化.
*/
@PostConstruct
public abstract void init();
protected boolean testConnection() {
boolean flag = true;
try {
@@ -55,12 +76,6 @@ public abstract class AbstractFileService implements FileService {
*/
public abstract StorageTypeEnum getStorageTypeEnum();
/**
* 清除缓存.
*/
@CacheEvict(allEntries = true)
public void clearCache() {}
/**
* 搜索文件
* @param name 文件名

View File

@@ -6,13 +6,9 @@ import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import im.zhaojun.common.config.ZFileCacheConfiguration;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import javax.annotation.Resource;
import java.net.URL;
@@ -24,12 +20,7 @@ import java.util.List;
* @author zhaojun
* @date 2019/12/26 22:26
*/
@CacheConfig(cacheNames = ZFileCacheConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
public abstract class AbstractS3FileService extends AbstractFileService {
@Value("${zfile.cache.timeout}")
private Long timeout;
@Resource
protected StorageConfigService storageConfigService;
@@ -44,14 +35,12 @@ public abstract class AbstractS3FileService extends AbstractFileService {
protected AmazonS3 s3Client;
@Override
@Cacheable
public List<FileItemDTO> fileList(String path) {
this.path = path;
return s3FileList(path);
}
@Override
@Cacheable
public String getDownloadUrl(String path) {
this.path = path;
return s3ObjectUrl(path);

View File

@@ -9,10 +9,11 @@ import java.util.List;
*/
public interface FileService {
/**
* 获取指定路径下的文件及文件
/***
* 获取指定路径下的文件及文件夹, 默认缓存 60 分钟,每隔 30 分钟刷新一次.
* @param path 文件路径
* @return 文件及文件夹列表
* @throws Exception 获取文件列表中出现的异常
*/
List<FileItemDTO> fileList(String path) throws Exception;

View File

@@ -54,6 +54,9 @@ public class SystemConfigService {
case SystemConfigConstant.DOMAIN:
systemConfigDTO.setDomain(systemConfig.getValue());
break;
case SystemConfigConstant.ENABLE_CACHE:
systemConfigDTO.setEnableCache("true".equals(systemConfig.getValue()));
break;
default:break;
}
}
@@ -84,6 +87,10 @@ public class SystemConfigService {
searchIgnoreCaseSystemConfig.setValue(systemConfigDTO.getSearchIgnoreCase() ? "true" : "false");
systemConfigList.add(searchIgnoreCaseSystemConfig);
SystemConfig enableCacheSystemConfig = systemConfigRepository.findByKey(SystemConfigConstant.ENABLE_CACHE);
enableCacheSystemConfig.setValue(systemConfigDTO.getEnableCache() ? "true" : "false");
systemConfigList.add(enableCacheSystemConfig);
SystemConfig storageStrategySystemConfig = systemConfigRepository.findByKey(SystemConfigConstant.STORAGE_STRATEGY);
storageStrategySystemConfig.setValue(systemConfigDTO.getStorageStrategy().getKey());
systemConfigList.add(storageStrategySystemConfig);
@@ -125,4 +132,9 @@ public class SystemConfigService {
return systemConfigDTO.getStorageStrategy();
}
public boolean getEnableCache() {
SystemConfigDTO systemConfigDTO = getSystemConfig();
return systemConfigDTO.getEnableCache();
}
}

View File

@@ -2,7 +2,6 @@ package im.zhaojun.ftp.service;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.ftp.Ftp;
import im.zhaojun.common.config.ZFileCacheConfiguration;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
@@ -15,7 +14,6 @@ import im.zhaojun.common.util.StringUtils;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@@ -28,7 +26,6 @@ import java.util.Map;
* @author zhaojun
*/
@Service
@CacheConfig(cacheNames = ZFileCacheConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
public class FtpServiceImpl extends AbstractFileService implements FileService {
private static final Logger log = LoggerFactory.getLogger(FtpServiceImpl.class);

View File

@@ -24,9 +24,6 @@ public class QiniuServiceImpl extends AbstractS3FileService implements FileServi
private static final Logger log = LoggerFactory.getLogger(QiniuServiceImpl.class);
@Value("${zfile.cache.timeout}")
private Long timeout;
@Override
public void init() {
try {

View File

@@ -2,7 +2,6 @@ package im.zhaojun.upyun.service;
import cn.hutool.core.util.URLUtil;
import com.UpYun;
import im.zhaojun.common.config.ZFileCacheConfiguration;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
@@ -14,7 +13,6 @@ import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@@ -28,7 +26,6 @@ import java.util.Map;
* @author zhaojun
*/
@Service
@CacheConfig(cacheNames = ZFileCacheConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
public class UpYunServiceImpl extends AbstractFileService implements FileService {
private static final Logger log = LoggerFactory.getLogger(UpYunServiceImpl.class);

View File

@@ -45,13 +45,33 @@ spring:
resources:
chain:
gzipped: true
redis:
host: 127.0.0.1
password: 12345
zfile:
cache:
timeout: 300
constant:
header: header.md
footer: footer.md
password: password.txt
password: password.txt
jetcache:
statIntervalMinutes: 1
areaInCacheName: false
local:
default:
type: caffeine
keyConvertor: fastjson
defaultExpireInMillis: 6000000
remote:
default:
type: redis
keyConvertor: fastjson
valueEncoder: kryo
valueDecoder: kryo
defaultExpireInMillis: 3600000
poolConfig:
minIdle: 5
maxIdle: 20
maxTotal: 50
host: 127.0.0.1
port: 6379
password: 12345