修复缓存实现配置为 redis 时抛异常的问题

This commit is contained in:
zhoumingfa 2025-03-28 20:57:48 +08:00
parent 580a783d25
commit a6607c063b
16 changed files with 360 additions and 32 deletions

View File

@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
@ -19,7 +21,10 @@ import java.time.LocalDateTime;
*/ */
@Data @Data
@TableName("t_category") @TableName("t_category")
public class CategoryEntity { public class CategoryEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long categoryId; private Long categoryId;

View File

@ -3,6 +3,8 @@ package net.lab1024.sa.admin.module.business.category.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
@ -15,7 +17,10 @@ import java.util.List;
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Data @Data
public class CategoryTreeVO { public class CategoryTreeVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "类目id") @Schema(description = "类目id")
private Long categoryId; private Long categoryId;

View File

@ -3,6 +3,8 @@ package net.lab1024.sa.admin.module.system.department.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
@ -15,7 +17,10 @@ import java.time.LocalDateTime;
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Data @Data
public class DepartmentVO { public class DepartmentVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "部门id") @Schema(description = "部门id")
private Long departmentId; private Long departmentId;

View File

@ -7,7 +7,7 @@ import jakarta.annotation.Resource;
import net.lab1024.sa.base.common.controller.SupportBaseController; import net.lab1024.sa.base.common.controller.SupportBaseController;
import net.lab1024.sa.base.common.domain.ResponseDTO; import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.constant.SwaggerTagConst; import net.lab1024.sa.base.constant.SwaggerTagConst;
import net.lab1024.sa.base.module.support.cache.CacheService; import net.lab1024.sa.base.module.support.cache.service.CacheService;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@ -0,0 +1,35 @@
package net.lab1024.sa.base.module.support.cache.config;
import net.lab1024.sa.base.module.support.cache.service.CacheService;
import net.lab1024.sa.base.module.support.cache.service.CaffeineCacheServiceImpl;
import net.lab1024.sa.base.module.support.cache.service.RedisCacheServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 缓存配置
*
* @author zhoumingfa
* @date 2025/03/28
*/
@Configuration
public class CacheConfig {
private static final String REDIS_CACHE = "redis";
private static final String CAFFEINE_CACHE = "caffeine";
@Bean
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
public CacheService redisCacheService() {
return new RedisCacheServiceImpl();
}
@Bean
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = CAFFEINE_CACHE)
public CacheService caffeineCacheService() {
return new CaffeineCacheServiceImpl();
}
}

View File

@ -0,0 +1,34 @@
package net.lab1024.sa.base.module.support.cache.service;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 缓存服务
*
* @Author 1024创新实验室: 罗伊
* @Date 2021/10/11 20:07
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Service
public interface CacheService {
/**
* 获取所有缓存名称
*/
List<String> cacheNames();
/**
* 某个缓存下的所有 key
*/
List<String> cacheKey(String cacheName);
/**
* 移除某个 key
*/
void removeCache(String cacheName);
}

View File

