From 509d57596f86f2e40c0dca36f8967879d84df246 Mon Sep 17 00:00:00 2001 From: dzq Date: Thu, 6 Nov 2025 10:28:05 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E7=BC=93=E5=AD=98):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84Caffeine=E7=BC=93=E5=AD=98=E6=A8=A1=E6=9D=BF=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构AbstractCaffeineCacheTemplate使其支持自定义过期和刷新时间配置 为不同业务场景的缓存实例配置合理的过期时间 --- .../common/cache/CaffeineCacheService.java | 30 ++++++-- .../AbstractCaffeineCacheTemplate.java | 71 +++++++++++++------ 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/common/cache/CaffeineCacheService.java b/agileboot-domain/src/main/java/com/agileboot/domain/common/cache/CaffeineCacheService.java index 4d118cd..4a9f1f1 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/common/cache/CaffeineCacheService.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/common/cache/CaffeineCacheService.java @@ -21,7 +21,10 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class CaffeineCacheService { - public AbstractCaffeineCacheTemplate captchaCache = new AbstractCaffeineCacheTemplate() { + // 验证码缓存:5分钟过期和刷新(验证码通常短时间内有效) + public AbstractCaffeineCacheTemplate captchaCache = new AbstractCaffeineCacheTemplate( + 5, java.util.concurrent.TimeUnit.MINUTES, + 5, java.util.concurrent.TimeUnit.MINUTES) { @Override public String getObjectFromDb(Object id) { // 验证码通常不需要从数据库获取,这里返回null @@ -29,7 +32,10 @@ public class CaffeineCacheService { } }; - public AbstractCaffeineCacheTemplate loginUserCache = new AbstractCaffeineCacheTemplate() { + // 登录用户缓存:1小时过期和刷新(登录态保持) + public AbstractCaffeineCacheTemplate loginUserCache = new AbstractCaffeineCacheTemplate( + 12, java.util.concurrent.TimeUnit.HOURS, + 12, java.util.concurrent.TimeUnit.HOURS) { @Override public SystemLoginUser getObjectFromDb(Object id) { // 登录用户信息通常不需要从数据库获取,这里返回null @@ -37,7 +43,10 @@ public class CaffeineCacheService { } }; - public AbstractCaffeineCacheTemplate userCache = new AbstractCaffeineCacheTemplate() { + // 用户信息缓存:2小时过期和刷新(用户信息相对稳定但可能更新) + public AbstractCaffeineCacheTemplate userCache = new AbstractCaffeineCacheTemplate( + 12, java.util.concurrent.TimeUnit.HOURS, + 12, java.util.concurrent.TimeUnit.HOURS) { @Override public SysUserEntity getObjectFromDb(Object id) { SysUserService userService = cn.hutool.extra.spring.SpringUtil.getBean(SysUserService.class); @@ -45,7 +54,10 @@ public class CaffeineCacheService { } }; - public AbstractCaffeineCacheTemplate roleCache = new AbstractCaffeineCacheTemplate() { + // 角色缓存:24小时过期和刷新(角色信息很少变更) + public AbstractCaffeineCacheTemplate roleCache = new AbstractCaffeineCacheTemplate( + 24, java.util.concurrent.TimeUnit.HOURS, + 24, java.util.concurrent.TimeUnit.HOURS) { @Override public SysRoleEntity getObjectFromDb(Object id) { SysRoleService roleService = cn.hutool.extra.spring.SpringUtil.getBean(SysRoleService.class); @@ -53,7 +65,10 @@ public class CaffeineCacheService { } }; - public AbstractCaffeineCacheTemplate postCache = new AbstractCaffeineCacheTemplate() { + // 岗位缓存:24小时过期和刷新(岗位信息很少变更) + public AbstractCaffeineCacheTemplate postCache = new AbstractCaffeineCacheTemplate( + 24, java.util.concurrent.TimeUnit.HOURS, + 24, java.util.concurrent.TimeUnit.HOURS) { @Override public SysPostEntity getObjectFromDb(Object id) { SysPostService postService = cn.hutool.extra.spring.SpringUtil.getBean(SysPostService.class); @@ -61,7 +76,10 @@ public class CaffeineCacheService { } }; - public AbstractCaffeineCacheTemplate qyUseridCache = new AbstractCaffeineCacheTemplate() { + // 企业微信用户ID缓存:6小时过期和刷新(通过API获取,有一定成本) + public AbstractCaffeineCacheTemplate qyUseridCache = new AbstractCaffeineCacheTemplate( + 12, java.util.concurrent.TimeUnit.HOURS, + 12, java.util.concurrent.TimeUnit.HOURS) { @Override public String getObjectFromDb(Object id) { // 企业微信用户ID需要通过API获取,这里返回null,由调用方处理 diff --git a/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/cache/caffeine/AbstractCaffeineCacheTemplate.java b/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/cache/caffeine/AbstractCaffeineCacheTemplate.java index 7d4730f..8a4a1e4 100644 --- a/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/cache/caffeine/AbstractCaffeineCacheTemplate.java +++ b/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/cache/caffeine/AbstractCaffeineCacheTemplate.java @@ -6,7 +6,6 @@ import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; import java.util.Optional; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; @@ -17,28 +16,53 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public abstract class AbstractCaffeineCacheTemplate { - private final LoadingCache> caffeineCache = Caffeine.newBuilder() - // 基于容量回收。缓存的最大数量 - .maximumSize(1024) - // 基于容量回收。但这是统计占用内存大小,maximumWeight与maximumSize不能同时使用 - // .maximumWeight(1000) - // 设置权重(可当成每个缓存占用的大小) - // .weigher((key, value) -> 1) - // 设置软引用值 - .softValues() - // 设置过期时间 - 最后一次写入后经过固定时间过期 - .expireAfterWrite(10, TimeUnit.HOURS) - // 设置刷新时间 - 写入后经过固定时间刷新 - .refreshAfterWrite(10, TimeUnit.HOURS) - // 所有segment的初始总容量大小 - .initialCapacity(128) - // 开启缓存统计 - .recordStats() - // 移除监听器 - .removalListener((key, value, cause) -> { - log.debug("触发删除动作,删除的key={}, 原因={}", key, cause); - }) - .build(new CacheLoader>() { + private final LoadingCache> caffeineCache; + + /** + * 默认构造函数,使用10小时的过期时间和刷新时间 + */ + public AbstractCaffeineCacheTemplate() { + this(10, TimeUnit.HOURS, 10, TimeUnit.HOURS); + } + + /** + * 构造函数,支持自定义过期时间和刷新时间 + * @param expireAfterWriteDuration 过期时间数值 + * @param expireAfterWriteUnit 过期时间单位 + * @param refreshAfterWriteDuration 刷新时间数值 + * @param refreshAfterWriteUnit 刷新时间单位 + */ + public AbstractCaffeineCacheTemplate(long expireAfterWriteDuration, TimeUnit expireAfterWriteUnit, + long refreshAfterWriteDuration, TimeUnit refreshAfterWriteUnit) { + Caffeine caffeineBuilder = Caffeine.newBuilder() + // 基于容量回收。缓存的最大数量 + .maximumSize(1024) + // 基于容量回收。但这是统计占用内存大小,maximumWeight与maximumSize不能同时使用 + // .maximumWeight(1000) + // 设置权重(可当成每个缓存占用的大小) + // .weigher((key, value) -> 1) + // 设置软引用值 + .softValues() + // 所有segment的初始总容量大小 + .initialCapacity(128) + // 开启缓存统计 + .recordStats() + // 移除监听器 + .removalListener((key, value, cause) -> { + log.debug("触发删除动作,删除的key={}, 原因={}", key, cause); + }); + + // 如果过期时间大于0,则设置过期策略 + if (expireAfterWriteDuration > 0) { + caffeineBuilder.expireAfterWrite(expireAfterWriteDuration, expireAfterWriteUnit); + } + + // 如果刷新时间大于0,则设置刷新策略 + if (refreshAfterWriteDuration > 0) { + caffeineBuilder.refreshAfterWrite(refreshAfterWriteDuration, refreshAfterWriteUnit); + } + + this.caffeineCache = caffeineBuilder.build(new CacheLoader>() { @Override public Optional load(String key) { T cacheObject = getObjectFromDb(key); @@ -55,6 +79,7 @@ public abstract class AbstractCaffeineCacheTemplate { }, executor); } }); + } /** * 从缓存中获取对象