2020-10-25

springboot缓存

JSR-107、Spring缓存抽象、整合Redis

一、JSR-107

由java退出的一套缓存规范

  • CachingProvider:定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期间访问多个CachinProvider。
  • CacheManager:定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache穿在与CacheManager的上下文中。一个CacheManager仅能被一个CachingProvider所拥有。
  • Cache:是一个类似于Map的数据结构并临时储存以Key为索引的值。一个Cache仅能被一个CacheManager所拥有。
  • Entry:是一个存储在Cache中的Key-value对。
  • Expiry:每一个储存在Cache中的条目有 一个定义的有效期。一旦超过这个时间,条目为过期的状态,条目不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cDkgdU0H-1603595507896)(images/JSR-107.PNG)]

二、Spring缓存抽象

Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager,并支持Cache(JSR-107)注解简化我们的开发;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-psyWkmpi-1603595507901)(images/Cache注解.png)]

其中CachePut总是被调用的,一般在更改方法上标注。

快速使用:

一、搭建基本环境

​ 1)、导入数据库文件 创建出department和employee表

​ 2)、创建javaBean封装数据

​ 3)、整合Mybatis

​ 1)、连接数据源

​ 2)、使用注解版的mybatis

​ 1)、@MapperScan指定需要扫描的mapper接口所在的包

​ 2)、配置mapepr,service,controller,并进行测试

二、快速体验缓存

​ 步骤

​ 1、开启基于注解的缓存 @EnableCaching

@MapperScan("com.huzy.cache.mapper")
@SpringBootApplication
@EnableCaching
public class SpringbootPlus001CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootPlus001CacheApplication.class, args);
    }

}

​ 2、标注缓存注解即可

@Cacheable
@CacheEvict
@CachePut

1)、Cacheable
将方法的运行结果进行缓存;以后再有相同的参数传入,直接从缓存中获取,不用调用方法。

原理

​ 1、自动配置类 :CacheAutoConfiguration

​ 2、缓存配置类10个(springBoot2.30)

  • org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration

  • org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration(JSR-107)

  • org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration(EH)

  • org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration(分布式缓存组件)

  • org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration

  • org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration

  • org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration(redis)

  • org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration

  • org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration

  • org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration

    3、那些配置类会默认生效:SimpleCacheConfiguration

    4、给容器注册了一个CacheManager,ConcurrentMapCacheManager

    5、可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用是将数据保存在ConcurrentMap

运行流程

@Cacheable

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

​ 2、去Cache中查找缓存的内容,使用一个key,默认是方法的参数。
​ key是按照某种策略生成的;默认是使用keyGenerator生成,默认使用SimpleKeyGenerator生成key

​ SimpleKeyGenerator生成key的默认策略;
​ 如果没有参数;key = new SimpleKey();
​ 若果没有一个参数; key = 参数的值
​ 如果有多个参数; key = new SimpleKey(params);

​ 3、如果没有查到缓存,就会调用目标方法。

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

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

注解有几个属性:
1. cacheNames/value:指定缓存组件的名字;

​ 将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存。

​ CacheManager管理多个Cache组件,对缓存真正的CRUD操作在Cache组件中,每一个组件都有自己唯一一个名字;
​ 表示将缓存放在哪个CacheManager中,若没有指定,会创建一个SimpleCacheConfiguration,

2. key:缓存数据使用的key;可以用它来指定.

​ 默认是 使用的方法参数的值, 1-方法返回的值.也可以使用CacheSqEL进行其他key生成策略,编写SpEL;#id;-参数id的值 #a0 #P0 #root.args[0]

​ 自定义名称 例如 @Cacheable(value = {“emp”}, key = “#root.methodName+”["+#id+"]")

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sxapQwKQ-1603595507903)(images/CacheSpEL.png)]

3.keyGenerator:key 的生成器 ;
​ 可以自己指定key的生成器的组件id,key/keyGenerator:二者二选一

package com.huzy.cache.config;

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author huzy
 * @date 2020/10/259:44
 */
@Configuration
public class MyCacheConfig {
    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return new KeyGenerator(){
            @Override // 实现抽象方法,实现代码的生成规则
            public Object generate(Object o, Method method, Object... objects) {
                return method.getName()+"["+ Arrays.asList(objects).toString()+"]";
            }
        };
    }
}

    @Cacheable(cacheNames = "emp" ,keyGenerator = "myKeyGenerator")
    public Employee getEmp(Integer id){
        return employeeMapper.getEmpById(id);
    }

4.keyManager:缓存管理器;
​ 或者cacheResolver 指定获取解析器 ,二者二选一
5.condition:指定符合条件的情况下才缓存;(条件缓存)

​ 例如: condition= “#a0>1” ; 表示第一个参数的值大于1的时候才进行缓存

    @Cacheable(cacheNames = "emp" ,keyGenerator = "myKeyGenerator",condition = "#a0>1")
    public Employee getEmp(Integer id){
        return employeeMapper.getEmpById(id);
    }

6.unless:否定缓存;
​ 当unless指定的条件为true,方法返回值就不会被缓存;可以获取搭配结果进行判断unless = "#result == null"意为返回结果为空的话不进行缓存。其优先级高于condition,

    @Cacheable(cacheNames = "emp" ,keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2")
    public Employee getEmp(Integer id){
        return employeeMapper.getEmpById(id);
    }//当 id输入为2时 ,虽然满足了condition的a0>1的条件,但是又满足了 unless的 a0=2 ,故不进行缓存

7.sync: 是否使用异步模式

​ 默认FALSE使用同步模式,就是缓存和sql查询同步进行;若是将其改为TRUE,会出现一个问题,不在支持unless。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值