一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
2.Spring Cache 注解
Spring Cache 提供了 @Cacheable 、@CachePut 、@CacheEvict 、@Caching 等注解,在方法上使用。
基于注解方式SpringCache引入Redis做缓存,需要先了解@EnableCaching、@CacheConfig、@Cacheable、@CachePut、@CacheEvict、@Caching相关注解的使用。
2.1 @EnableCaching
开启缓存功能,一般放在启动类上或者自定义的RedisConfig配置类上。
2.2 @CacheConfig
在类上使用,当该类有多个方法有同样的缓存操作时使用
当我们需要缓存的地方越来越多,可以使用@CacheConfig(cacheNames = "cacheName") 注解在 class 之上来统一指定value的值,统一管理keys,这时可省略value,如果你在你的方法依旧写上了value,那么依然以方法的value值为准。
@Service
@CacheConfig(cacheNames = "categories")
public class UserServiceImpl implements UserService{}
| 参数 | 含义 | 使用说明 |
|---|---|---|
cacheManager | 缓存管理器 | 缺省指首要的CacheManager |
cacheNames | 缓存名 | |
keyGenerator | key值生成器 |
在类上统一进行配置,类下的方法自动继承相应的配置。
2.3 @Cacheable
用于查询数据,添加缓存,该注解用于修饰方法 or 类,添加加缓存的核心注解,分两种情况:
-
一是对应key值未有缓存数据,先执行方法,然后根据condition和unless条件决定是否添加缓存;
-
二是对应key值已有缓存,不执行方法体,直接返回数据。
参数keyGenerator与key是互斥的,当key存在时keyGenerator配置自动失效。
| 参数 | 含义 | 使用说明 |
|---|---|---|
cacheManager | 缓存管理器 | 缺省指首要的CacheManager |
cacheNames | 缓存名 | |
keyGenerator | key值生成器 | |
key | key值 | |
condition | 缓存条件 | 指示满足条件方执行缓存操作,一般使用参数作为条件 |
unless | 否定缓存 | 当条件为 true ,方法的返回值不会被缓存 |
sync | 同步状态 | 默认值:false,表示将方法执行结果以何种方式存入缓存 |
cacheNames 可以理解为缓存 key 的前缀,可以为组件缓存的 key 变量;当 key 不设置时,使用方法参数来初始化,注意 key 为 SpEL 表达式,因此如果要写字符串时,用单引号括起来。
/**
* 首先从缓存中查,查到之后,直接返回缓存数据;否则执行方法,并将结果缓存
* <p>
* redisKey: cacheNames + key 组合而成 --> 支持SpEL
* redisValue: 返回结果
*
* @param name
* @return
*/
@Cacheable(cacheNames = "say", key = "'p_'+ #name")
public String sayHello(String name) {
return "hello+" + name + "-->" + UUID.randomUUID().toString();
}
如我们传参为 hanpang, 那么缓存 key 为
say::p_hanpang
/**
* 满足condition条件的才写入缓存
* @param age
* @return
*/
@Cacheable(cacheNames = "condition", key = "#age", condition = "#age % 2 == 0")
public String setByCondition(int age) {
return "condition:" + age + "-->" + UUID.randomUUID().toString();
}
上面这个 case 中,age 为偶数的时候,才走缓存;否则不写缓存
/**
* unless, 不满足条件才写入缓存
* @param age
* @return
*/
@Cacheable(cacheNames = "unless", key = "#age", unless = "#age % 2 == 0")
public String setUnless(int age) {
return "unless:" + age + "-->" + UUID.randomUUID().toString();
}
上面这个 case 中,age 为奇数的时候,才走缓存;否则不写缓存
2.4 @CachePut
用于新增数据时, 自动更新缓存,使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。
一般用在新增方法上。 查看源码,属性值同上@Cacheable差不多。
| 参数 | 含义 | 使用说明 |
|---|---|---|
cacheManager | 缓存管理器 | 缺省指首要的CacheManager |
cacheNames | 缓存名 | |
keyGenerator | key值生成器 | |
key | key值 | |
condition | 缓存条件 | 指示满足条件方执行缓存操作,一般使用参数作为条件 |
unless | 否定缓存 | 当条件为 true ,方法的返回值不会被缓存 |
/**
* 不管缓存有没有,都写入缓存
* @param age
* @return
*/
@CachePut(cacheNames = "t4", key = "#age")
public String cachePut(int age) {
return "t4:" + age + "-->" + UUID.randomUUID().toString();
}
2.5 @CacheEvict
用于修改或删除数据时,清空缓存,使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上。
| 参数 | 含义 | 使用说明 |
|---|---|---|
cacheManager | 缓存管理器 | 缺省指首要的CacheManager |
cacheNames | 缓存名 | |
keyGenerator | key值生成器 | |
key | key值 | |
condition | 缓存条件 | 指示满足条件方执行缓存操作,一般使用参数作为条件 |
allEntries | 所有缓存 | 默认为false 如果指定为true,则方法调用后将立即清空所有的缓存 |
beforeInvocation | 调用前 | 是否在方法执行前就清空所有缓存,默认为false。如果指定为true,则方法执行前就会清空所有的缓存 |
/**
* 失效缓存
* @param name
* @return
*/
@CacheEvict(cacheNames = "say", key = "'p_'+ #name")
public String evict(String name) {
return "evict+" + name + "-->" + UUID.randomUUID().toString();
}
2.6 @Caching
该注解可以实现同一个方法上同时使用多种注解
// 可从其源码看出
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
/**
* caching实现组合,添加缓存,并失效其他的缓存
*
* @param age
* @return
*/
@Caching(cacheable = @Cacheable(cacheNames = "caching", key = "#age"),
evict = @CacheEvict(cacheNames = "t4", key = "#age"))
public String caching(int age) {
return "caching: " + age + "-->" + UUID.randomUUID().toString();
}
- 从
caching::age缓存取数据,不存在时执行方法并写入缓存;- 失效缓存
t4::age