# memo-agent
**Repository Path**: ingrun/memo-agent
## Basic Information
- **Project Name**: memo-agent
- **Description**: 轻量 Java 方法级缓存组件。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-07-13
- **Last Updated**: 2026-07-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# MemoAgent
轻量 Java 方法级缓存组件。支持**内存缓存**和 **Redis 缓存**两种后端,提供统一的静态门面 API。
---
## 快速开始
### 添加依赖
```xml
cn.ingrun
memo-agent-core
1.0.0
cn.ingrun
memo-agent-sb-redis
1.0.0
```
### Redis 缓存模式(Spring Boot)
引入 `memo-agent-sb-redis` 后自动装配,无需手动创建 Handler:
```yml
# application.yml
spring:
redis:
host: localhost
port: 6379
```
```java
// 直接使用 MemoAgent 静态方法
@RestController
public class UserController {
@GetMapping("/user/{id}")
public UserInfo getUser(@PathVariable String id) {
return MemoAgent.computeIfAbsent("user:" + id, () -> queryDB(id));
}
}
```
自动装配的 Bean:
- `StringRedisTemplate`(Spring Boot 默认提供)
- `JacksonRedisSerializer` — 默认序列化器
- `RedisMemoCache` — 基于 Redis 的 MemoCache
- `MemoConfigManage` + `MemoHandler` — 自动初始化 MemoAgent
### 示例:缓存一个慢查询
```java
// 配置命名空间(可选)
MemoAgent.config("user").setTtl(30_000).setNullValueCache(true);
// 生成 key 并缓存
String key = Util.genKey("user", new QueryParam(1));
UserInfo r1 = MemoAgent.computeIfAbsent(key, 10_000, () -> getUserFromDB(param));
UserInfo r2 = MemoAgent.computeIfAbsent(key, 10_000, () -> getUserFromDB(param));
// r2 命中缓存,不会执行 getUserFromDB
```
---
## API 参考
### MemoAgent — 唯一入口
| 方法 | 说明 |
|------|------|
| ` R computeIfAbsent(String key, long ttl, Supplier)` | 缓存读取,未命中执行 supplier 并缓存 |
| ` R computeIfAbsent(String key, Supplier)` | 同上,TTL 由配置决定 |
| ` R get(String key)` | 只读查询,不触发回源 |
| `put(String key, Object value, long ttl)` | 覆盖缓存 |
| `remove(String key)` | 移除缓存 |
| `updateTtl(String key, long ttl)` | 修改 TTL |
| `config(String cacheName)` | 获取命名空间配置(链式设置) |
### Util — Key 生成
| 方法 | 说明 |
|------|------|
| `genKey(String prefix, Object... args)` | `prefix:json(arg1):json(arg2)...` |
参数通过 Jackson 序列化为 JSON,确保"值相等则 key 相等"。
### MemoConfig — 配置
```java
MemoAgent.config("user")
.setTtl(30_000) // TTL (ms),0=继承全局,-1=永不过期
.setNullValueCache(true) // 是否缓存 null 值
.setRedisSerializer(serializer); // Redis 序列化器
```
哨兵值语义:
| 字段 | 哨兵值 | 含义 |
|------|--------|------|
| `ttl` | `0` | 合并时继承全局 TTL |
| `nullValueCache` | `null` | 合并时继承全局策略 |
| `redisSerializer` | `null` | 合并时继承全局序列化器 |
### MemoConfigManage — 三层配置
**默认值 → 全局 → 按命名空间(前缀匹配)**
```java
MemoConfigManage mgr = new MemoConfigManage();
mgr.getGlobalConfig().setTtl(60_000); // 全局 TTL 60s
mgr.getConfig("user").setTtl(30_000); // user 命名空间 TTL=30s
mgr.getConfig("user:detail").setNullValueCache(true);
// getMemoConfig 按最长前缀匹配
MemoConfig c = mgr.getMemoConfig("user:detail:123");
// → ttl=30000, nullValueCache=true
```
---
## SPI 接口
### MemoCache — 缓存后端
```java
public interface MemoCache {
void setCache(String key, Object value, long ttl);
Object getCache(String key);
void removeCache(String key);
void updateTtl(String key, long ttl);
long getRemainingTtl(String key);
boolean containsKey(String key); // 区分"缓存了 null"和"key 不存在"
}
```
内置实现:
| 实现 | 模块 | 存储 | 分布式 |
|------|------|------|:---:|
| `MemoryMemoCache` | core | ConcurrentHashMap + 惰性删除 | 不支持 |
| `RedisMemoCache` | sb-redis | Redis + 原生 EXPIRE | 支持 |
### RedisSerializer — 序列化器
```java
public interface RedisSerializer {
byte[] serialize(T t);
T deserialize(byte[] bytes);
}
```
内置实现:
- `JacksonRedisSerializer` — 基于 Jackson,包装模式存 `className + JSON`
- 演示参见 `memo-agent-demo`,含 `FastJsonRedisSerializer` 示例
### 自定义序列化器
```java
// 实现接口
public class MySerializer implements RedisSerializer