feat(缓存添加可配置标识):

针对二次开发项目可能部署在同一个服务器上导致缓存冲突的问题,给所有的缓存Key改原先写在代码里的配置为引用CacheKey配置,并给每个缓存Key增加PROJECT作为头,用以区分不同的项目缓存
pull/768/head
Emil.Zhang 2022-08-30 16:51:49 +08:00
parent 164ce50bb0
commit e65f10dba5
17 changed files with 152 additions and 75 deletions

View File

@ -16,6 +16,10 @@
package me.zhengjie.utils;
/**
* Key PROJECT + xxx_KEY + :: + ID|NAME + : +
* <p>
* key baiKe-user-id-1
*
* @author: liaojinlong
* @date: 2020/6/11 15:49
* @apiNote: Key
@ -23,36 +27,97 @@ package me.zhengjie.utils;
public interface CacheKey {
/**
*
*
*/
String USER_ID = "user::id:";
String PROJECT = "baiKe-";
/**
*
*
*/
String DATA_USER = "data::user:";
String USER_KEY = "user";
/**
*
*
*/
String MENU_ID = "menu::id:";
String MENU_USER = "menu::user:";
String MENU_KEY = "menu";
/**
*
*
*/
String ROLE_AUTH = "role::auth:";
String ROLE_KEY = "role";
/**
*
*
*/
String ROLE_ID = "role::id:";
/**
*
*/
String DEPT_ID = "dept::id:";
String DEPT_KEY = "dept";
/**
*
*/
String JOB_ID = "job::id:";
String JOB_KEY = "job";
/**
*
*/
String DATA_KEY = "data";
/**
*
*/
String AUTH_KEY = "auth";
/**
*
*/
String DICT_NAME = "dict::name:";
String DICT_KEY = "dict";
/**
*
*/
String ALI_PAY = "aliPay";
/**
*
*/
String EMAIL = "email";
/**
*
*/
String QI_NIU = "qiNiu";
/**
* ID
*/
String ID = "id";
/**
*
*/
String NAME = "name";
/**
*
*/
String CONFIG = "config";
/**
* key PROJECT + xx_KEY
* baiKe-user
*
* @param key xx_KEY
* @return /
*/
static String projectAndKey(String key) {
return String.format(
"%1$s%2$s",
PROJECT,
key
);
}
/**
* RedisKey
* <p>
* key target PROJECT + xx_KEY + target::
* <p>
* baiKe-user::id:ID
*
* @param key xx_KEY
* @param target target
* @return PROJECT-key::target:
*/
static String keyAndTarget(String key, String target) {
return String.format(
"%1$s::%2$s:",
projectAndKey(key),
target
);
}
}

View File

