第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解

摘要:
4、SimpleCacheConfiguration作用SimpleCacheConfiguration给容器中注册了一个CacheManager:ConcurrentMapCacheManager    5、ConcurrentMapCacheManager作用ConcurrentMapCacheManager实现了CacheManager接口,并重写了其中的方法:ConcurrentMapCacheManager作用:可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用是将数据保存到ConcurrentMap中;6、ConcurrentMapCache类用于缓存数据的类,其中使用ConcurrentMap来缓存数据。

一、@Cacheable 注解

作用:将方法的运行结果进行缓存,以后再要相同的数据,直接从缓存中获取,不用调用方法:

属性:

value/cacheNames:指定缓存组件的名字;
  CacheManager 管理多个 Cache 组件,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字

key: 缓存数据使用的 key,可以用它来指定。默认是使用方法参数的值。如 id=1, 1——>方法的返回值
   使用SPEL表达式:#id 是参数 id 的值 #a0 #p0 #root.arg[0]

keyGenerator:key 的生成器,可以自己指定 key 的生成器的组件 id
  key 与 keyGenerator 二选一使用

cacheManager:指定缓存管理器;或者是 cacheResolver

condition:判断条件,指定符合条件的情况下才缓存

unless:否定,unless 指定的条件为 true,方法的返回值就不会被缓存,可以获取到结果进行判断
	  unless = "#result == null"

sync:是否使用异步模式

代码示例:

@Cacheable(cacheNames = {"emp"})
publicEmployee getEmpById(Integer id) {
    System.out.println("查询" + id +"号员工");
    returnemployeeMapper.getEmpById(id);
}

二、@Cacheable 原理

当在主程序类上使用了@EnableCaching 注解就可以开启基于注解的缓存,下面来分析一下缓存的原理。

1、自动配置类CacheAutoConfiguration

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第1张

给容器中导入 CacheConfigurationImportSelector 类。

2、CacheConfigurationImportSelector 给容器中导入一系列的缓存的配置类

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第2张

导入的自动配置类:

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第3张

3、查看那个配置类默认生效

在配置文件中使用 debug = true 打开配置报告

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第4张

默认是SimpleCacheConfiguration 缓存配置类生效。

4、SimpleCacheConfiguration 作用

SimpleCacheConfiguration 给容器中注册了一个CacheManager: ConcurrentMapCacheManager第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第5张     

5、ConcurrentMapCacheManager 作用

ConcurrentMapCacheManager 实现了 CacheManager 接口,并重写了其中的方法:

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第6张

ConcurrentMapCacheManager 作用:

(1)可以获取和创建 ConcurrentMapCache 类型的缓存组件;

(2)他的作用是将数据保存到 ConcurrentMap 中;

6、ConcurrentMapCache 类

用于缓存数据的类,其中使用 ConcurrentMap 来缓存数据。

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第7张

存放值的方法:

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第8张

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第9张

三、运行流程

以 @Cacheable 注解为例:

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

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第10张

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

SimpleKeyGenerator 生成 key 的默认策略

如果没有参数:key = new SimpleKeyGenerator

  如果有一个参数: key = 参数的值

  如果有多个参数:key = new SimpleKey(param);

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第11张

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

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

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第12张

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

核心

(1)使用 CacheManager【ConcurrentMapCacheManager】 按照名字得到 Cache 【ConcurrentMapCache】组件;

(2)key 是使用keyGenerator 生成的,默认是SimpleKeyGenerator 生成的;

四、常用属性

  1、value/cacheNames

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

示例:

@Cacheable(cacheNames = {"emp", "temp"})
    publicEmployee getEmpById(Integer id) {
        System.out.println("查询" + id +"号员工");
        returnemployeeMapper.getEmpById(id);
    }

  2、key: 缓存数据使用的 key

支持使用 Spel 表达式

使用SPEL表达式:#id 是参数 id 的值 #a0 #p0 #root.arg[0]
getEmp[1] 作为 key key = "#root.methodName + '[' + #id + ']'"

