您好,登录后才能下订单哦!
密码登录
            
            
            
            
        登录注册
            
            
            
        点击 登录注册 即表示同意《亿速云用户服务条款》
        # 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) {
    // 数据库查询逻辑
}
| 参数 | 作用 | 
|---|---|
value | 
指定缓存名称(必需) | 
key | 
自定义缓存键(可选) | 
condition | 
满足条件才缓存(SpEL表达式) | 
当不指定key时,Spring使用SimpleKeyGenerator生成规则:
- 无参数方法:返回SimpleKey.EMPTY
- 单参数方法:直接使用该参数
- 多参数方法:返回包含所有参数的SimpleKey
// 使用参数作为key
@Cacheable(key = "#user.id")
public User updateUser(User user)
// 组合多个参数
@Cacheable(key = "#type + '_' + #id")
public Item getItem(String type, String id)
| 表达式 | 说明 | 
|---|---|
#root.methodName | 
获取当前方法名 | 
#root.targetClass | 
目标类Class对象 | 
#result | 
方法返回值(仅限unless使用) | 
// 嵌套属性访问
@Cacheable(key = "#user.address.postCode")
// 调用对象方法
@Cacheable(key = "#user.getFullName().toLowerCase()")
@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());
    }
}
@Cacheable(value="books", keyGenerator="customKeyGenerator")
public Book findBook(ISBN isbn, boolean checkWarehouse)
适用场景: - 需要统一key生成规则时 - 复杂参数对象的特殊处理
// 业务前缀+参数组合
@Cacheable(key = "'user:' + #userId")
// 日期分区缓存
@Cacheable(key = "T(java.time.LocalDate).now().toString() + ':' + #productId")
// 使用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("_"));
    };
}
@Cacheable(key = "'app1:user:' + #userId")
// 使用hash tag保证相同用户数据落在同一节点
@Cacheable(key = "'user_{' + #userId + '}'")
unless = "#result == null"// 通过CacheManager获取统计信息
cacheManager.getCache("userCache").getNativeCache(); 
// Ehcache: getStatistics()
// Redis: info命令
最佳实践提示:建议在项目初期建立《缓存key设计规范》,包括命名约定、失效策略等,可显著降低后期维护成本。 “`
注:本文实际约4500字(含代码示例),完整版可扩展以下内容: 1. 各缓存实现(Redis/Ehcache)的特殊配置 2. 与@CacheEvict的联动使用 3. 性能压测数据对比 4. 完整案例项目演示
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。