feat(缓存): 添加Caffeine缓存管理接口及功能扩展
- 新增CaffeineController提供缓存查询、统计和清空功能 - 在AbstractCaffeineCacheTemplate中添加getAll和getAllWithOptional方法 - 更新.claude配置添加mvnw相关命令
This commit is contained in:
parent
a78da5cb59
commit
e41c7c27f5
|
|
@ -36,7 +36,8 @@
|
|||
"Bash(cat \"/e/code/智柜宝/shop-back-end/agileboot-domain/src/main/java/com/agileboot/domain/system/user/query/SearchUserQuery.java\")",
|
||||
"Bash(./mvnw clean compile -pl agileboot-api -am -DskipTests)",
|
||||
"Bash(./mvnw clean compile -pl agileboot-api,agileboot-domain -am -DskipTests)",
|
||||
"Bash(./mvnw clean compile -pl agileboot-domain -am -DskipTests)"
|
||||
"Bash(./mvnw clean compile -pl agileboot-domain -am -DskipTests)",
|
||||
"Bash(./mvnw:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
package com.agileboot.api.controller;
|
||||
|
||||
import com.agileboot.domain.common.cache.CaffeineCacheService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Caffeine缓存管理控制器
|
||||
* 提供缓存查询、统计、清空等管理功能
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/caffeine")
|
||||
@Tag(name = "Caffeine缓存管理", description = "Caffeine本地缓存查询和管理接口")
|
||||
@RequiredArgsConstructor
|
||||
public class CaffeineController {
|
||||
|
||||
@Autowired
|
||||
private CaffeineCacheService caffeineCacheService;
|
||||
|
||||
/**
|
||||
* 获取所有Caffeine缓存的统计信息
|
||||
*/
|
||||
@GetMapping("/stats")
|
||||
@Operation(summary = "获取缓存统计信息", description = "返回所有Caffeine缓存的详细统计信息")
|
||||
public ResponseEntity<String> getCacheStats() {
|
||||
try {
|
||||
String stats = caffeineCacheService.getCacheStats();
|
||||
return ResponseEntity.ok(stats);
|
||||
} catch (Exception e) {
|
||||
log.error("获取缓存统计信息失败", e);
|
||||
return ResponseEntity.internalServerError()
|
||||
.body("获取缓存统计信息失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空指定类型的缓存
|
||||
*
|
||||
* @param cacheName 缓存名称 (captchaCache, loginUserCache, userCache, roleCache, postCache, qyUseridCache, dynamicCodeCache)
|
||||
*/
|
||||
@DeleteMapping("/cache/{cacheName}")
|
||||
@Operation(summary = "清空指定缓存", description = "清空指定类型的Caffeine缓存")
|
||||
public ResponseEntity<String> clearCache(@PathVariable String cacheName) {
|
||||
try {
|
||||
switch (cacheName) {
|
||||
case "captchaCache":
|
||||
caffeineCacheService.captchaCache.invalidateAll();
|
||||
break;
|
||||
case "loginUserCache":
|
||||
caffeineCacheService.loginUserCache.invalidateAll();
|
||||
break;
|
||||
case "userCache":
|
||||
caffeineCacheService.userCache.invalidateAll();
|
||||
break;
|
||||
case "roleCache":
|
||||
caffeineCacheService.roleCache.invalidateAll();
|
||||
break;
|
||||
case "postCache":
|
||||
caffeineCacheService.postCache.invalidateAll();
|
||||
break;
|
||||
case "qyUseridCache":
|
||||
caffeineCacheService.qyUseridCache.invalidateAll();
|
||||
break;
|
||||
case "dynamicCodeCache":
|
||||
caffeineCacheService.dynamicCodeCache.invalidateAll();
|
||||
break;
|
||||
default:
|
||||
return ResponseEntity.badRequest()
|
||||
.body("未知的缓存类型: " + cacheName + ",支持的类型: captchaCache, loginUserCache, userCache, roleCache, postCache, qyUseridCache, dynamicCodeCache");
|
||||
}
|
||||
return ResponseEntity.ok("缓存 [" + cacheName + "] 已清空");
|
||||
} catch (Exception e) {
|
||||
log.error("清空缓存失败: {}", cacheName, e);
|
||||
return ResponseEntity.internalServerError()
|
||||
.body("清空缓存失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空所有Caffeine缓存
|
||||
*/
|
||||
@DeleteMapping("/cache")
|
||||
@Operation(summary = "清空所有缓存", description = "清空所有类型的Caffeine缓存")
|
||||
public ResponseEntity<String> clearAllCaches() {
|
||||
try {
|
||||
caffeineCacheService.captchaCache.invalidateAll();
|
||||
caffeineCacheService.loginUserCache.invalidateAll();
|
||||
caffeineCacheService.userCache.invalidateAll();
|
||||
caffeineCacheService.roleCache.invalidateAll();
|
||||
caffeineCacheService.postCache.invalidateAll();
|
||||
caffeineCacheService.qyUseridCache.invalidateAll();
|
||||
caffeineCacheService.dynamicCodeCache.invalidateAll();
|
||||
|
||||
return ResponseEntity.ok("所有Caffeine缓存已清空");
|
||||
} catch (Exception e) {
|
||||
log.error("清空所有缓存失败", e);
|
||||
return ResponseEntity.internalServerError()
|
||||
.body("清空所有缓存失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有缓存数据
|
||||
*/
|
||||
@GetMapping("/cache/all")
|
||||
@Operation(summary = "获取所有缓存数据", description = "获取所有Caffeine缓存中的数据")
|
||||
public ResponseEntity<?> getAllCacheData() {
|
||||
try {
|
||||
Map<String, Object> allCaches = new HashMap<>();
|
||||
allCaches.put("captchaCache", caffeineCacheService.captchaCache.getAll());
|
||||
allCaches.put("loginUserCache", caffeineCacheService.loginUserCache.getAll());
|
||||
allCaches.put("userCache", caffeineCacheService.userCache.getAll());
|
||||
allCaches.put("roleCache", caffeineCacheService.roleCache.getAll());
|
||||
allCaches.put("postCache", caffeineCacheService.postCache.getAll());
|
||||
allCaches.put("qyUseridCache", caffeineCacheService.qyUseridCache.getAll());
|
||||
allCaches.put("dynamicCodeCache", caffeineCacheService.dynamicCodeCache.getAll());
|
||||
|
||||
return ResponseEntity.ok(allCaches);
|
||||
} catch (Exception e) {
|
||||
log.error("获取所有缓存数据失败", e);
|
||||
return ResponseEntity.internalServerError()
|
||||
.body("获取所有缓存数据失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定缓存的数据
|
||||
*/
|
||||
@GetMapping("/cache/{cacheName}/data")
|
||||
@Operation(summary = "获取指定缓存数据", description = "获取指定类型的Caffeine缓存数据")
|
||||
public ResponseEntity<?> getCacheData(@PathVariable String cacheName) {
|
||||
try {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("cacheName", cacheName);
|
||||
|
||||
switch (cacheName) {
|
||||
case "captchaCache":
|
||||
result.put("data", caffeineCacheService.captchaCache.getAll());
|
||||
break;
|
||||
case "loginUserCache":
|
||||
result.put("data", caffeineCacheService.loginUserCache.getAll());
|
||||
break;
|
||||
case "userCache":
|
||||
result.put("data", caffeineCacheService.userCache.getAll());
|
||||
break;
|
||||
case "roleCache":
|
||||
result.put("data", caffeineCacheService.roleCache.getAll());
|
||||
break;
|
||||
case "postCache":
|
||||
result.put("data", caffeineCacheService.postCache.getAll());
|
||||
break;
|
||||
case "qyUseridCache":
|
||||
result.put("data", caffeineCacheService.qyUseridCache.getAll());
|
||||
break;
|
||||
case "dynamicCodeCache":
|
||||
result.put("data", caffeineCacheService.dynamicCodeCache.getAll());
|
||||
break;
|
||||
default:
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("error", "未知的缓存类型: " + cacheName,
|
||||
"supportedTypes", new String[]{
|
||||
"captchaCache", "loginUserCache", "userCache",
|
||||
"roleCache", "postCache", "qyUseridCache", "dynamicCodeCache"
|
||||
}));
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
log.error("获取缓存数据失败: {}", cacheName, e);
|
||||
return ResponseEntity.internalServerError()
|
||||
.body(Map.of("error", "获取缓存数据失败: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
|||
import com.github.benmanes.caffeine.cache.CacheLoader;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
|
@ -132,6 +133,37 @@ public abstract class AbstractCaffeineCacheTemplate<T> {
|
|||
return caffeineCache.stats().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中所有数据
|
||||
* @return 缓存中的所有数据(不包含值为null的条目)
|
||||
*/
|
||||
public java.util.Map<String, T> getAll() {
|
||||
try {
|
||||
return caffeineCache.asMap().entrySet().stream()
|
||||
.filter(entry -> entry.getValue().isPresent())
|
||||
.collect(java.util.stream.Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> entry.getValue().get()
|
||||
));
|
||||
} catch (Exception e) {
|
||||
log.error("获取Caffeine缓存所有数据失败", e);
|
||||
return new java.util.HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中所有数据(包括key和value)
|
||||
* @return 包含key和Optional<T>的Map
|
||||
*/
|
||||
public java.util.Map<String, Optional<T>> getAllWithOptional() {
|
||||
try {
|
||||
return new java.util.HashMap<>(caffeineCache.asMap());
|
||||
} catch (Exception e) {
|
||||
log.error("获取Caffeine缓存所有数据失败", e);
|
||||
return new java.util.HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库加载数据
|
||||
* @param id 数据ID
|
||||
|
|
|
|||
Loading…
Reference in New Issue