找工作,来万码优才: #小程序://万码优才/r6rqmzDaXpYkJZF
对于Java的基本知识推荐阅读:
@Cacheable
是 Spring 提供的注解,用于声明一个方法的返回结果会被缓存
当方法被调用时,Spring 会先检查缓存中是否存在该方法的结果
如果缓存存在,则直接返回缓存结果;如果不存在,则执行该方法并将返回值存入缓存
具体的一个参数说明如下:
value
缓存的名称或命名空间
必填参数,值通常是一个字符串数组
示例:@Cacheable(value = "userCache")
表示将数据缓存到 userCache 中
key
缓存的键,用于唯一标识一个缓存数据
默认:使用方法的所有参数作为键
支持 Spring 表达式语言(SpEL)
示例:@Cacheable(key = "#id")
表示缓存以参数 id 的值作为键
condition
一个 SpEL 表达式,用于指定是否启用缓存
如果表达式返回 false,方法将不会缓存结果
示例:@Cacheable(condition = "#id > 10")
表示只有当 id > 10 时才会缓存
unless
一个 SpEL 表达式,用于在缓存结果后判断是否移除缓存
示例:@Cacheable(unless = "#result.size() > 10")
表示如果返回值的大小超过 10,则不会缓存
sync
是否启用同步缓存
如果为 true,多个线程同时请求一个未缓存的键时,只有一个线程会执行方法,其余线程等待缓存结果
默认:false
总体来说,常见的场景如下:
场景 | 应用意义 |
---|---|
避免重复查询数据库 | 如果缓存中已存在数据,避免重复调用方法,从而减少数据库查询压力,提升系统性能 |
避免缓存无效数据 | 使用 unless 条件避免缓存 null 值,防止缓存无效数据导致后续业务逻辑异常 |
按需加载 | 方法首次调用时执行数据库查询,随后结果会被缓存,后续相同参数的调用直接使用缓存数据,无需重复查询 |
挑选实战中的Demo来解释
@Override
@Cacheable(value = "drag:cache:page", key = "#name", condition = "false")
public Cache getCache(String name) {
// 如果开启多租户,则 name 拼接租户后缀
if (!TenantContextHolder.isIgnore()
&& TenantContextHolder.getTenantId() != null) {
name = name + ":" + TenantContextHolder.getTenantId();
}
// 继续基于父方法
return super.getCache(name);
}
解释如下:
@Cacheable
注解
value:使用缓存命名空间 drag:cache:page
key:使用方法参数 name 作为缓存键
condition:始终为 false,因此结果不会被缓存
多租户逻辑
检查是否开启了多租户功能,并根据租户 ID 动态调整缓存键
这样可以为不同租户分别缓存数据,避免冲突
父类调用
如果缓存未命中,则通过 super.getCache(name) 调用父类方法获取结果
另外的Demo解答:
@Override
@Cacheable(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#id", unless = "#result == null")
public MailAccountDO getMailAccountFromCache(Long id) {
return getMailAccount(id);
}
部分 | 解释 |
---|---|
@Override | 标注这是重写父类或接口中的方法,确保方法签名一致 |
@Cacheable | Spring 的缓存注解,用于指定方法的返回值是否被缓存。每次调用该方法时,Spring 会检查缓存中是否存在对应的值,如果存在直接返回,否则执行方法并将结果存入缓存 |
value = RedisKeyConstants.MAIL_ACCOUNT | 指定缓存的命名空间。这里用常量 RedisKeyConstants.MAIL_ACCOUNT 表示缓存的具体名称,通常为 Redis 中的某个 key 的前缀,方便管理和排查 |
key = “#id” | 指定缓存的键,以方法参数 id 的值为键。#id 是 SpEL(Spring Expression Language)表达式,表示方法参数 id |
unless = “#result == null” | 条件表达式,表示除非方法返回值为 null,否则将结果缓存。如果返回值为 null,则不缓存,避免缓存无效数据 |