refactor(cache): 将Redis缓存替换为Caffeine缓存实现
修改缓存过期时间为10分钟 添加put方法到AbstractCaffeineCacheTemplate 更新相关服务类使用CaffeineCacheService
This commit is contained in:
parent
8eb671ec58
commit
f19a8077c4
|
|
@ -6,7 +6,7 @@ import com.agileboot.common.core.dto.ResponseDTO;
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Client;
|
import com.agileboot.common.exception.error.ErrorCode.Client;
|
||||||
import com.agileboot.common.utils.ServletHolderUtil;
|
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.admin.customize.async.AsyncTaskFactory;
|
||||||
import com.agileboot.infrastructure.thread.ThreadPoolManager;
|
import com.agileboot.infrastructure.thread.ThreadPoolManager;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
|
|
@ -48,7 +48,7 @@ public class SecurityConfig {
|
||||||
|
|
||||||
private final TokenService tokenService;
|
private final TokenService tokenService;
|
||||||
|
|
||||||
private final RedisCacheService redisCache;
|
private final CaffeineCacheService caffeineCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* token认证过滤器
|
* token认证过滤器
|
||||||
|
|
@ -89,7 +89,7 @@ public class SecurityConfig {
|
||||||
if (loginUser != null) {
|
if (loginUser != null) {
|
||||||
String userName = loginUser.getUsername();
|
String userName = loginUser.getUsername();
|
||||||
// 删除用户缓存记录
|
// 删除用户缓存记录
|
||||||
redisCache.loginUserCache.delete(loginUser.getCachedKey());
|
caffeineCache.loginUserCache.invalidate(loginUser.getCachedKey());
|
||||||
// 记录用户退出日志
|
// 记录用户退出日志
|
||||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(
|
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(
|
||||||
userName, LoginStatusEnum.LOGOUT, LoginStatusEnum.LOGOUT.description()));
|
userName, LoginStatusEnum.LOGOUT, LoginStatusEnum.LOGOUT.description()));
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import com.agileboot.common.utils.ServletHolderUtil;
|
||||||
import com.agileboot.common.utils.i18n.MessageUtils;
|
import com.agileboot.common.utils.i18n.MessageUtils;
|
||||||
import com.agileboot.domain.common.cache.GuavaCacheService;
|
import com.agileboot.domain.common.cache.GuavaCacheService;
|
||||||
import com.agileboot.domain.common.cache.MapCache;
|
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.admin.customize.async.AsyncTaskFactory;
|
||||||
import com.agileboot.domain.qywx.accessToken.AccessTokenApplicationService;
|
import com.agileboot.domain.qywx.accessToken.AccessTokenApplicationService;
|
||||||
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
|
import com.agileboot.domain.qywx.accessToken.db.QyAccessTokenEntity;
|
||||||
|
|
@ -66,7 +66,7 @@ public class LoginService {
|
||||||
|
|
||||||
private final TokenService tokenService;
|
private final TokenService tokenService;
|
||||||
|
|
||||||
private final RedisCacheService redisCache;
|
private final CaffeineCacheService caffeineCache;
|
||||||
|
|
||||||
private final GuavaCacheService guavaCache;
|
private final GuavaCacheService guavaCache;
|
||||||
|
|
||||||
|
|
@ -198,7 +198,8 @@ public class LoginService {
|
||||||
// 保存验证码信息
|
// 保存验证码信息
|
||||||
String imgKey = IdUtil.simpleUUID();
|
String imgKey = IdUtil.simpleUUID();
|
||||||
|
|
||||||
redisCache.captchaCache.set(imgKey, answer);
|
caffeineCache.captchaCache.put(imgKey, answer);
|
||||||
|
|
||||||
// 转换流信息写出
|
// 转换流信息写出
|
||||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||||
ImgUtil.writeJpg(image, os);
|
ImgUtil.writeJpg(image, os);
|
||||||
|
|
@ -220,8 +221,8 @@ public class LoginService {
|
||||||
* @param captchaCodeKey 验证码对应的缓存key
|
* @param captchaCodeKey 验证码对应的缓存key
|
||||||
*/
|
*/
|
||||||
public void validateCaptcha(String username, String captchaCode, String captchaCodeKey) {
|
public void validateCaptcha(String username, String captchaCode, String captchaCodeKey) {
|
||||||
String captcha = redisCache.captchaCache.getObjectById(captchaCodeKey);
|
String captcha = caffeineCache.captchaCache.get(captchaCodeKey);
|
||||||
redisCache.captchaCache.delete(captchaCodeKey);
|
caffeineCache.captchaCache.invalidate(captchaCodeKey);
|
||||||
if (captcha == null) {
|
if (captcha == null) {
|
||||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(username, LoginStatusEnum.LOGIN_FAIL,
|
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(username, LoginStatusEnum.LOGIN_FAIL,
|
||||||
ErrorCode.Business.LOGIN_CAPTCHA_CODE_EXPIRE.message()));
|
ErrorCode.Business.LOGIN_CAPTCHA_CODE_EXPIRE.message()));
|
||||||
|
|
@ -242,7 +243,7 @@ public class LoginService {
|
||||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginUser.getUsername(), LoginStatusEnum.LOGIN_SUCCESS,
|
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginUser.getUsername(), LoginStatusEnum.LOGIN_SUCCESS,
|
||||||
LoginStatusEnum.LOGIN_SUCCESS.description()));
|
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.setLoginIp(ServletUtil.getClientIP(ServletHolderUtil.getRequest()));
|
||||||
entity.setLoginDate(DateUtil.date());
|
entity.setLoginDate(DateUtil.date());
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil;
|
||||||
import com.agileboot.common.constant.Constants.Token;
|
import com.agileboot.common.constant.Constants.Token;
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
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 com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
|
|
@ -54,7 +54,7 @@ public class TokenService {
|
||||||
@Value("${token.autoRefreshTime}")
|
@Value("${token.autoRefreshTime}")
|
||||||
private long 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);
|
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) {
|
} catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException jwtException) {
|
||||||
log.error("parse token failed.", jwtException);
|
log.error("parse token failed.", jwtException);
|
||||||
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
|
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
|
||||||
|
|
@ -92,7 +92,8 @@ public class TokenService {
|
||||||
public String createTokenAndPutUserInCache(SystemLoginUser loginUser) {
|
public String createTokenAndPutUserInCache(SystemLoginUser loginUser) {
|
||||||
loginUser.setCachedKey(IdUtil.fastUUID());
|
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()));
|
return generateToken(MapUtil.of(Token.LOGIN_USER_KEY, loginUser.getCachedKey()));
|
||||||
}
|
}
|
||||||
|
|
@ -105,8 +106,7 @@ public class TokenService {
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
if (currentTime > loginUser.getAutoRefreshCacheTime()) {
|
if (currentTime > loginUser.getAutoRefreshCacheTime()) {
|
||||||
loginUser.setAutoRefreshCacheTime(currentTime + TimeUnit.MINUTES.toMillis(autoRefreshTime));
|
loginUser.setAutoRefreshCacheTime(currentTime + TimeUnit.MINUTES.toMillis(autoRefreshTime));
|
||||||
// 根据uuid将loginUser存入缓存
|
caffeineCache.loginUserCache.put(loginUser.getCachedKey(), loginUser);
|
||||||
redisCache.loginUserCache.set(loginUser.getCachedKey(), loginUser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
||||||
import com.agileboot.common.constant.Constants.Token;
|
import com.agileboot.common.constant.Constants.Token;
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
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 com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
|
|
@ -43,7 +43,7 @@ public class JwtTokenService {
|
||||||
@Value("${token.secret}")
|
@Value("${token.secret}")
|
||||||
private String 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);
|
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) {
|
} catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException jwtException) {
|
||||||
log.error("parse token failed.", jwtException);
|
log.error("parse token failed.", jwtException);
|
||||||
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
|
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
|
||||||
} catch (Exception e) {
|
} 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());
|
throw new ApiException(e, ErrorCode.Client.TOKEN_PROCESS_FAILED, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import org.springframework.stereotype.Component;
|
||||||
/**
|
/**
|
||||||
* 缓存中心 提供全局访问点
|
* 缓存中心 提供全局访问点
|
||||||
* 如果是领域类的缓存 可以自己新建一个直接放在CacheCenter 不用放在infrastructure包里的GuavaCacheService
|
* 如果是领域类的缓存 可以自己新建一个直接放在CacheCenter 不用放在infrastructure包里的GuavaCacheService
|
||||||
* 或者RedisCacheService
|
* 或者CaffeineCacheService
|
||||||
* @author valarchie
|
* @author valarchie
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import com.agileboot.domain.ab98.api.Ab98ApiUtil;
|
||||||
import com.agileboot.domain.ab98.api.SsoLoginUserinfo;
|
import com.agileboot.domain.ab98.api.SsoLoginUserinfo;
|
||||||
import com.agileboot.domain.ab98.user.db.Ab98UserEntity;
|
import com.agileboot.domain.ab98.user.db.Ab98UserEntity;
|
||||||
import com.agileboot.domain.ab98.user.db.Ab98UserService;
|
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.common.command.BulkOperationCommand;
|
||||||
import com.agileboot.domain.qywx.user.command.AddQyUserCommand;
|
import com.agileboot.domain.qywx.user.command.AddQyUserCommand;
|
||||||
import com.agileboot.domain.qywx.user.command.UpdateQyUserCommand;
|
import com.agileboot.domain.qywx.user.command.UpdateQyUserCommand;
|
||||||
|
|
@ -44,7 +44,7 @@ public class QyUserApplicationService {
|
||||||
private final SysRoleService sysRoleService;
|
private final SysRoleService sysRoleService;
|
||||||
private final Ab98UserService ab98UserService;
|
private final Ab98UserService ab98UserService;
|
||||||
|
|
||||||
private final RedisCacheService redisCache;
|
private final CaffeineCacheService caffeineCache;
|
||||||
|
|
||||||
public PageDTO<QyUserDTO> getUserList(SearchQyUserQuery<QyUserEntity> query) {
|
public PageDTO<QyUserDTO> getUserList(SearchQyUserQuery<QyUserEntity> query) {
|
||||||
Page<QyUserEntity> page = userService.getUserList(query);
|
Page<QyUserEntity> page = userService.getUserList(query);
|
||||||
|
|
@ -104,7 +104,7 @@ public class QyUserApplicationService {
|
||||||
sysUser.setRoleId(command.getRoleId() > 0 ? command.getRoleId() : null);
|
sysUser.setRoleId(command.getRoleId() > 0 ? command.getRoleId() : null);
|
||||||
sysUser.updateById();
|
sysUser.updateById();
|
||||||
|
|
||||||
redisCache.userCache.delete(sysUser.getUserId());
|
caffeineCache.userCache.invalidate(String.valueOf(sysUser.getUserId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ public abstract class AbstractCaffeineCacheTemplate<T> {
|
||||||
// 设置软引用值
|
// 设置软引用值
|
||||||
.softValues()
|
.softValues()
|
||||||
// 设置过期时间 - 最后一次写入后经过固定时间过期
|
// 设置过期时间 - 最后一次写入后经过固定时间过期
|
||||||
.expireAfterWrite(60, TimeUnit.MINUTES)
|
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||||
// 设置刷新时间 - 写入后经过固定时间刷新
|
// 设置刷新时间 - 写入后经过固定时间刷新
|
||||||
.refreshAfterWrite(5, TimeUnit.MINUTES)
|
.refreshAfterWrite(5, TimeUnit.MINUTES)
|
||||||
// 所有segment的初始总容量大小
|
// 所有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 缓存键
|
* @param key 缓存键
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue