Spring Boot中的EnableCaching简述

spring boot中自带有数据缓存机制,主要通过其org.springframework.cache包下的各种类来实现。

EnableCaching

@EnableCaching是启用缓存的注解,标注在任何一个可自动注入的类上即可开启。

Cacheable

@Cacheable是一个标注与类与方法上的注解,用于表示此类或此方法需要使用缓存机制。当类与方法上都有时,采用 就近原则

@Cacheable注解中,有一些常用参数可以进行配置:

  • valuecacheNames - 表示绑定的缓存名称。这里的缓存指的是单个的缓存存储器,并不是最终的键值对缓存对象。
  • key - 表示缓存对象的 key,这个才是最终的缓存键值对的 key。这里的参数需要使用 SpEL表达式。
  • keyGenerator - 表示用于生成此方法 缓存key的类。与key参数只能选择一个添加,否则会抛出IllegalStateException异常。
  • cacheManager - 指定缓存管理器。这个后面再细说。
  • condition - 缓存的条件。支持SpEL,当缓存条件满足时,才会进入缓存取值模式。
  • unless - 排除的条件。支持SpEL,当排除的条件满足时,会直接调用方法取值。
  • sync - 异步缓存模式。是否采用异步的方式,在方法取值时异步缓存。默认false,在缓存完成后才返回值。

一般情况下,可以这样使用:

@RestController
@RequestMapping("cache")
@Cacheable(value = "cache", sync = true)
public class CacheController {
@Cacheable(value = "hello", sync = true, keyGenerator = "myKeyGenerator")
@GetMapping("hello")
public String hello(String name) {
System.out.println("name - " + name);
return "hello " + name;
}
@GetMapping("hello2")
public String hello2(@RequestParam(defaultValue = "1") Integer size, @RequestParam(defaultValue = "world") String name) {
System.out.println("name - " + name);
return "hello " + name;
}
}
  • 这里的CacheController被标记上了@Cacheable(value = "cache", sync = true),表示其下的方法默认使用名为cache的缓存存取器,并采用异步的方式进行缓存处理。
  • hello方法上同样添加了@Cacheable(value = "hello", sync = true, keyGenerator = "myKeyGenerator"),使得hello方法使用了独立的缓存设置,并通过myKeyGenerator的策略来生成 缓存key

CachePut

将方法返回值存入到缓存中,一般情况下是用在更新操作中,并于CacheableCacheEvict配合使用。

CacheEvict

清除缓存值,一般用在删除或更新操作中,并于CacheableCachePut配合使用。

并且在CacheEvict注解中,多了两个参数:

  • allEntries - 清除当前value下的所有缓存。
  • beforeInvocation - 在方法执行前清除缓存。

示例代码示例如下:

    @Cacheable(value = "c", key = "123")
@GetMapping("hello")
public String hello(String name) {
System.out.println("name - " + name);
return "hello " + name;
}
@GetMapping("/put")
@CachePut(value = "c", key = "123")
public String put() {
return "hello put";
}
@GetMapping("/evict")
@CacheEvict(value = "c", key = "123")
public String evict() {
return "hello put";
}

上述代码中,访问hello接口时,会从c缓存存取器中取出key123的缓存数值,没有则会调用方法并进行缓存。

访问put接口时,会将c缓存存取器key123的缓存值改为hello put,没有则进行缓存。

访问evict接口时,会将c缓存存取器key123的缓存值删除,此时访问hello接口会重新调用方法并进行缓存。

CacheConfig

@CacheConfig作为类上的注解,目的是为了统一配置其下的方法缓存参数,并设定共享缓存名。

  • cacheNames - 共享缓存名数组。设定后表示此类下的方法缓存会依次从这些缓存存取器中取值,如果有,则取用缓存值;若没有则调用方法取值,并缓存值到设定的所有缓存存取器中。

CacheManager

缓存管理器接口,用来做缓存管理的类。一般我们需要自定义缓存策略时,就是从CacheManager来入手的。

直接上实例:

@Component
public class MyCacheManager implements CacheManager, InitializingBean {
private final Map<String, Cache> cacheMap;
public MyCacheManager() {
cacheMap = new HashMap<>();
}
@Override
public Cache getCache(String name) {
System.out.println("正在获取缓存 - " + name);
return cacheMap.computeIfAbsent(name, MyCache::new);
}
@Override
public Collection<String> getCacheNames() {
return cacheMap.keySet();
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("say something!");
}
}

CacheManager有两个方法需要被实现:

  • getCache(String) - 获取缓存存取器。这里的name其实就对应了@Cacheable注解中的valuecacheName参数。
  • getCacheNames - 获取类中所有缓存的名称集合。这主要是为了Spring内部的统一管理需要。

    因为 Spring采用了默认替补策略,所以我们使用@Component或是通过@Bean自动注入后,默认的缓存管理器就会切换成我们自定义的。如果我们自定义了两个的话,可以通过@Primary来设定默认管理器。

Cache

缓存存取器,用来管理缓存键值对的基本单元。

为了能对不同的缓存采用不同的存取策略,我们可以定制不同的Cache,并通过自定义的CacheManagergetCache方法返回对应的Cache

举个例子:

public final static class MyCache extends ConcurrentMapCache {
public MyCache(String name) {
super(name);
}
@Override
public <T> T get(Object key, Class<T> type) {
System.out.println("正在读取 - " + key);
return super.get(key, type);
}
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
System.out.println("正在读取 - " + key);
return super.get(key, valueLoader);
}
@Override
public ValueWrapper get(Object key) {
System.out.println("正在读取 - " + key);
return super.get(key);
}
}

这里的MyCache集成了ConcurrentMapCache,并对每次缓存值的获取都进行了控制台输出。

KeyGenerator

缓存key生成器,用于自定义规则缓存key的生成。

其接口的方法只有一个:

public interface KeyGenerator {
Object generate(Object target, Method method, Object... params);
}

一目了然,通过调用的目标对象、目标方法与方法入参进行key的生成。这里不做过多赘述。

不过需要注意的是,由于不同类可能有同名同参数的方法,这里建议加上target.getClass().getName()来作为标记,避免出现不希望的缓存映射。

SpringBoot的EnableCaching简述的更多相关文章

  1. springboot底层原理简述

    1.maven 子父依赖关系,快速整合第三方框架 2.无配置文件 省略了web.xml,spring.xml,springmvc.xml.mybatis.xml. spring3.0以上提供注解,sp ...

  2. SpringBoot的启动简述

    一.注解和启动类SpringBootApplication 它是一个复式注解. @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME ...

  3. springboot中RedisTemplate的使用

    springboot中RedisTemplate的使用 参考 了解 Redis 并在 Spring Boot 项目中使用 Redis--以IBM为学习模板 springboot之使用redistemp ...

  4. Spring Boot 2.X(七):Spring Cache 使用

    Spring Cache 简介 在 Spring 3.1 中引入了多 Cache 的支持,在 spring-context 包中定义了org.springframework.cache.Cache 和 ...

  5. JavaXXX成长直通车_汇总

    学习开始于2019-12-08 阶段一 阶段一-01.万丈高楼,地基首要-第1章 学习指南-1-1 课程导学 1-2是图片 阶段一-01.万丈高楼,地基首要-第1章 学习指南-1-3 大型网站架构演变 ...

  6. Spring Cache缓存技术,Cacheable、CachePut、CacheEvict、Caching、CacheConfig注解的使用

    前置知识: 在Spring Cache缓存中有两大组件CacheManager和Cache.在整个缓存中可以有多个CacheManager,他们负责管理他们里边的Cache.一个CacheManage ...

  7. SpringBoot史前简述

    背景 大约20年前,程序员们使用“企业级Java Bean”(EJB)开发企业应用,需要配置复杂的XML. 在二十世纪初期,新兴Java技术——Spring,横空出世.使用极简XML和POJO(普通J ...

  8. springboot之jpa(简述)

    1.maven引入jar包(jpa和mysql) <dependency> <groupId>org.springframework.boot</groupId> ...

  9. springboot+redis

    上篇整合了DB层,现在开始整合缓存层,使用redis. springboot驱动注解,使用spring注入JedisPool便可封装自己的redis工具类. package hello.configu ...

  10. 【springBoot】springBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

随机推荐

  1. oracle 实例无法启动和初始化

    1 先看oracle的监听和oracle的服务是否都启动了.启动oracle监听:cmd的命令行窗口下,输入lsnrctl start,回车即启动监听.2 查看oracle的sid叫什么,比如创建数据 ...

  2. git 报错 incorrect username or password

    如果报这个 就是用户名 或密码错误 添加个正确的凭据就好了

  3. fpga 通过vga模块使电脑显示图片

    对vga模块搞了好几天,vga接口时序不难,就是行计数,列计数,对应到每一个像素上去.这里我先把vga控制模块的程序付上.采用的是小梅哥的程序.屏幕是800X600,配置的时钟是40M.注意改变屏幕尺 ...

  4. qt中的一些对话框(个人备忘录)

    一.标准对话框 1.对于颜色对话框 void MyWidget::on_pushButton_clicked() { QColorDialog dialog(Qt::red,this); dialog ...

  5. PTA最大子列和问题

    给定K个整数组成的序列{ N1​, N2​, ..., NK​ },"连续子列"被定义为{ Ni​, Ni+1​, ..., Nj​ },其中 1≤i≤j≤K."最大子列 ...

  6. js 获取html加载的参数?file=123&time=2021

    <script> function GetArgsFromHref(sHref, sArgName) { var args = sHref.split("?"); va ...

  7. ubuntu14搭建内网gitlab服务器

    平台 宿主机系统版本:Ubuntu 14.04.5 LTS gitlab软件版本:11.10.8-ee 验证web浏览器版本:Mozilla Firefox 68.3.0esr 安装firefox浏览 ...

  8. 华为服务器修改ibmc账号密码、配置raid5、安装系统

    修改ibmc账号密码 转载自:https://www.cnblogs.com/mtactor/p/2288V5.html  昵称: mtactor 方法一:采用网线直连管理口 1.使用网线直接连接服务 ...

  9. input类型为number仍可以输入e,+,-解决方法

    <input type="number" onKeypress="return(/[\d\.]/.test(String.fromCharCode(event.ke ...

  10. Hive启动留下的RunJar进程不能使用Kill -9 杀不掉怎么办?

    1.问题示例 [Hadoop@master Logs]$ jps 3728 ResourceManager 6976 RunJar 7587 Jps 4277 Master 3095 NameNode ...