Sprintg boot 热数据缓存

2020-08-22  本文已影响0人  杨健kimyeung

一、主要类&缓存注解

名称 解释
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其进行缓存
@CachePut 保证方法被调用,又希望结果被缓存。 与@Cacheable区别在于是否每次都调用方法,常用于更新
@CacheEvict 清空缓存
@EnableCaching 开启基于注解的缓存
@CacheConfig 统一配置本类的缓存注解的属性
keyGenerator 缓存数据时key生成策略
serialize 缓存数据时value序列化策略
Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 缓存管理器

核心注解参数

名称 解释
value 缓存的名称,在 spring 配置文件中定义
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写, 如果不指定,则缺省按照方法的所有参数进行组合 例如: @Cacheable(value=”testcache”,key=”#id”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false, 只有为 true 才进行缓存/清除缓存 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
unless 否定缓存。当条件结果为TRUE时,就不会缓存。 @Cacheable(value=”testcache”,unless=”#userName.length()>2”)
allEntries (@CacheEvict ) 是否清空所有缓存内容,缺省为 false,如果指定为 true, 则方法调用后将立即清空所有缓存 例如: @CachEvict(value=”testcache”,allEntries=true)
beforeInvocation (@CacheEvict) 是否在方法执行前就清空,缺省为 false,如果指定为 true, 则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法 执行抛出异常,则不会清空缓存 例如: @CachEvict(value=”testcache”,beforeInvocation=true)

二、开启缓存

1、在启动类上加注解 @EnableCaching

@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisCacheApplication.class, args);
    }
}

2、EnableCaching

完成了这些配置之后,Spring Boot就会自动帮我们在后台配置一个RedisCacheManager,相关的配置是在RedisCacheConfiguration类中完成的。

@Configuration
@ConditionalOnClass(RedisConnectionFactory.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class RedisCacheConfiguration {
  @Bean
  public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
    RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
    List<String> cacheNames = this.cacheProperties.getCacheNames();
    if (!cacheNames.isEmpty()) {
      builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
    }
    return this.customizerInvoker.customize(builder.build());
  }
}

三、添加@Cacheable

1、作用

表示将一个方法的返回值缓存起来,一般用于查询方法,默认情况下,缓存的key就是方法的参数,缓存的value就是方法的返回值。执行过程

  1. 先查询是否已经有缓存
  2. 有会使用缓存
  3. 没有则会执行方法并缓存

2、源代码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
    @AliasFor("cacheNames")
    String[] value() default {};
    @AliasFor("value")
    String[] cacheNames() default {};
    String key() default "";
    String keyGenerator() default "";
    String cacheManager() default "";
    String cacheResolver() default "";
    String condition() default "";
    String unless() default "";
    boolean sync() default false;
}

2、属性说明

属性说明 说明
String key() key的生成器。可以是spEL表达式。默认情况下,缓存的key就是方法的参数
String[] value() 同cacheNames
String[] cacheNames() 必要参数,指定一个或多个Cache名字
String keyGenerator() key的生成器。key/keyGenerator二选一使用
String cacheManager() 指定缓存管理器
String cacheResolver() 指定获取解析器
String condition() 条件符合则缓存
String unless() 条件符合则不缓存
boolean sync() 是否使用异步模式

4、栗子

@RestController
public class CacheController {
//    @Cacheable(cacheNames = "index",key = "#name")
    @RequestMapping("/")
    @Cacheable(cacheNames = "index", key = ("targetClass.getName() + '.'+methodName"))
    public String index() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}

5、key自定义策略

当有多个参数时,默认就使用多个参数来做key,如果只需要其中某一个参数做key,则可以在@Cacheable注解中,通过key属性来指定key,如上代码就表示只使用id作为缓存的key,如果对key有复杂的要求,可以自定义keyGenerator。

当然,Spring Cache 中提供了root对象,可以在不定义keyGenerator的情况下实现一些复杂的效果

#root可以省略

属性名称 描述 示例
methodName 当前方法名 #root.methodName
method 当前方法 #root.method.name
target 当前被调用的对象 #root.target
targetClass 当前被调用的对象的class #root.targetClass
args 当前方法参数组成的数组 #root.args[0]
caches 当前被调用的方法使用的Cache #root.caches[0].name
@Bean
public KeyGenerator myKeyGenerator(){
    return new KeyGenerator(){
        @Override
        public Object generate(Object target, Method method, Object... params) {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
                sb.append(obj.toString());
            }
            return sb.toString();
        }
    };
}

四、更新@CachePut

1、作用

主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用 。简单来说就是用户更新缓存数据。但需要注意的是该注解的valuekey 必须与要更新的缓存相同,也就是与@Cacheable 相同

2、源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
    @AliasFor("cacheNames")
    String[] value() default {};
    @AliasFor("value")
    String[] cacheNames() default {};
    String key() default "";
    String keyGenerator() default "";
    String cacheManager() default "";
    String unless() default "";
}

3、属性说明

同@Cacheable

4、栗子

@CachePut(value = "index", key = ("targetClass.getName() + '.'+methodName"))
public String updateDate() {
return "更新数据";
}

5、注意

五、删除@CacheEvict

1、作用

主要针对方法配置,能够根据一定的条件对缓存进行清空 。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheEvict {
  // ...其它属性同上
  boolean allEntries() default false;
  boolean beforeInvocation() default false;
}

2、属性说明

属性 解释 示例
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 @CachEvict(value="index",allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 @CachEvict(value="index",beforeInvocation=true)

六、配置@CacheConfig

1、作用

这个注解是用于在同一个类中共享一些基础的cache配置的
一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。
该操作会被覆盖。

七、组合@Caching

1、作用

有时候我们可能组合多个Cache注解使用,此时就需要@Caching组合多个注解标签了。

2、源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Caching {
    Cacheable[] cacheable() default {};
    CachePut[] put() default {};
    CacheEvict[] evict() default {};
}
上一篇 下一篇

猜你喜欢

热点阅读