Spel 表达式:

第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解第13张

  3、keyGenerator:key 的生成器

key 与 keyGenerator 二选一使用,可以自定义keyGenerator

自定义 KeyGenerator:

@Configuration
public classMyCacheConfig {

    @Bean(value = "myKeyGenerator")
    publicKeyGenerator keyGenerator() {
        return newKeyGenerator(){
            @Override
            publicObject generate(Object target, Method method, Object... params) {
                return method.getName() + "[" + Arrays.asList(params).toString() + "]";
            }
        };
    }
}

    @Cacheable(cacheNames = {"emp"}, keyGenerator = "myKeyGenerator")
    publicEmployee getEmpById(Integer id) {
        System.out.println("查询" + id +"号员工");
        returnemployeeMapper.getEmpById(id);
    }

  4、condition:判断条件,指定符合条件的情况下才缓存

condition = "#a0 > 1" 当第一个参数的值 > 1 的时候才进行缓存
condition = "#a0 > 1 and #root.methodName eq 'getEmpById'" 第一个参数的值 > 1 并且方法名是 getEmpById

  5、unless:否定,unless 指定的条件为 true,方法的返回值就不会被缓存,可以获取到结果进行判断

unless = "#result == null" 方法返回值如果为null,结果不缓存
unless = "#a0 == 2 " 如果第一个参数的值是2,结果不缓存

示例:

@Cacheable(cacheNames = {"emp"}, keyGenerator = "myKeyGenerator", condition = "#a0 > 1", unless = "#a0 == 2 ")
    publicEmployee getEmpById(Integer id) {
        System.out.println("查询" + id +"号员工");
        returnemployeeMapper.getEmpById(id);
    }

  6、sync:是否使用异步模式

#unless()} is not supported 开启异步,不支持 unless

免责声明:文章转载自《第九章:(2)Spring Boot 与 缓存 之 @Cacheable 注解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇信息安全等级保护三级系统基线要求判分标准之应用安全自编码器 Autoencoder下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mysql性能监控相关

如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接 怎么进入mysql命令行呢? mysql的安装目录下面有个bin目录,先用命令行进入该目录,然后用 mysql -uroot -p123456 来登录(注意:用户名和密码不用包含“”) 命令: show processlist; 如果是root帐号,你能看到所有用户...

Spring3.1 Cache注解

@Cacheable 支持如下几个参数: value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name key:缓存的key,默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL 例...

试验go rod 及更改chrome浏览器缓存位置

发现一个新的go语言库,例子在这里https://github.com/ysmood/rod/blob/master/examples_test.go 打算运行以下代码 package main import ( "fmt" "github.com/ysmood/rod" "github.com/ysmood/rod/lib/...

【转】分析SQL Server计划缓存

http://www.cio360.net/Page/1808/InfoID/291578/SourceId/11281/PubDate/2009-02-03/Default.aspx#pager SQL Server 7.0发布的版本之前,计划缓存是用于SQL Server的整个内存的单独可配置缓存区域。只有存储过程缓存在缓存的那个部分。由于这个原因,...

H5 缓存机制解析

在web项目开发中,我们可能都曾碰到过这样一个棘手的问题: 线上项目需要更新一个有问题的资源(可能是图片,js,css,json数据等),这个资源已经发布了很长一段时间,为什么页面在浏览器里打开还是没有看到更新? 有些web开发经验的同学应该马上会想到,可能是资源发布出了岔子导致没有实际发布成功,更大的可能是老的资源被缓存了。说到web缓存,首先我们要弄...

mysql 禁用查询缓存 query cache

os:centos 6.8 mysql: 5.5.49 MySQL Query Cache 会缓存select 查询,但是在调优sql查询及测试数据库的性能时需要禁用该功能。 查看变量、状态 mysql> show global variables like '%cache%'; +------------------------------+--...