refactor(cache): 缓存操作接口化,支持 Redis/Caffeine 双实现切换

将系统所有缓存操作从 `RedisUtil` 迁移至 `CacheOperations` 接口,
通过 `gym.cache.type` 配置选择 Redis 或 Caffeine 实现。

变更内容:
- 新增 CacheOperations 接口,定义 get/set/delete/hasKey/expire/deleteByPattern 等标准方法
- 新增 RedisCacheOperations 实现(基于 ReactiveRedisTemplate,默认实现)
- 新增 CaffeineCacheOperations 实现(基于 Caffeine 本地缓存)
- 新增 CacheProperties 配置类,支持 Caffeine 容量/过期等参数配置
- 新增 CacheAutoConfiguration 自动装配,通过 AutoConfiguration.imports 注册
- 全系统 17 个业务服务 + 18 个测试文件从 RedisUtil 迁移至 CacheOperations
- manage-gateway 配置 caffeine 实现(无需 Redis),manage-app 配置 redis 实现
- 分布式锁等 Redis 独有特性保持直接使用 ReactiveRedisTemplate

测试:202 通过,0 失败,0 错误
This commit was merged in pull request #56.
This commit is contained in:
2026-08-02 18:26:15 +08:00
parent eb33755f23
commit 4ba4af2f53
45 changed files with 798 additions and 476 deletions
@@ -1,6 +1,6 @@
package cn.novalon.gym.manage.payment.service.impl;
import cn.novalon.gym.manage.common.util.RedisUtil;
import cn.novalon.gym.manage.common.cache.CacheOperations;
import cn.novalon.gym.manage.payment.config.HuifuProperties;
import cn.novalon.gym.manage.payment.dto.CreatePaymentRequest;
import cn.novalon.gym.manage.payment.dto.PaymentResponse;
@@ -46,16 +46,16 @@ public class PaymentServiceImpl implements PaymentService {
private final HuifuProperties huifuProperties;
private final PaymentOrderRepository paymentOrderRepository;
private final RedisUtil redisUtil;
private final CacheOperations cacheOperations;
private final PaymentNotifyService paymentNotifyService;
public PaymentServiceImpl(HuifuProperties huifuProperties,
PaymentOrderRepository paymentOrderRepository,
RedisUtil redisUtil,
CacheOperations cacheOperations,
PaymentNotifyService paymentNotifyService) {
this.huifuProperties = huifuProperties;
this.paymentOrderRepository = paymentOrderRepository;
this.redisUtil = redisUtil;
this.cacheOperations = cacheOperations;
this.paymentNotifyService = paymentNotifyService;
}
@@ -860,7 +860,7 @@ public class PaymentServiceImpl implements PaymentService {
}
private Mono<Boolean> isTradeProcessed(String reqSeqId) {
return redisUtil.hasKey(PROCESSED_TRADE_PREFIX + reqSeqId)
return cacheOperations.hasKey(PROCESSED_TRADE_PREFIX + reqSeqId)
.onErrorResume(e -> {
log.error("[Huifu] 检查交易处理状态异常: reqSeqId={}", reqSeqId, e);
return Mono.just(false);
@@ -868,7 +868,7 @@ public class PaymentServiceImpl implements PaymentService {
}
private Mono<Void> markTradeProcessed(String reqSeqId) {
return redisUtil.setWithExpire(PROCESSED_TRADE_PREFIX + reqSeqId, "1", IDEMPOTENT_EXPIRE_SECONDS)
return cacheOperations.setWithExpire(PROCESSED_TRADE_PREFIX + reqSeqId, "1", IDEMPOTENT_EXPIRE_SECONDS)
.onErrorResume(e -> {
log.error("[Huifu] 标记交易处理状态异常: reqSeqId={}", reqSeqId, e);
return Mono.empty();
@@ -1,6 +1,6 @@
package cn.novalon.gym.manage.payment.service.impl;
import cn.novalon.gym.manage.common.util.RedisUtil;
import cn.novalon.gym.manage.common.cache.CacheOperations;
import cn.novalon.gym.manage.payment.config.HuifuProperties;
import cn.novalon.gym.manage.payment.dto.CreatePaymentRequest;
import cn.novalon.gym.manage.payment.dto.PaymentResponse;
@@ -35,7 +35,7 @@ class PaymentServiceImplTest {
private PaymentOrderRepository paymentOrderRepository;
@Mock
private RedisUtil redisUtil;
private CacheOperations cacheOperations;
@Mock
private PaymentNotifyService paymentNotifyService;
@@ -58,7 +58,7 @@ class PaymentServiceImplTest {
lenient().when(huifuProperties.isSdkInitialized()).thenReturn(false);
paymentService = new PaymentServiceImpl(huifuProperties, paymentOrderRepository, redisUtil, paymentNotifyService);
paymentService = new PaymentServiceImpl(huifuProperties, paymentOrderRepository, cacheOperations, paymentNotifyService);
}
private PaymentOrder createTestOrder(String status) {
@@ -369,7 +369,7 @@ class PaymentServiceImplTest {
params.put("resp_data", "{\"req_seq_id\":\"REQ123\",\"hf_seq_id\":\"HF123\",\"trans_stat\":\"S\"}");
params.put("sign", "testSign");
when(redisUtil.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(true));
when(cacheOperations.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(true));
Mono<String> result = paymentService.handleAlipayNotify(params);
@@ -388,10 +388,10 @@ class PaymentServiceImplTest {
PaymentOrder order = createTestOrder("PENDING");
when(redisUtil.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(cacheOperations.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(paymentOrderRepository.findByReqSeqId("REQ123")).thenReturn(Mono.just(order));
when(paymentOrderRepository.save(any(PaymentOrder.class))).thenReturn(Mono.just(order));
when(redisUtil.setWithExpire("huifu:processed:trade:REQ123", "1", 86400)).thenReturn(Mono.just(true));
when(cacheOperations.setWithExpire("huifu:processed:trade:REQ123", "1", 86400)).thenReturn(Mono.just(true));
when(paymentNotifyService.notifyPaymentStatus(order.getOrderNo(), "SUCCESS", MEMBER_ID)).thenReturn(Mono.empty());
Mono<String> result = paymentService.handleAlipayNotify(params);
@@ -401,7 +401,7 @@ class PaymentServiceImplTest {
.verifyComplete();
verify(paymentOrderRepository).save(any(PaymentOrder.class));
verify(redisUtil).setWithExpire("huifu:processed:trade:REQ123", "1", 86400);
verify(cacheOperations).setWithExpire("huifu:processed:trade:REQ123", "1", 86400);
verify(paymentNotifyService).notifyPaymentStatus(order.getOrderNo(), "SUCCESS", MEMBER_ID);
}
@@ -413,10 +413,10 @@ class PaymentServiceImplTest {
PaymentOrder order = createTestOrder("PENDING");
when(redisUtil.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(cacheOperations.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(paymentOrderRepository.findByReqSeqId("REQ123")).thenReturn(Mono.just(order));
when(paymentOrderRepository.save(any(PaymentOrder.class))).thenReturn(Mono.just(order));
when(redisUtil.setWithExpire("huifu:processed:trade:REQ123", "1", 86400)).thenReturn(Mono.just(true));
when(cacheOperations.setWithExpire("huifu:processed:trade:REQ123", "1", 86400)).thenReturn(Mono.just(true));
when(paymentNotifyService.notifyPaymentStatus(order.getOrderNo(), "FAIL", MEMBER_ID)).thenReturn(Mono.empty());
Mono<String> result = paymentService.handleAlipayNotify(params);
@@ -426,7 +426,7 @@ class PaymentServiceImplTest {
.verifyComplete();
verify(paymentOrderRepository).save(any(PaymentOrder.class));
verify(redisUtil).setWithExpire("huifu:processed:trade:REQ123", "1", 86400);
verify(cacheOperations).setWithExpire("huifu:processed:trade:REQ123", "1", 86400);
verify(paymentNotifyService).notifyPaymentStatus(order.getOrderNo(), "FAIL", MEMBER_ID);
}
@@ -438,7 +438,7 @@ class PaymentServiceImplTest {
PaymentOrder order = createTestOrder("PENDING");
when(redisUtil.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(cacheOperations.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(paymentOrderRepository.findByReqSeqId("REQ123")).thenReturn(Mono.just(order));
when(paymentNotifyService.notifyPaymentStatus(order.getOrderNo(), "PENDING", MEMBER_ID)).thenReturn(Mono.empty());
@@ -458,7 +458,7 @@ class PaymentServiceImplTest {
params.put("resp_data", "{\"req_seq_id\":\"REQ123\",\"hf_seq_id\":\"HF123\",\"trans_stat\":\"S\"}");
params.put("sign", "testSign");
when(redisUtil.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(cacheOperations.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(paymentOrderRepository.findByReqSeqId("REQ123")).thenReturn(Mono.empty());
Mono<String> result = paymentService.handleAlipayNotify(params);
@@ -474,7 +474,7 @@ class PaymentServiceImplTest {
params.put("resp_data", "{\"req_seq_id\":\"REQ123\",\"hf_seq_id\":\"HF123\",\"trans_stat\":\"S\"}");
params.put("sign", "testSign");
when(redisUtil.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(cacheOperations.hasKey("huifu:processed:trade:REQ123")).thenReturn(Mono.just(false));
when(paymentOrderRepository.findByReqSeqId("REQ123")).thenReturn(Mono.error(new RuntimeException("DB error")));
Mono<String> result = paymentService.handleAlipayNotify(params);