Spring Boot Cache

Spring Boot Cache

一、Spring 缓存抽象

Spring 从 3.1 开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术;并支持使用 JCache(JSR-107) 注解简化我们开发。

二、几个重要概念

名称 说明
Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 缓存管理器,管理各种缓存(Cache)组件
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CacheEvict 清空缓存
@CachePut 保证方法被调用,又希望结果被缓存
@EnableCaching 开启基于注解的缓存
keyGenerator 缓存数据的 key 生成策略
serialize 缓存数据时 value 序列化策略

三、使用缓存

步骤

  • 给 Application 添加 @EnableCaching 注解

  • 标注缓存注解即可

    • @Cacheable 的属性

      名称 说明
      cacheNames/value 指定缓存组件的 名字
      key 缓存数据使用的key
      keyGenerator key 的生成器;可以自己指定 key 的生成器,key/keyGenerator 两者二选一
      cacheManager 指定缓存管理器,或者指定缓存解析器,两者二选其一
      cacheResolver 缓存解析器
      condition 指定符合条件的情况下才缓存
      unless 否定缓存;当 unless 指定的条件为 true ,方法的结果不缓存,可以获取到结果进行判断 unless = "#result==null" 则不缓存
      sync 是否使用异步模式

      注解中的值的指定可以使用 SpEL 表达式:

      @Cacheable(cacheNames="#root.targetClass",key="#root.args[0]")
      

  • 运行流程

    1、方法运行之前,先去查询 Cache(缓存组件),按照 cacheNames 指定的名字获取;(CacheManager先获取相应的缓存),第一次获取缓存如果没有 Cache 组件会自动创建。

    2、去 Cache 中查找缓存的内容,使用一个 key,默认就是方法的参数;

    ​ key 是按照某种策略生成的;默认是使用 keyGenerator 生成的,默认使用 SimpleKeyGenerator 生成 key;

    ​ SimpleKeyGenerator 生成key的默认策略;

    ​ 如果没有参数:key = new SimpleKey();

    ​ 如果有一个参数:key = new SimpleKey(params);

    3、没有查到缓存就调用目标方法;

    4、将目标方法返回的结果,放进缓存中。

    @Cacheable 标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为 key 去查询缓存,如果没有就运行方法并将结果放入缓存中;以后再来调用就可以直接使用该缓存。

  • 自定义 KeyGenerator 需要实现接口 KeyGenerator。

  • @CachePut 既调用了方法,又更新了缓存。

  • @CacheEvict 清除缓存,用在 delete 中。

    1、key:指定要清除的数据

    2、allEntries = true : 指定清除这个缓存中所有的数据

    3、beforeInvocation = false :缓存的清除是否在方法之前执行,默认代表缓存清除操作在方法执行之后执行;如果方法执行出现异常缓存就不会清除、

  • @Caching 定义复杂的缓存规则

    如果要对一个对象采用多种方式来进行缓存,例如对User 采用 ID 、姓名 等多种缓存方式可以选择@Caching注解

  • @CacheConfig 缓存公共配置,可以给整个类配置公共的缓存组件以此简化代码

四、使用 Redis 作为缓存中间件

1、安装 redis,可以使用 docker 比较方便

2、引入 redis 的 starter

​ 可以去 spring-boot 的文档中找 redis 的 starter,例如:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

3、配置 redis

spring:
  redis:
    host: localhost
    password: zolmk123456

4、使用 redis

​ 快捷键 Ctrl N 搜索 RedisAutoConfiguration 可以看到这个类注入了 StringRedisTemplate 和 RedisTemplate 两个 bean 对象,我们可以使用这两个对象来操作 redis。

5、使用 json 格式的序列化器

​ redis默认使用 jdk 的序列化器,保存对象的时候会出现一些不易理解的字符,所以一般我们使用 json 格式的序列化器。

​ RedisConfig 类配置如下:

package com.zolmk.cache.config;

import com.zolmk.cache.entity.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.net.UnknownHostException;

/**
 * @author : Administrator
 * @project : cache
 * @date : 2020/5/11 1:11
 **/
@Configuration
public class RedisConfig
{
    @Bean
    public RedisTemplate<Object, User> userRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException
    {
        RedisTemplate<Object, User> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        template.setDefaultSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
        return template;
    }
}

​ 使用 json 格式的序列化器之后效果如下图所示:

五、主动用代码操作缓存

// 1.注入一个 CacheManager
@Autowired
private RedisCacheManager cacheManager;
// 2.使用CacheManager 获取一个 Cache 中间件
RedisCache redisCache = (RedisCache) cacheManager.getCache("user");
// 3.使用 Cache 对象进行缓存操作
redisCache.put("user-01",user);
posted @ 2020-12-02 15:46  zolmk  阅读(191)  评论(0编辑  收藏  举报