refactor(cache): 将Redis缓存替换为Caffeine缓存实现

修改缓存过期时间为10分钟
添加put方法到AbstractCaffeineCacheTemplate
更新相关服务类使用CaffeineCacheService
This commit is contained in:
dzq 2025-09-19 15:03:32 +08:00
parent 8eb671ec58
commit f19a8077c4
7 changed files with 32 additions and 24 deletions

View File

@ -6,7 +6,7 @@ import com.agileboot.common.core.dto.ResponseDTO;
import com.agileboot.common.exception.ApiException;
import com.agileboot.common.exception.error.ErrorCode.Client;
import com.agileboot.common.utils.ServletHolderUtil;
import com.agileboot.domain.common.cache.RedisCacheService;
import com.agileboot.domain.common.cache.CaffeineCacheService;
import com.agileboot.admin.customize.async.AsyncTaskFactory;
import com.agileboot.infrastructure.thread.ThreadPoolManager;
import com.agileboot.infrastructure.user.web.SystemLoginUser;
@ -48,7 +48,7 @@ public class SecurityConfig {
private final TokenService tokenService;
private final RedisCacheService redisCache;
private final CaffeineCacheService caffeineCache;
/**
* token认证过滤器
@ -89,7 +89,7 @@ public class SecurityConfig {
if (loginUser != null) {
String userName = loginUser.getUsername();
// 删除用户缓存记录
redisCache.loginUserCache.delete(loginUser.getCachedKey());
caffeineCache.loginUserCache.invalidate(loginUser.getCachedKey());
// 记录用户退出日志
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(
userName, LoginStatusEnum.LOGOUT, LoginStatusEnum.LOGOUT.description()));

View File

@ -21,7 +21,7 @@ import com.agileboot.common.utils.ServletHolderUtil;
import com.agileboot.common.utils.i18n.MessageUtils;
import com.agileboot.domain.common.cache.GuavaCacheService;
import com.agileboot.domain.common.cache.MapCache;
import com.agileboot.domain.common.cache.RedisCacheService;
import com.agileboot.domain.common.cache.CaffeineCacheService;
import com.agileboot.admin.customize.async.AsyncTaskFactory;
import com.agileboot.domain.qywx.accessToken.AccessTokenApplicationService;
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
@ -66,7 +66,7 @@ public class LoginService {
private final TokenService tokenService;
private final RedisCacheService redisCache;
private final CaffeineCacheService caffeineCache;
private final GuavaCacheService guavaCache;
@ -198,7 +198,8 @@ public class LoginService {
// 保存验证码信息
String imgKey = IdUtil.simpleUUID();
redisCache.captchaCache.set(imgKey, answer);
caffeineCache.captchaCache.put(imgKey, answer);
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
ImgUtil.writeJpg(image, os);
@ -220,8 +221,8 @@ public class LoginService {
* @param captchaCodeKey 验证码对应的缓存key
*/
public void validateCaptcha(String username, String captchaCode, String captchaCodeKey) {
String captcha = redisCache.captchaCache.getObjectById(captchaCodeKey);
redisCache.captchaCache.delete(captchaCodeKey);
String captcha = caffeineCache.captchaCache.get(captchaCodeKey);
caffeineCache.captchaCache.invalidate(captchaCodeKey);
if (captcha == null) {
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(username, LoginStatusEnum.LOGIN_FAIL,
ErrorCode.Business.LOGIN_CAPTCHA_CODE_EXPIRE.message()));
@ -242,7 +243,7 @@ public class LoginService {
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginUser.getUsername(), LoginStatusEnum.LOGIN_SUCCESS,
LoginStatusEnum.LOGIN_SUCCESS.description()));
SysUserEntity entity = redisCache.userCache.getObjectById(loginUser.getUserId());
SysUserEntity entity = caffeineCache.userCache.get(String.valueOf(loginUser.getUserId()));
entity.setLoginIp(ServletUtil.getClientIP(ServletHolderUtil.getRequest()));
entity.setLoginDate(DateUtil.date());

View File

@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil;
import com.agileboot.common.constant.Constants.Token;
import com.agileboot.common.exception.ApiException;
import com.agileboot.common.exception.error.ErrorCode;
import com.agileboot.domain.common.cache.RedisCacheService;
import com.agileboot.domain.common.cache.CaffeineCacheService;
import com.agileboot.infrastructure.user.web.SystemLoginUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
@ -54,7 +54,7 @@ public class TokenService {
@Value("${token.autoRefreshTime}")
private long autoRefreshTime;
private final RedisCacheService redisCache;
private final CaffeineCacheService caffeineCache;
/**
* 获取用户身份信息
@ -70,7 +70,7 @@ public class TokenService {
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Token.LOGIN_USER_KEY);
return redisCache.loginUserCache.getObjectOnlyInCacheById(uuid);
return caffeineCache.loginUserCache.get(uuid);
} catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException jwtException) {
log.error("parse token failed.", jwtException);
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
@ -92,7 +92,8 @@ public class TokenService {
public String createTokenAndPutUserInCache(SystemLoginUser loginUser) {
loginUser.setCachedKey(IdUtil.fastUUID());
redisCache.loginUserCache.set(loginUser.getCachedKey(), loginUser);
caffeineCache.loginUserCache.put(loginUser.getCachedKey(), loginUser);
return generateToken(MapUtil.of(Token.LOGIN_USER_KEY, loginUser.getCachedKey()));
}
@ -105,8 +106,7 @@ public class TokenService {
long currentTime = System.currentTimeMillis();
if (currentTime > loginUser.getAutoRefreshCacheTime()) {
loginUser.setAutoRefreshCacheTime(currentTime + TimeUnit.MINUTES.toMillis(autoRefreshTime));
// 根据uuid将loginUser存入缓存
redisCache.loginUserCache.set(loginUser.getCachedKey(), loginUser);
caffeineCache.loginUserCache.put(loginUser.getCachedKey(), loginUser);
}
}

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
import com.agileboot.common.constant.Constants.Token;
import com.agileboot.common.exception.ApiException;
import com.agileboot.common.exception.error.ErrorCode;
import com.agileboot.domain.common.cache.RedisCacheService;
import com.agileboot.domain.common.cache.CaffeineCacheService;
import com.agileboot.infrastructure.user.web.SystemLoginUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
@ -43,7 +43,7 @@ public class JwtTokenService {
@Value("${token.secret}")
private String secret;
private final RedisCacheService redisCache;
private final CaffeineCacheService caffeineCache;
/**
* 获取用户身份信息
@ -59,12 +59,12 @@ public class JwtTokenService {
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Token.LOGIN_USER_KEY);
return redisCache.loginUserCache.getObjectOnlyInCacheById(uuid);
return caffeineCache.loginUserCache.get(uuid);
} catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException jwtException) {
log.error("parse token failed.", jwtException);
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
} catch (Exception e) {
log.error("fail to get cached user from redis", e);
log.error("fail to get cached user from caffeine", e);
throw new ApiException(e, ErrorCode.Client.TOKEN_PROCESS_FAILED, e.getMessage());
}

View File

@ -14,7 +14,7 @@ import org.springframework.stereotype.Component;
/**
* 缓存中心 提供全局访问点
* 如果是领域类的缓存 可以自己新建一个直接放在CacheCenter 不用放在infrastructure包里的GuavaCacheService
* 或者RedisCacheService
* 或者CaffeineCacheService
* @author valarchie
*/
@Component

View File

@ -6,7 +6,7 @@ import com.agileboot.domain.ab98.api.Ab98ApiUtil;
import com.agileboot.domain.ab98.api.SsoLoginUserinfo;
import com.agileboot.domain.ab98.user.db.Ab98UserEntity;
import com.agileboot.domain.ab98.user.db.Ab98UserService;
import com.agileboot.domain.common.cache.RedisCacheService;
import com.agileboot.domain.common.cache.CaffeineCacheService;
import com.agileboot.domain.common.command.BulkOperationCommand;
import com.agileboot.domain.qywx.user.command.AddQyUserCommand;
import com.agileboot.domain.qywx.user.command.UpdateQyUserCommand;
@ -44,7 +44,7 @@ public class QyUserApplicationService {
private final SysRoleService sysRoleService;
private final Ab98UserService ab98UserService;
private final RedisCacheService redisCache;
private final CaffeineCacheService caffeineCache;
public PageDTO<QyUserDTO> getUserList(SearchQyUserQuery<QyUserEntity> query) {
Page<QyUserEntity> page = userService.getUserList(query);
@ -104,7 +104,7 @@ public class QyUserApplicationService {
sysUser.setRoleId(command.getRoleId() > 0 ? command.getRoleId() : null);
sysUser.updateById();
redisCache.userCache.delete(sysUser.getUserId());
caffeineCache.userCache.invalidate(String.valueOf(sysUser.getUserId()));
}
}

View File

@ -27,7 +27,7 @@ public abstract class AbstractCaffeineCacheTemplate<T> {
// 设置软引用值
.softValues()
// 设置过期时间 - 最后一次写入后经过固定时间过期
.expireAfterWrite(60, TimeUnit.MINUTES)
.expireAfterWrite(10, TimeUnit.MINUTES)
// 设置刷新时间 - 写入后经过固定时间刷新
.refreshAfterWrite(5, TimeUnit.MINUTES)
// 所有segment的初始总容量大小
@ -74,6 +74,13 @@ public abstract class AbstractCaffeineCacheTemplate<T> {
}
}
public void put(String key, T value) {
if (StrUtil.isEmpty(key)) {
return;
}
caffeineCache.put(key, Optional.ofNullable(value));
}
/**
* 使缓存失效
* @param key 缓存键