<cache:annotation-driven/> ``` 它们负责负责注册必要的Spring组件,提供缓存管理,例如`CacheInterceptor`和基于代理的增强。 然后就给出了很清晰的使用方法: ``` java @Configuration @EnableCaching public class AppConfig { @Bean public MyService myService() { // configure and return a class having @Cacheable methods return new MyService(); } @Bean public CacheManager cacheManager() { // configure and return an implementation of Spring's CacheManager SPI SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default"))); return cacheManager; } }
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, 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 method return invokeOperation(invoker); } }
// Process any early evictions // 处理beforeInvocation processCacheEvicts(contexts.get(CacheEvictOperation.class), true, CacheOperationExpressionEvaluator.NO_RESULT);
// Check if we have a cached item matching the conditions // 就是这里从缓存中获取对象,实际处理了注解中condition、key Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
// Collect puts from any @Cacheable miss, if no cached item is found // 判断unless List<CachePutRequest> cachePutRequests = new ArrayList<>(); if (cacheHit == null) { collectPutRequests(contexts.get(CacheableOperation.class), CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests); }
Object cacheValue; Object returnValue;
if (cacheHit != null && !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 // 处理其他CachePut for (CachePutRequest cachePutRequest : cachePutRequests) { cachePutRequest.apply(cacheValue); }
// Process any late evictions // 处理condition processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);