@ -1,4 +1,4 @@
package net.lab1024.sa.base.module.support.cache; package net.lab1024.sa.base.module.support.cache.service;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -6,7 +6,6 @@ import net.lab1024.sa.base.constant.ReloadConst;
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload; import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
import org.springframework.cache.caffeine.CaffeineCache; import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -14,32 +13,31 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* 缓存操作 * caffeine 缓存实现
* *
* @Author 1024创新实验室: 罗伊 * @Author 1024创新实验室: 罗伊
* @Date 2021/10/11 20:07 * @Date 2021/10/11 20:07
* @Wechat zhuoda1024 * @Wechat zhuoda1024
* @Email lab1024@163.com * @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Service public class CaffeineCacheServiceImpl implements CacheService {
public class CacheService {
@Resource @Resource
private CaffeineCacheManager caffeineCacheManager; private CaffeineCacheManager caffeineCacheManager;
/** /**
* 获取所有缓存名称 * 获取所有缓存名称
*
*/ */
@Override
public List<String> cacheNames() { public List<String> cacheNames() {
return Lists.newArrayList(caffeineCacheManager.getCacheNames()); return Lists.newArrayList(caffeineCacheManager.getCacheNames());
} }
/** /**
* 某个缓存下的所有key * 某个缓存下的所有 key
*
*/ */
@Override
public List<String> cacheKey(String cacheName) { public List<String> cacheKey(String cacheName) {
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
if (cache == null) { if (cache == null) {
@ -50,10 +48,9 @@ public class CacheService {
} }
/** /**
* 移除某个key * 移除某个 key
*
*/ */
@Override
public void removeCache(String cacheName) { public void removeCache(String cacheName) {
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
if (cache != null) { if (cache != null) {

View File

@ -0,0 +1,86 @@
package net.lab1024.sa.base.module.support.cache.service;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import net.lab1024.sa.base.constant.ReloadConst;
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* redis 缓存实现
*
* @author zhoumingfa
* @date 2025/3/28
*/
public class RedisCacheServiceImpl implements CacheService {
@Resource
private RedisCacheManager redisCacheManager;
@Resource
private RedisConnectionFactory redisConnectionFactory;
/**
* 获取所有缓存名称
*/
@Override
public List<String> cacheNames() {
return Lists.newArrayList(redisCacheManager.getCacheNames());
}
/**
* 某个缓存下的所有 key
*/
@Override
public List<String> cacheKey(String cacheName) {
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
if (cache == null) {
return Lists.newArrayList();
}
// 获取 Redis 连接
RedisConnection connection = redisConnectionFactory.getConnection();
// 根据指定的 key 模式获取所有匹配的键
Set<byte[]> keys = connection.keyCommands().keys((cacheName + ":*").getBytes());
if (keys != null) {
return keys.stream().map(key -> {
String redisKey = StrUtil.str(key, "utf-8");
// Redis 键中提取出最后一个冒号后面的字符串作为真正的键
return redisKey.substring(redisKey.lastIndexOf(":") + 1);
}).collect(Collectors.toList());
}
connection.close();
return Lists.newArrayList(cacheName);
}
/**
* 移除某个 key
*/
@Override
public void removeCache(String cacheName) {
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
if (cache != null) {
cache.clear();
}
}
@SmartReload(ReloadConst.CACHE_SERVICE)
public void clearAllCache() {
Collection<String> cacheNames = redisCacheManager.getCacheNames();
for (String name : cacheNames) {
RedisCache cache = (RedisCache) redisCacheManager.getCache(name);
if (cache != null) {
cache.clear();
}
}
}
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
@ -19,7 +20,9 @@ import java.time.LocalDateTime;
*/ */
@Data @Data
@TableName("t_category") @TableName("t_category")
public class CategoryEntity { public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long categoryId; private Long categoryId;

View File

@ -3,6 +3,7 @@ package net.lab1024.sa.admin.module.business.category.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
@ -15,7 +16,9 @@ import java.util.List;
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Data @Data
public class CategoryTreeVO { public class CategoryTreeVO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "类目id") @Schema(description = "类目id")
private Long categoryId; private Long categoryId;

View File

@ -3,6 +3,7 @@ package net.lab1024.sa.admin.module.system.department.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
@ -15,7 +16,9 @@ import java.time.LocalDateTime;
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Data @Data
public class DepartmentVO { public class DepartmentVO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "部门id") @Schema(description = "部门id")
private Long departmentId; private Long departmentId;

View File

@ -6,7 +6,7 @@ import io.swagger.v3.oas.annotations.Operation;
import net.lab1024.sa.base.common.controller.SupportBaseController; import net.lab1024.sa.base.common.controller.SupportBaseController;
import net.lab1024.sa.base.common.domain.ResponseDTO; import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.constant.SwaggerTagConst; import net.lab1024.sa.base.constant.SwaggerTagConst;
import net.lab1024.sa.base.module.support.cache.CacheService; import net.lab1024.sa.base.module.support.cache.cache.service.CacheService;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@ -0,0 +1,35 @@
package net.lab1024.sa.base.module.support.cache.cache.config;
import net.lab1024.sa.base.module.support.cache.cache.service.CacheService;
import net.lab1024.sa.base.module.support.cache.cache.service.CaffeineCacheServiceImpl;
import net.lab1024.sa.base.module.support.cache.cache.service.RedisCacheServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 缓存配置
*
* @author zhoumingfa
* @date 2025/03/28
*/
@Configuration
public class CacheConfig {
private static final String REDIS_CACHE = "redis";
private static final String CAFFEINE_CACHE = "caffeine";
@Bean
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
public CacheService redisCacheService() {
return new RedisCacheServiceImpl();
}
@Bean
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = CAFFEINE_CACHE)
public CacheService caffeineCacheService() {
return new CaffeineCacheServiceImpl();
}
}

View File

@ -0,0 +1,34 @@
package net.lab1024.sa.base.module.support.cache.cache.service;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 缓存服务
*
* @Author 1024创新实验室: 罗伊
* @Date 2021/10/11 20:07
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Service
public interface CacheService {
/**
* 获取所有缓存名称
*/
List<String> cacheNames();
/**
* 某个缓存下的所有 key
*/
List<String> cacheKey(String cacheName);
/**
* 移除某个 key
*/
void removeCache(String cacheName);
}

View File

@ -1,11 +1,10 @@
package net.lab1024.sa.base.module.support.cache; package net.lab1024.sa.base.module.support.cache.cache.service;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.lab1024.sa.base.constant.ReloadConst; import net.lab1024.sa.base.constant.ReloadConst;
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload; import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
import org.springframework.cache.caffeine.CaffeineCache; import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection; import java.util.Collection;
@ -14,32 +13,31 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* 缓存操作 * caffeine 缓存实现
* *
* @Author 1024创新实验室: 罗伊 * @Author 1024创新实验室: 罗伊
* @Date 2021/10/11 20:07 * @Date 2021/10/11 20:07
* @Wechat zhuoda1024 * @Wechat zhuoda1024
* @Email lab1024@163.com * @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Service public class CaffeineCacheServiceImpl implements CacheService {
public class CacheService {
@Resource @Resource
private CaffeineCacheManager caffeineCacheManager; private CaffeineCacheManager caffeineCacheManager;
/** /**
* 获取所有缓存名称 * 获取所有缓存名称
*
*/ */
@Override
public List<String> cacheNames() { public List<String> cacheNames() {
return Lists.newArrayList(caffeineCacheManager.getCacheNames()); return Lists.newArrayList(caffeineCacheManager.getCacheNames());
} }
/** /**
* 某个缓存下的所有key * 某个缓存下的所有 key
*
*/ */
@Override
public List<String> cacheKey(String cacheName) { public List<String> cacheKey(String cacheName) {
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
if (cache == null) { if (cache == null) {
@ -50,10 +48,9 @@ public class CacheService {
} }
/** /**
* 移除某个key * 移除某个 key
*
*/ */
@Override
public void removeCache(String cacheName) { public void removeCache(String cacheName) {
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
if (cache != null) { if (cache != null) {

View File

@ -0,0 +1,86 @@
package net.lab1024.sa.base.module.support.cache.cache.service;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import net.lab1024.sa.base.constant.ReloadConst;
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* redis 缓存实现
*
* @author zhoumingfa
* @date 2025/3/28
*/
public class RedisCacheServiceImpl implements CacheService {
@Resource
private RedisCacheManager redisCacheManager;
@Resource
private RedisConnectionFactory redisConnectionFactory;
/**
* 获取所有缓存名称
*/
@Override
public List<String> cacheNames() {
return Lists.newArrayList(redisCacheManager.getCacheNames());
}
/**
* 某个缓存下的所有 key
*/
@Override
public List<String> cacheKey(String cacheName) {
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
if (cache == null) {
return Lists.newArrayList();
}
// 获取 Redis 连接
RedisConnection connection = redisConnectionFactory.getConnection();
// 根据指定的 key 模式获取所有匹配的键
Set<byte[]> keys = connection.keyCommands().keys((cacheName + ":*").getBytes());
if (keys != null) {
return keys.stream().map(key -> {
String redisKey = StrUtil.str(key, "utf-8");
// Redis 键中提取出最后一个冒号后面的字符串作为真正的键
return redisKey.substring(redisKey.lastIndexOf(":") + 1);
}).collect(Collectors.toList());
}
connection.close();
return Lists.newArrayList(cacheName);
}
/**
* 移除某个 key
*/
@Override
public void removeCache(String cacheName) {
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
if (cache != null) {
cache.clear();
}
}
@SmartReload(ReloadConst.CACHE_SERVICE)
public void clearAllCache() {
Collection<String> cacheNames = redisCacheManager.getCacheNames();
for (String name : cacheNames) {
RedisCache cache = (RedisCache) redisCacheManager.getCache(name);
if (cache != null) {
cache.clear();
}
}
}
}