首页 > 编程知识 正文

cache buffer区别,cacheable注解

时间:2023-05-06 09:34:31 阅读:17539 作者:3023

CacheAble、CachePut、CacheEvict的缓存注释基础逻辑分析目录1、序言2、 @Cacheable @CachePut @CacheEvict功能1. @Cacheable作用代码使用实例2. @CachePut作用代码使用实例3. @CacheEvict作用3, @Cacheable @CachePut @CacheEvict基础处理方式1. Springboot-cache处理核心类CacheAspectSupport.java2.源代码及分析3. Springboot-cache 有关更多用法,可以查看官方教程和其他博客文章。 如果这篇文章有错误的地方,希望大家指出来,共同讨论,共同进步。 尼、@Cacheable @CachePut @CacheEvict功能提示:已经掌握的学生可以直接看到下一节。

1. @Cacheable角色简要说明:此注释基于cacheNames key查询缓存。 说明深度: @Cacheable在执行方法之前返回并从缓存中检索数据。 如果检索到,则将此缓存值直接返回到方法的返回值。 未能取得时执行本方法,将本方法的结果放入缓存中。 这样,下次执行本方法时使用缓存。 代码使用示例@ service @ allargsconstructorpublicclassroleserviceimplimplementsiroleservice { privatefinalrolemapperrrolemapper; /** * @Cacheable在执行本方法(getOneById )之前先返回缓存获取数据(如果获取了,则直接将该缓存值返回为本方法的返回值;如果未获取,则执行本方法,然后返回//@ override @ cacheable (cache names=' role ',key='#p0 ' ) publicrolegetonebyid(longid ) return this.role maper

此注释是基于cacheNames key添加缓存的,遇到同名时将被覆盖。 深度说明:

@CachePut将此方法(getOneById )的返回值放入指定的缓存中。 因此,此评论具有添加和修改(覆盖)缓存的功能。 代码使用示例@ service @ allargsconstructorpublicclassroleserviceimplimplementsiroleservice { privatefinalrolemapperrrolemapper; /** * @CachePut将此方法(getOneById )的返回值放入指定的缓存中),因此具有添加和更改(复盖)缓存的功能。 //@ override @ cache put (cache names=' role ',key='#p0 ' ) publicrolegetonebyid(longid ) return this.role mapper } 深度说明: @CacheEvict删除满足密钥的缓存,不对该方法(getOneById )的返回值执行任何操作。 但是,请记住,默认情况下,此删除是在本方法结束后进行的。 @ service @ allargsconstructorpublicclassroleserviceimplimplementsiroleservice { privatefinalrolemapperrrolemapper; /** *@CacheEvict删除满足密钥的缓存,不对该方法(getOneById )的返回值执行任何操作。 //@ override @ cache evict (cache names=' role ',key='#p0 ' ) publicrolegetonebyid(longid ) returnthis.rolemapppid } @Cacheable @CachePut @CacheEvict基底处理方式1. Springboot-cache处理核心类CacheAspectSupport.java对本类来说,是最重要的这三种注释和调用方法以及

protectedobjectexecute (cacheoperationinvokerinvoker,Object target,方法方法,对象[ ] args ) )。

因此,这次将聚焦于该方法的业务逻辑,对与此相关的方法,简单说明其作用和返回值,但不深入挖掘。

2. 源码及解析 @Nullableprivate Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) { // 一、方法参数解释 // invoker : 用于执行method的对象,对应上述代码指的是:放在Spring-IOC中的RoleServiceImpl对象。 // method : 被注解的方法,对应上述的代码指的是:getOneById。 // contexts : 被注解方法的@Cacheable等注解信息,可以从里面提取出对应的缓存注解。 // 二、这段方法和主要逻辑关系不大,可以简单理解根据参数进行一些简单的设置。// Special handling of synchronized invocationif (contexts.isSynchronized()) {CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);Cache cache = context.getCaches().iterator().next();try {return wrapCacheValue(method, handleSynchronizedGet(invoker, key, cache));}catch (Cache.ValueRetrievalException ex) {// Directly propagate ThrowableWrapper from the invoker,// or potentially also an IllegalArgumentException etc.ReflectionUtils.rethrowRuntimeException(ex.getCause());}}else {// No caching required, only call the underlying methodreturn invokeOperation(invoker);}} // 三、@CacheEvict注解有一个叫做beforeInvocation的字段可以设置是否在methods执行前就将缓存删除。这个方法就是将此字段为true的缓存在此处进行删除// Process any early evictionsprocessCacheEvicts(contexts.get(CacheEvictOperation.class), true,CacheOperationExpressionEvaluator.NO_RESULT); // 四、从Contexts获取是否有@Cacheable注解。如果有的话就去找缓存,如果缓存中存在对应数据就返回,不存在就返回null;如果没有此注解就返回null。 // 所以cacheHit这个对象代表,是否存在key对应的缓存。null代表没有,非null代表存在。 // 在此时Cacheable就已经去查询缓存了。// Check if we have a cached item matching the conditionsCache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class)); // 四、如果缓存为空的话,SpringCache会将@Cacheable自动降级为@CachePut,用于之后增加缓存。 // 可以理解为缓存的添加是由CachePut维护的,@Cacheable的查询和增添功能是被分隔开的。 // 如果是@CahceEvict,虽然cacheHit为null,但是不影响。// Collect puts from any @Cacheable miss, if no cached item is foundList<CachePutRequest> cachePutRequests = new ArrayList<>();if (cacheHit == null) {collectPutRequests(contexts.get(CacheableOperation.class),CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);} // 用于对缓存操作(增加)的对象Object cacheValue; // 用于作文methods返回值的对象Object returnValue; // 五-1、如果cache存在,并且不是个CachePut(更新请求),就是用上面查到的缓存Cachehit进行赋值。if (cacheHit != null && !hasCachePut(contexts)) {// If there are no put requests, just use the cache hitcacheValue = cacheHit.get();returnValue = wrapCacheValue(method, cacheValue);} // 五-2、如果Cache不存在,或是@CachePut缓存更新操作, // 就通过反射调用目标方法methods从而进行获取最新的数据。else {// Invoke the method if we don't have a cache hitreturnValue = invokeOperation(invoker);cacheValue = unwrapReturnValue(returnValue);} // 六-1、判断是否有@CachePut请求,如果有的就加入一个请求更新链(因为一个@CachePut可以 // 确定多个要跟新的缓存区域)// Collect any explicit @CachePutscollectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests); // 六-2、根据上面的链(有@CacheAble但是数据不存在,也有@CachePut这种默认更新)将本次方法结果一一放入缓存。// Process any collected put requests, either from @CachePut or a @Cacheable missfor (CachePutRequest cachePutRequest : cachePutRequests) {cachePutRequest.apply(cacheValue);} // 七、删除@CacheEvict的删除缓存的操作。与上面提前删除有关,如果之前设置提前删除,这里就不再删除了// Process any late evictionsprocessCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue); // 八、返回methods执行的结果。return returnValue;} 3. Springboot-cache流程图

execute方法会处理上述的三个注解,所以这个流程图这代表泵方法的流程图
如图:

四、尾声 不足: 本次方法有的没有研究到,比如execute方法,第二个过程的代码块。所以没有涉及,后续博主如果研究过后,会再写一篇博客。本篇博客只涉及了这三个注解的解析过程。它们怎么使用,以及这个execute的触发都没有写到。因为前者是工具性质博客,后者是一种通用的注解拓展功能的思想,其不仅仅在Springboot-cache中使用到了,其它地方也用到了,博主想用更好的文章来讲解这块知识。

最后如果本篇博客有什么问题还请大家指出。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。