@ -19,6 +19,7 @@ import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;
import lombok.Data;
import me.zhengjie.exception.BadConfigurationException;
import me.zhengjie.utils.CacheKey;
import me.zhengjie.utils.StringUtils;
import java.awt.*;
import java.util.Objects;
@ -39,7 +40,7 @@ public class LoginProperties {
private LoginCode loginCode;
public static final String cacheKey = "USER-LOGIN-DATA";
public static final String cacheKey = CacheKey.PROJECT + "USER-LOGIN-DATA";
public boolean isSingleLogin() {
return singleLogin;

View File

@ -16,6 +16,7 @@
package me.zhengjie.modules.security.config.bean;
import lombok.Data;
import me.zhengjie.utils.CacheKey;
/**
* Jwt
@ -66,6 +67,14 @@ public class SecurityProperties {
*/
private Long renew;
public void setOnlineKey(String onlineKey) {
this.onlineKey = CacheKey.PROJECT + onlineKey;
}
public void setCodeKey(String codeKey) {
this.codeKey = CacheKey.PROJECT + codeKey;
}
public String getTokenStartWith() {
return tokenStartWith + " ";
}

View File

@ -22,6 +22,7 @@ import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.CacheKey;
import me.zhengjie.utils.enums.DataScopeEnum;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
@ -36,7 +37,7 @@ import java.util.*;
**/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "data")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.DATA_KEY)
public class DataServiceImpl implements DataService {
private final RoleService roleService;
@ -48,7 +49,7 @@ public class DataServiceImpl implements DataService {
* @return /
*/
@Override
@Cacheable(key = "'user:' + #p0.id")
@Cacheable(key = "'" + CacheKey.USER_KEY + ":' + #user.id")
public List<Long> getDeptIds(UserDto user) {
// 用于存储部门id
Set<Long> deptIds = new HashSet<>();

View File

@ -47,7 +47,7 @@ import java.util.stream.Collectors;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dept")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.DEPT_KEY)
public class DeptServiceImpl implements DeptService {
private final DeptRepository deptRepository;
@ -88,7 +88,7 @@ public class DeptServiceImpl implements DeptService {
}
@Override
@Cacheable(key = "'id:' + #p0")
@Cacheable(key = "'" + CacheKey.ID + ":' + #id")
public DeptDto findById(Long id) {
Dept dept = deptRepository.findById(id).orElseGet(Dept::new);
ValidationUtil.isNull(dept.getId(),"Dept","id",id);
@ -277,7 +277,10 @@ public class DeptServiceImpl implements DeptService {
public void delCaches(Long id){
List<User> users = userRepository.findByRoleDeptId(id);
// 删除数据权限
redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
redisUtils.del(CacheKey.DEPT_ID + id);
redisUtils.delByKeys(
CacheKey.keyAndTarget(CacheKey.DATA_KEY, CacheKey.USER_KEY),
users.stream().map(User::getId).collect(Collectors.toSet())
);
redisUtils.del(CacheKey.keyAndTarget(CacheKey.DEPT_KEY, CacheKey.ID) + id);
}
}

View File

@ -40,7 +40,7 @@ import java.util.Map;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.DICT_KEY)
public class DictDetailServiceImpl implements DictDetailService {
private final DictRepository dictRepository;
@ -74,7 +74,7 @@ public class DictDetailServiceImpl implements DictDetailService {
}
@Override
@Cacheable(key = "'name:' + #p0")
@Cacheable(key = "'" + CacheKey.NAME + ":' + #name")
public List<DictDetailDto> getDictByName(String name) {
return dictDetailMapper.toDto(dictDetailRepository.findByDictName(name));
}
@ -90,6 +90,6 @@ public class DictDetailServiceImpl implements DictDetailService {
public void delCaches(DictDetail dictDetail){
Dict dict = dictRepository.findById(dictDetail.getDict().getId()).orElseGet(Dict::new);
redisUtils.del(CacheKey.DICT_NAME + dict.getName());
redisUtils.del(CacheKey.keyAndTarget(CacheKey.DICT_KEY, CacheKey.NAME) + dict.getName());
}
}

View File

@ -40,7 +40,7 @@ import java.util.*;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.DICT_KEY)
public class DictServiceImpl implements DictService {
private final DictRepository dictRepository;
@ -116,6 +116,6 @@ public class DictServiceImpl implements DictService {
}
public void delCaches(Dict dict){
redisUtils.del(CacheKey.DICT_NAME + dict.getName());
redisUtils.del(CacheKey.keyAndTarget(CacheKey.DICT_KEY, CacheKey.NAME) + dict.getName());
}
}

View File

@ -43,7 +43,7 @@ import java.util.*;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "job")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.JOB_KEY)
public class JobServiceImpl implements JobService {
private final JobRepository jobRepository;
@ -64,7 +64,7 @@ public class JobServiceImpl implements JobService {
}
@Override
@Cacheable(key = "'id:' + #p0")
@Cacheable(key = "'" + CacheKey.ID + ":' + #id")
public JobDto findById(Long id) {
Job job = jobRepository.findById(id).orElseGet(Job::new);
ValidationUtil.isNull(job.getId(),"Job","id",id);
@ -82,7 +82,7 @@ public class JobServiceImpl implements JobService {
}
@Override
@CacheEvict(key = "'id:' + #p0.id")
@CacheEvict(key = "'" + CacheKey.ID + ":' + #resources.id")
@Transactional(rollbackFor = Exception.class)
public void update(Job resources) {
Job job = jobRepository.findById(resources.getId()).orElseGet(Job::new);
@ -100,7 +100,7 @@ public class JobServiceImpl implements JobService {
public void delete(Set<Long> ids) {
jobRepository.deleteAllByIdIn(ids);
// 删除缓存
redisUtils.delByKeys(CacheKey.JOB_ID, ids);
redisUtils.delByKeys(CacheKey.keyAndTarget(CacheKey.JOB_KEY, CacheKey.ID), ids);
}
@Override

View File

@ -50,7 +50,7 @@ import java.util.stream.Collectors;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "menu")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.MENU_KEY)
public class MenuServiceImpl implements MenuService {
private final MenuRepository menuRepository;
@ -82,7 +82,7 @@ public class MenuServiceImpl implements MenuService {
}
@Override
@Cacheable(key = "'id:' + #p0")
@Cacheable(key = "'" + CacheKey.ID + ":' + #id")
public MenuDto findById(long id) {
Menu menu = menuRepository.findById(id).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Menu","id",id);
@ -95,7 +95,7 @@ public class MenuServiceImpl implements MenuService {
* @return /
*/
@Override
@Cacheable(key = "'user:' + #p0")
@Cacheable(key = "'" + CacheKey.USER_KEY + ":' + #currentUserId")
public List<MenuDto> findByUser(Long currentUserId) {
List<RoleSmallDto> roles = roleService.findByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet());
@ -344,12 +344,12 @@ public class MenuServiceImpl implements MenuService {
*/
public void delCaches(Long id){
List<User> users = userRepository.findByMenuId(id);
redisUtils.del(CacheKey.MENU_ID + id);
redisUtils.delByKeys(CacheKey.MENU_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
redisUtils.del(CacheKey.keyAndTarget(CacheKey.MENU_KEY, CacheKey.ID) + id);
redisUtils.delByKeys(CacheKey.keyAndTarget(CacheKey.MENU_KEY, CacheKey.USER_KEY), users.stream().map(User::getId).collect(Collectors.toSet()));
// 清除 Role 缓存
List<Role> roles = roleService.findInMenuId(new ArrayList<Long>(){{
add(id);
}});
redisUtils.delByKeys(CacheKey.ROLE_ID, roles.stream().map(Role::getId).collect(Collectors.toSet()));
redisUtils.delByKeys(CacheKey.keyAndTarget(CacheKey.ROLE_KEY, CacheKey.ID), roles.stream().map(Role::getId).collect(Collectors.toSet()));
}
}

View File

@ -52,7 +52,7 @@ import java.util.stream.Collectors;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "role")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.ROLE_KEY)
public class RoleServiceImpl implements RoleService {
private final RoleRepository roleRepository;
@ -80,7 +80,7 @@ public class RoleServiceImpl implements RoleService {
}
@Override
@Cacheable(key = "'id:' + #p0")
@Cacheable(key = "'" + CacheKey.ID + ":' + #id")
@Transactional(rollbackFor = Exception.class)
public RoleDto findById(long id) {
Role role = roleRepository.findById(id).orElseGet(Role::new);
@ -163,7 +163,7 @@ public class RoleServiceImpl implements RoleService {
}
@Override
@Cacheable(key = "'auth:' + #p0.id")
@Cacheable(key = "'" + CacheKey.AUTH_KEY + ":' + #user.id")
public List<AuthorityDto> mapToGrantedAuthorities(UserDto user) {
Set<String> permissions = new HashSet<>();
// 如果是管理员直接返回
@ -215,10 +215,10 @@ public class RoleServiceImpl implements RoleService {
if (CollectionUtil.isNotEmpty(users)) {
users.forEach(item -> userCacheManager.cleanUserCache(item.getUsername()));
Set<Long> userIds = users.stream().map(User::getId).collect(Collectors.toSet());
redisUtils.delByKeys(CacheKey.DATA_USER, userIds);
redisUtils.delByKeys(CacheKey.MENU_USER, userIds);
redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds);
redisUtils.delByKeys(CacheKey.keyAndTarget(CacheKey.DATA_KEY, CacheKey.USER_KEY), userIds);
redisUtils.delByKeys(CacheKey.keyAndTarget(CacheKey.MENU_KEY, CacheKey.USER_KEY), userIds);
redisUtils.delByKeys(CacheKey.keyAndTarget(CacheKey.ROLE_KEY, CacheKey.AUTH_KEY), userIds);
}
redisUtils.del(CacheKey.ROLE_ID + id);
redisUtils.del(CacheKey.keyAndTarget(CacheKey.ROLE_KEY, CacheKey.ID) + id);
}
}

View File

@ -49,7 +49,7 @@ import java.util.stream.Collectors;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "user")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.USER_KEY)
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@ -73,7 +73,7 @@ public class UserServiceImpl implements UserService {
}
@Override
@Cacheable(key = "'id:' + #p0")
@Cacheable(key = "'" + CacheKey.ID + ":' + #id")
@Transactional(rollbackFor = Exception.class)
public UserDto findById(long id) {
User user = userRepository.findById(id).orElseGet(User::new);
@ -115,13 +115,13 @@ public class UserServiceImpl implements UserService {
}
// 如果用户的角色改变
if (!resources.getRoles().equals(user.getRoles())) {
redisUtils.del(CacheKey.DATA_USER + resources.getId());
redisUtils.del(CacheKey.MENU_USER + resources.getId());
redisUtils.del(CacheKey.ROLE_AUTH + resources.getId());
redisUtils.del(CacheKey.keyAndTarget(CacheKey.DATA_KEY, CacheKey.USER_KEY) + resources.getId());
redisUtils.del(CacheKey.keyAndTarget(CacheKey.MENU_KEY, CacheKey.USER_KEY) + resources.getId());
redisUtils.del(CacheKey.keyAndTarget(CacheKey.ROLE_KEY, CacheKey.AUTH_KEY) + resources.getId());
}
// 修改部门会影响 数据权限
if (!Objects.equals(resources.getDept(),user.getDept())) {
redisUtils.del(CacheKey.DATA_USER + resources.getId());
redisUtils.del(CacheKey.keyAndTarget(CacheKey.DATA_KEY, CacheKey.USER_KEY) + resources.getId());
}
// 如果用户被禁用,则清除用户登录信息
if(!resources.getEnabled()){
@ -255,7 +255,7 @@ public class UserServiceImpl implements UserService {
* @param id /
*/
public void delCaches(Long id, String username) {
redisUtils.del(CacheKey.USER_ID + id);
redisUtils.del(CacheKey.keyAndTarget(CacheKey.USER_KEY, CacheKey.ID) + id);
flushCache(username);
}

View File

@ -84,9 +84,9 @@ jwt:
# 令牌过期时间 此处单位/毫秒 默认4小时可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 14400000
# 在线用户key
online-key: online-token-
online-key: ONLINE-TOKEN-
# 验证码
code-key: code-key-
code-key: CODE-KEY-
# token 续期检查时间范围默认30分钟单位毫秒在token即将过期的一段时间内用户操作了则给用户的token续期
detect: 1800000
# 续期时间范围默认1小时单位毫秒

View File

@ -86,9 +86,9 @@ jwt:
# 令牌过期时间 此处单位/毫秒 默认2小时可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 7200000
# 在线用户key
online-key: online-token-
online-key: ONLINE-TOKEN-
# 验证码
code-key: code-key-
code-key: CODE-KEY-
# token 续期检查时间范围默认30分钟单位默认毫秒在token即将过期的一段时间内用户操作了则给用户的token续期
detect: 1800000
# 续期时间范围,默认 1小时这里单位毫秒

View File

@ -25,6 +25,7 @@ import me.zhengjie.domain.AlipayConfig;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.repository.AliPayRepository;
import me.zhengjie.service.AliPayService;
import me.zhengjie.utils.CacheKey;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
@ -38,20 +39,20 @@ import java.util.Optional;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "aliPay")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.ALI_PAY)
public class AliPayServiceImpl implements AliPayService {
private final AliPayRepository alipayRepository;
@Override
@Cacheable(key = "'config'")
@Cacheable(key = CacheKey.CONFIG)
public AlipayConfig find() {
Optional<AlipayConfig> alipayConfig = alipayRepository.findById(1L);
return alipayConfig.orElseGet(AlipayConfig::new);
}
@Override
@CachePut(key = "'config'")
@CachePut(key = CacheKey.CONFIG)
@Transactional(rollbackFor = Exception.class)
public AlipayConfig config(AlipayConfig alipayConfig) {
alipayConfig.setId(1L);

View File

@ -23,6 +23,7 @@ import me.zhengjie.domain.vo.EmailVo;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.repository.EmailRepository;
import me.zhengjie.service.EmailService;
import me.zhengjie.utils.CacheKey;
import me.zhengjie.utils.EncryptUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
@ -37,13 +38,13 @@ import java.util.Optional;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "email")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.EMAIL)
public class EmailServiceImpl implements EmailService {
private final EmailRepository emailRepository;
@Override
@CachePut(key = "'config'")
@CachePut(key = CacheKey.CONFIG)
@Transactional(rollbackFor = Exception.class)
public EmailConfig config(EmailConfig emailConfig, EmailConfig old) throws Exception {
emailConfig.setId(1L);
@ -55,7 +56,7 @@ public class EmailServiceImpl implements EmailService {
}
@Override
@Cacheable(key = "'config'")
@Cacheable(key = CacheKey.CONFIG)
public EmailConfig find() {
Optional<EmailConfig> emailConfig = emailRepository.findById(1L);
return emailConfig.orElseGet(EmailConfig::new);

View File

@ -29,14 +29,10 @@ import me.zhengjie.domain.QiniuConfig;
import me.zhengjie.domain.QiniuContent;
import me.zhengjie.repository.QiniuContentRepository;
import me.zhengjie.service.dto.QiniuQueryCriteria;
import me.zhengjie.utils.QiNiuUtil;
import me.zhengjie.utils.*;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.repository.QiNiuConfigRepository;
import me.zhengjie.service.QiNiuService;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import me.zhengjie.utils.ValidationUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
@ -55,7 +51,7 @@ import java.util.*;
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "qiNiu")
@CacheConfig(cacheNames = CacheKey.PROJECT + CacheKey.QI_NIU)
public class QiNiuServiceImpl implements QiNiuService {
private final QiNiuConfigRepository qiNiuConfigRepository;
@ -65,14 +61,14 @@ public class QiNiuServiceImpl implements QiNiuService {
private Long maxSize;
@Override
@Cacheable(key = "'config'")
@Cacheable(key = CacheKey.CONFIG)
public QiniuConfig find() {
Optional<QiniuConfig> qiniuConfig = qiNiuConfigRepository.findById(1L);
return qiniuConfig.orElseGet(QiniuConfig::new);
}
@Override
@CachePut(key = "'config'")
@CachePut(key = CacheKey.CONFIG)
@Transactional(rollbackFor = Exception.class)
public QiniuConfig config(QiniuConfig qiniuConfig) {
qiniuConfig.setId(1L);