博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring cache
阅读量:6963 次
发布时间:2019-06-27

本文共 3095 字,大约阅读时间需要 10 分钟。

spring cache定义的接口

如下图,涉及到的操作有get、put、evict,对应于查询、更新、清除缓存
image
对应的注解为cacheable、cacheevict、cacheput操作,可以查看源码分析注解的字段了解注解的用法
image
参考:

SpEL上下文数据

spring cache支持SpEL表达式

methodName

root对象

当前被调用的方法名

root.methodName

method

root对象

当前被调用的方法

root.method.name

target

root对象

当前被调用的目标对象

root.target

targetClass

root对象

当前被调用的目标对象类

root.targetClass

args

root对象

当前被调用的方法的参数列表

root.args[0]

caches

root对象

当前方法调用使用的缓存列表(如@Cacheable(value={"cache1", "cache2"})),则有两个cache

root.caches[0].name

argument name

执行上下文

当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数

user.id

result

执行上下文

方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,'cache evict'的beforeInvocation=false)

result

通过这些数据我们可能实现比较复杂的缓存逻辑了,后边再来介绍。

image

execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());

根据 类 + 方法 ,获取定义的缓存操作,构建缓存上下文

image

缓存的执行流程

1、首先执行@CacheEvict(如果beforeInvocation=true且condition 通过),如果allEntries=true,则清空所有
2、接着收集@Cacheable(如果condition 通过,且key对应的数据不在缓存),放入cachePutRequests(也就是说如果cachePutRequests为空,则数据在缓存中)
3、如果cachePutRequests为空且没有@CachePut操作,那么将查找@Cacheable的缓存,否则result=缓存数据(也就是说只要当没有cache put请求时才会查找缓存)
4、如果没有找到缓存,那么调用实际的API,把结果放入result
5、如果有@CachePut操作(如果condition 通过),那么放入cachePutRequests
6、执行cachePutRequests,将数据写入缓存(unless为空或者unless解析结果为false);
7、执行@CacheEvict(如果beforeInvocation=false 且 condition 通过),如果allEntries=true,则清空所有

// Process any early evictions        processCacheEvicts(contexts.get(CacheEvictOperation.class), true,                CacheOperationExpressionEvaluator.NO_RESULT);        // Check if we have a cached item matching the conditions        Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));        // Collect puts from any @Cacheable miss, if no cached item is found        List
cachePutRequests = new LinkedList
(); if (cacheHit == null) { collectPutRequests(contexts.get(CacheableOperation.class), CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests); } Object cacheValue; Object returnValue; if (cacheHit != null && cachePutRequests.isEmpty() && !hasCachePut(contexts)) { // If there are no put requests, just use the cache hit cacheValue = cacheHit.get(); returnValue = wrapCacheValue(method, cacheValue); } else { // Invoke the method if we don't have a cache hit returnValue = invokeOperation(invoker); cacheValue = unwrapReturnValue(returnValue); } // Collect any explicit @CachePuts collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests); // Process any collected put requests, either from @CachePut or a @Cacheable miss for (CachePutRequest cachePutRequest : cachePutRequests) { cachePutRequest.apply(cacheValue); } // Process any late evictions processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);

如何定义自己的缓存管理器CacheManager

spring cache的CacheManager的体系结构如下
image
默认提供了Ehcache和JCache的支持,并且缓存还支持事务(事务回退缓存回退),如果自定义缓存可以选择继承其中的某一个,只需要实现其中一个抽象方法,将实现了cache接口的缓存注入到缓存管理器即可
image

转载地址:http://bczsl.baihongyu.com/

你可能感兴趣的文章
JEESZ-Zookeeper集群安装
查看>>
Dubbo背景和简介
查看>>
vue-router的HTML5 History 模式设置
查看>>
Neo 虚拟机
查看>>
Pycharm上Django的使用 Day10
查看>>
node上的redis调用优化示例
查看>>
Jenkinsfile
查看>>
CSS:父子元素浮动分析和清除浮动
查看>>
springboot配置Druid数据源
查看>>
IT兄弟连 JavaWeb教程 过滤器与监听器经典面试题
查看>>
[喵咪BELK实战(2)] elasticsearch+kibana搭建
查看>>
关于 SSHKey
查看>>
struts-ObjectFactory
查看>>
eclipse查看版本
查看>>
Hadoop面试45个题目及答案
查看>>
nagios的安装
查看>>
【GO 笔记】 20180907 golang GUI
查看>>
Go语言下载、安装、配置、使用
查看>>
Rabbitmq-springboot集成
查看>>
mysql实用命令
查看>>