Spring Cache 缓存注解

243 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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缓存名
keyGeneratorkey值生成器

在类上统一进行配置,类下的方法自动继承相应的配置。

2.3 @Cacheable

用于查询数据,添加缓存,该注解用于修饰方法 or 类,添加加缓存的核心注解,分两种情况:

  • 一是对应key值未有缓存数据,先执行方法,然后根据conditionunless条件决定是否添加缓存;

  • 二是对应key值已有缓存,不执行方法体,直接返回数据。

参数keyGeneratorkey是互斥的,当key存在时keyGenerator配置自动失效。

参数含义使用说明
cacheManager缓存管理器缺省指首要的CacheManager
cacheNames缓存名
keyGeneratorkey值生成器
keykey值
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缓存名
keyGeneratorkey值生成器
keykey值
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缓存名
keyGeneratorkey值生成器
keykey值
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