Skip to content

缓存(forge-starter-cache)

Forge 的缓存模块基于 受管注解缓存(Managed Annotation Cache) 与 Redis / Redisson 实现。它不是 Spring Cache 的 @Cacheable,而是自研的一套注解:@ForgeCacheable / @ForgeCachePut / @ForgeCacheEvict / @ForgeCacheConfig,由 AOP 拦截、支持多级存储(本地 + Redis)、按租户 / 用户身份隔离缓存键,并可在管理后台按「缓存名 + 应用」动态治理策略。

引入依赖

xml
<dependency>
    <groupId>com.mdframe.forge</groupId>
    <artifactId>forge-starter-cache</artifactId>
</dependency>

缓存注解

@ForgeCacheable

方法级,命中即返回缓存,未命中则回源并写入。

java
@ForgeCacheable(cacheName = "sys_user", key = "#userId")
public SysUser getById(Long userId) {
    return userMapper.selectById(userId);
}
属性必填说明
cacheName缓存名
keySpEL 表达式,如 #userId;留空则用全部方法入参

@ForgeCachePut

方法级,强制写入缓存(通常用于更新后回填)。

java
@ForgeCachePut(cacheName = "sys_user", key = "#user.userId")
public SysUser update(SysUser user) {
    userMapper.updateById(user);
    return user;
}

@ForgeCacheEvict

方法级,失效缓存。

java
// 失效指定键
@ForgeCacheEvict(cacheName = "sys_user", key = "#userId")
public void delete(Long userId) { ... }

// 全量失效
@ForgeCacheEvict(cacheName = "sys_user", allEntries = true)
public void clearAll() { ... }
属性必填说明
cacheName缓存名
keySpEL 表达式
allEntries是否全量失效,默认 false

@ForgeCacheConfig

类型级(@Inherited、可重复 @Repeatable),声明一个命名缓存的代码默认策略和不可变安全边界

java
@ForgeCacheConfig(
    name = "sys_user",
    description = "用户缓存",
    mode = CacheMode.REDIS,
    allowedModes = { CacheMode.LOCAL, CacheMode.REDIS, CacheMode.MULTI },
    scope = CacheScope.TENANT,
    redisTtlSeconds = 1800,
    localTtlSeconds = 60,
    localMaxSize = 1000,
    cacheNull = false,
    nullTtlSeconds = 30
)
@Service
public class SysUserService { ... }
属性默认值说明
name—(必填)缓存名
description""缓存描述
modeREDIS默认存储模式
allowedModesLOCAL/REDIS/MULTI代码声明的不可变安全边界,运行时不能越界
scopeTENANT缓存键身份隔离范围
redisTtlSeconds1800Redis TTL(秒)
localTtlSeconds60本地 TTL(秒)
localMaxSize1000本地缓存容量
cacheNullfalse是否缓存空值
nullTtlSeconds30空值 TTL(秒)

存储模式(CacheMode)

枚举说明
LOCAL仅本地缓存(单机)
REDIS仅 Redis
MULTI多级:本地 + Redis

身份隔离范围(CacheScope)

缓存键按可信身份隔离,避免跨租户 / 跨用户串数据:

枚举隔离维度
GLOBAL全局共享
TENANT按租户隔离
TENANT_USER按租户 + 用户隔离
TENANT_USER_ORG按租户 + 用户 + 组织隔离

缓存键生成规则

key 只对代码内可信的 SpEL 求值,最终写入 Redis 的 entry key 始终是 SHA-256 摘要,并由 CacheScope 的隔离材料拼接(如 tenant:1:user:2):

text
scope材料 + "|" + SpEL结果(JSON)  →  SHA-256 摘要

因此业务侧无需关心跨租户键冲突,也不建议直接手写 Redis key 与受管缓存混用。

编程式缓存(ICacheService)

除注解外,可注入 ICacheService 做命令式读写:

java
@Autowired
private ICacheService cacheService;

cacheService.set("user:1", user, 1, TimeUnit.HOURS);   // 设置并指定过期
SysUser user = cacheService.get("user:1", SysUser.class); // 读取
cacheService.setIfAbsent("user:1", user, 1, TimeUnit.HOURS); // 仅不存在时写入
cacheService.delete("user:1");                            // 删除

命令式接口不经过 @ForgeCacheConfig 的受管策略与身份隔离,适合工具类 / 临时缓存场景;业务主数据优先使用注解。

配置

配置前缀 forge.cache

配置默认值说明
forge.cache.annotation-enabledtrue是否启用注解拦截,关闭后业务方法全部穿透
forge.cache.application-codespring.application.name应用编码
forge.cache.namespaceforge:managed-cacheRedis 控制面与数据对象前缀
forge.cache.policy-refresh-seconds30Pub/Sub 丢失时重新校准策略快照的最小间隔

Redis / Redisson 基础连接沿用标准配置:

yaml
spring:
  data:
    redis:
      host: localhost
      port: 6379
      password:
      database: 0

运行时策略治理

受管缓存的运行策略(模式、TTL、容量、空值缓存)存放于 sys_cache_policy 表,可在管理后台 平台管理 → 运维监控 → 缓存监控 中按「应用编码 + 缓存名」在线编辑、重置、清空;allowedModes 仍是代码声明的不可变边界。详细说明见受管注解缓存

注意事项

  1. key 只支持 SpEL,且只对方法入参 / #result 求值,不要写外部表达式。
  2. allowedModes 是代码不可变安全边界,运行策略不能越界改模式。
  3. 更新数据时用 @ForgeCachePut 回填或 @ForgeCacheEvict 失效,避免脏读。
  4. 合理设置 TTL 与 cacheNull,规避穿透、击穿、雪崩。

Forge Admin — 基于 Vue3 + Spring Boot 的企业级后台管理框架