Hyperf 3.0 的 @Cacheable 支持轻量级 SpEL 表达式,支持参数引用(#id、#p0)、对象属性(#user.id)、数组键(#filters['status'])、字符串拼接(. 或 +)、空值处理(?:)、数组序列化(json_encode/md5)、自定义工具函数及 #root 上下文访问。

Hyperf 3.0 的 @Cacheable 注解支持 SpEL 表达式(Spring Expression Language 风格),但注意:Hyperf 并非 Spring,其 SpEL 实现是轻量级兼容版本(由 hyperf/cache 和 hyperf/annotation 模块提供),语法高度相似,但不完全等同于 Spring Boot 的完整 SpEL 功能。动态 key 的核心在于正确引用方法参数、调用工具方法、处理数组或对象属性。
基础参数引用写法
直接使用 #参数名 或 #p0、#p1 索引方式是最常用且最稳妥的写法:
-
#[Cacheable(key: "#id")]→ 引用名为id的参数 -
#[Cacheable(key: "#p0")]→ 引用第一个参数(索引从 0 开始) -
#[Cacheable(key: "#user.id")]→ 引用$user对象的id属性(要求对象有 public 属性或 getter) -
#[Cacheable(key: "#filters['status']")]→ 引用关联数组中键为status的值(PHP 数组语法兼容)
组合多个参数生成 key
用字符串拼接可清晰表达业务语义,推荐用单引号包裹字面量,避免解析歧义:
#[Cacheable(key: "'search_' + #page + '_' + #perPage + '_' + #filters.status")]-
#[Cacheable(key: "#userId . '_' . #category . '_' . #sortBy")](Hyperf 支持.拼接,更符合 PHP 习惯) - 若含空值风险,建议配合
?:默认值:#[Cacheable(key: "#userId . '_' . (#filters.type ?: 'all')")]
安全处理数组参数(关键痛点)
Hyperf 默认对数组参数直接 implode(':',$args),易导致键冲突或过长。应显式控制序列化逻辑:
- 用
json_encode标准化(注意排序与键顺序):#[Cacheable(key: "'list_' . md5(json_encode(#filters, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT))")] - 提取关键字段再拼接,避免全量数组:
#[Cacheable(key: "'user_list_' . (#filters['role'] ?: 'all') . '_' . (#filters['enabled'] ?? 'any'))"] - 自定义工具函数(需在注解上下文中可访问):
#[Cacheable(key: "App\Helper\CacheKeyHelper::buildSearchKey(#filters, #page)")],前提是该静态方法已注册并被注解处理器支持
使用 root 对象获取上下文信息
Hyperf 的 #root 提供当前方法元信息,适合通用缓存策略:
-
#root.methodName→ 当前方法名,如"searchUsers" -
#root.target→ 当前类实例,可用于调用辅助方法:#[Cacheable(key: "#root.target.getCachePrefix() . '_' . #id")] -
#root.args→ 参数数组,可配合array_slice或implode使用(慎用于含数组的场景)


















