# cache-plus
**Repository Path**: go_into_the_new_era/cache-plus
## Basic Information
- **Project Name**: cache-plus
- **Description**: 缓存框架
- **Primary Language**: Java
- **License**: Unlicense
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 1
- **Created**: 2020-06-07
- **Last Updated**: 2022-03-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 缓存抽象增强
spring 官方提供了标准的[缓存抽象](https://docs.spring.io/spring/docs/5.1.10.RELEASE/spring-framework-reference/integration.html#cache),它大致实现了[JSR-107](https://github.com/jsr107/jsr107spec)。
但是它对缓存需求支持的程度有限,尤其是不支持批量缓存操作。
现已找到的资源只有[CacheX](https://github.com/feiqing/cachex)实现了批量模式。
为何不直接采用:
- 上一次更新是1年之前;
- 依赖了一些不太合理的库,如 jbox 等,还有一些我们用不上的功能;
- 难以及时响应需求变更,无法掌控开发进度;
因此,决定自己动手。
## 使用指南
### 引入
如果你想自己配置各个 bean,可以使用如下依赖:
```xml
com.chenjia
cache-plus-base
1.3.0.RELEASE
```
如果想开箱即用,可以使用如下依赖,以获得自动配置:
```xml
com.chenjia
cache-plus-spring-boot-starter
1.3.0.RELEASE
```
### 基于注解的使用
0. 所有被设置缓存的方法的实体类都最好实现序列化接口 `Serializable`,以兼容不同的序列化方式。默认序列化方式是 [kryo](https://github.com/EsotericSoftware/kryo)。此外,为了保证反序列化的字段兼容性(比如缓存了a字段,现在又加上了b字段,反序列化就会失败),kryo 应该使用较高版本(5及以上),它提供了兼容性。不过最好还是通过缓存的版本号来区分,以防业务出错。
1. 对方法进行缓存,单条
```
@Cached(value = "redis", prefix = "test-", expire = Expire.HALF_HOUR)
public TestEntity read(@CacheKey int id) {
log.info("---> method called!");
return testMapper.getTest(id);
}
```
上面的示例表示:对 read 方法进行缓存;指定缓存实现 为 redis(默认值);缓存 key 用入参 id 的值,结合前缀 `test-`;过期时间是半个小时。
当访问没有走缓存时,日志 "---> method called!" 将会被打印出来(这个仅用于测试缓存是否生效)。
缓存实现的指定:默认使用第一个(HashMap#entrySet()遍历的第一个),如果只配置了一个缓存实现,可以不指定。目前在 starter 中只配置了 redis 这一个缓存实现。若有其它,需要重写配置,并在使用处显式指定所用的缓存。
缓存实现都会托管到 `CacheManager#cachePool` 中,其键名就是配置名。
2. 对方法进行缓存,批量模式
```
@Cached(prefix = "test-", expire = Expire.HALF_HOUR)
public List readList(@CacheKey(value = "#idList[#i]", field = "id") List idList) {
log.info("---> method called, idList={}", idList);
return testMapper.getTestList(idList);
}
```
与单条模式的区别有两点:
- 入参出参都是集合类;
- CacheKey 需要指定 SpEL 表达式和 field,前者指定遍历key的方式,后者指定入参与出参的一一对应关系(这要求出参实体类必须包含入参字段,以区分缓存命中)。
## TODO LIST
1. 缓存的续签:当缓存接近失效时,提前异步进行缓存重新加载。
2. 缓存更新:这是个大问题,需要慢慢设计实现。
欢迎提需求与想法,任何方面的都可以!