设为首页 加入收藏

TOP

Spring Cache框架(四)
2018-11-21 22:08:35 】 浏览:605
Tags:Spring Cache 框架
heEvicts) { ops.add(parseEvictAnnotation(ae, defaultConfig, cacheEvict)); } } CachePut[] cachePuts = caching.put(); if (!ObjectUtils.isEmpty(cachePuts)) { ops = lazyInit(ops); for (CachePut cachePut : cachePuts) { ops.add(parsePutAnnotation(ae, defaultConfig, cachePut)); } } return ops; }

然后回到 AbstractFallbackCacheOperationSource 类:

public Collection<CacheOperation> getCacheOperations(Method method, Class<?> targetClass) {
	if (method.getDeclaringClass() == Object.class) {
		return null;
	}

	Object cacheKey = getCacheKey(method, targetClass);
	Collection<CacheOperation> cached = this.attributeCache.get(cacheKey);

	if (cached != null) {
		return (cached != NULL_CACHING_ATTRIBUTE ? cached : null);
	}
	else {
		Collection<CacheOperation> cacheOps = computeCacheOperations(method, targetClass);
		if (cacheOps != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Adding cacheable method '" + method.getName() + "' with attribute: " + cacheOps);
			}
			this.attributeCache.put(cacheKey, cacheOps);
		}
		else {
			this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE);
		}
		return cacheOps;
	}
}

这里会将解析出来的 CacheOperation 放在当前 Map<Object, Collection<CacheOperation>> attributeCache = new ConcurrentHashMap<Object, Collection<CacheOperation>>(1024); 属性上,为后续拦截方法时处理缓存做好数据的准备。

注解产生作用

当访问 categoryService.get(category) 方法时,会走到 CglibAopProxy.intercept() 方法,这也说明缓存注解是基于动态代理实现,通过方法的拦截来动态设置或失效缓存。方法中会通过 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 来拿到当前调用方法的 Interceptor 链。往下走会调用 CacheInterceptor 的 invoke 方法,最终调用 execute 方法,我们重点分析这个方法的实现。

private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
	// Special handling of synchronized invocation
	if (contexts.isSynchronized()) {
		CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
		if (isConditionPassing(context, CacheOperationExpressioneva luator.NO_RESULT)) {
			Object key = generateKey(context, CacheOperationExpressioneva luator.NO_RESULT);
			Cache cache = context.getCaches().iterator().next();
			try {
				return wrapCacheva lue(method, cache.get(key, new Callable<Object>() {
					@Override
					public Object call() throws Exception {
						return unwrapReturnValue(invokeOperation(invoker));
					}
				}));
			}
			catch (Cache.ValueRetrieva lException ex) {
				// The invoker wraps any Throwable in a ThrowableWrapper instance so we
				// can just make sure that one bubbles up the stack.
				throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();
			}
		}
		else {
			// No caching required, only call the underlying method
			return invokeOperation(invoker);
		}
	}

	// Process any early evictions
	processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
			CacheOperationExpressioneva luator.NO_RESULT);

	// Check if we have a cached item matching the conditions
	Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));

	// Collect puts from any @Ca
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇SpringBoot系列二:SpringBoot自.. 下一篇Java调试检查表

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目