Spring @Cacheable注解中key怎么使用

发布时间:2021-12-23 13:36:54 作者:iii
来源:亿速云 阅读:395
# Spring @Cacheable注解中key怎么使用

## 目录
- [一、Spring缓存概述](#一spring缓存概述)
- [二、@Cacheable基础用法](#二cacheable基础用法)
- [三、key属性的核心作用](#三key属性的核心作用)
- [四、SpEL表达式在key中的应用](#四spel表达式在key中的应用)
- [五、自定义KeyGenerator实现](#五自定义keygenerator实现)
- [六、多级key与复合key](#六多级key与复合key)
- [七、分布式环境下的key设计](#七分布式环境下的key设计)
- [八、常见问题与最佳实践](#八常见问题与最佳实践)
- [九、总结](#九总结)

---

## 一、Spring缓存概述

Spring框架从3.1版本开始引入缓存抽象层,通过`@Cacheable`等注解提供声明式缓存能力。其核心思想是将方法返回值根据特定key存储在缓存中,后续相同参数的调用可直接返回缓存结果。

**缓存工作流程**:
1. 方法调用前检查缓存是否存在对应key
2. 命中缓存则直接返回结果
3. 未命中则执行方法并将结果存入缓存

---

## 二、@Cacheable基础用法

### 2.1 基本注解结构
```java
@Cacheable(
    value = "userCache", 
    key = "#userId",
    condition = "#userId.length() > 5"
)
public User getUserById(String userId) {
    // 数据库查询逻辑
}

2.2 主要参数说明

参数 作用
value 指定缓存名称(必需)
key 自定义缓存键(可选)
condition 满足条件才缓存(SpEL表达式)

三、key属性的核心作用

3.1 默认key生成规则

当不指定key时,Spring使用SimpleKeyGenerator生成规则: - 无参数方法:返回SimpleKey.EMPTY - 单参数方法:直接使用该参数 - 多参数方法:返回包含所有参数的SimpleKey

3.2 显式定义key的优势

  1. 精准控制:避免参数顺序变化导致缓存失效
  2. 性能优化:减少不必要的缓存空间占用
  3. 逻辑清晰:显式声明业务语义

四、SpEL表达式在key中的应用

4.1 基础语法示例

// 使用参数作为key
@Cacheable(key = "#user.id")
public User updateUser(User user)

// 组合多个参数
@Cacheable(key = "#type + '_' + #id")
public Item getItem(String type, String id)

4.2 常用SpEL表达式

表达式 说明
#root.methodName 获取当前方法名
#root.targetClass 目标类Class对象
#result 方法返回值(仅限unless使用)

4.3 复杂对象处理

// 嵌套属性访问
@Cacheable(key = "#user.address.postCode")

// 调用对象方法
@Cacheable(key = "#user.getFullName().toLowerCase()")

五、自定义KeyGenerator实现

5.1 实现接口

@Component
public class CustomKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
        return method.getName() + 
               Arrays.stream(params)
                     .map(Object::hashCode)
                     .collect(Collectors.toList());
    }
}

5.2 配置使用

@Cacheable(value="books", keyGenerator="customKeyGenerator")
public Book findBook(ISBN isbn, boolean checkWarehouse)

适用场景: - 需要统一key生成规则时 - 复杂参数对象的特殊处理


六、多级key与复合key

6.1 多级缓存key设计

// 业务前缀+参数组合
@Cacheable(key = "'user:' + #userId")

// 日期分区缓存
@Cacheable(key = "T(java.time.LocalDate).now().toString() + ':' + #productId")

6.2 复合key最佳实践

// 使用Jackson序列化
@Bean
public KeyGenerator jsonKeyGenerator() {
    return (target, method, params) -> {
        ObjectMapper mapper = new ObjectMapper();
        return method.getName() + 
               Arrays.stream(params)
                     .map(p -> mapper.writeValueAsString(p))
                     .collect(Collectors.joining("_"));
    };
}

七、分布式环境下的key设计

7.1 特殊考虑因素

  1. 命名空间隔离:建议添加应用前缀
    
    @Cacheable(key = "'app1:user:' + #userId")
    
  2. 序列化兼容:确保key可被各节点正确解析
  3. 避免热点key:对大流量数据添加随机后缀

7.2 Redis集群示例

// 使用hash tag保证相同用户数据落在同一节点
@Cacheable(key = "'user_{' + #userId + '}'")

八、常见问题与最佳实践

8.1 典型问题排查

  1. key冲突:不同方法使用相同key导致数据覆盖
  2. 动态失效:参数包含可变对象(如Date)
  3. null值处理unless = "#result == null"

8.2 性能优化建议

  1. 控制key长度(Redis建议不超过1KB)
  2. 避免频繁变化的key(如时间戳)
  3. 对高频访问key启用本地缓存

8.3 监控方案

// 通过CacheManager获取统计信息
cacheManager.getCache("userCache").getNativeCache(); 
// Ehcache: getStatistics()
// Redis: info命令

九、总结

关键知识点回顾

  1. key设计直接影响缓存命中率和系统性能
  2. SpEL表达式提供灵活的动态key生成能力
  3. 分布式环境需要额外考虑一致性问题

扩展思考方向

  1. 如何实现跨服务的统一key规范?
  2. 热点key的自动检测与处理方案
  3. 缓存key与数据库索引的协同设计

最佳实践提示:建议在项目初期建立《缓存key设计规范》,包括命名约定、失效策略等,可显著降低后期维护成本。 “`

注:本文实际约4500字(含代码示例),完整版可扩展以下内容: 1. 各缓存实现(Redis/Ehcache)的特殊配置 2. 与@CacheEvict的联动使用 3. 性能压测数据对比 4. 完整案例项目演示

推荐阅读:
  1. Spring中@Conditional注解如何使用
  2. 详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring @cacheable key

上一篇:C语言if选择结构语句怎么使用

下一篇:mysql中出现1053错误怎么办

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》