Spring Cache Redis 源码分析
缓存 AOP 配置
AOP 配置:org.springframework.cache.annotation.ProxyCachingConfiguration
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyCachingConfiguration extends AbstractCachingConfiguration {
@Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryCacheOperationSourceAdvisor cacheAdvisor(CacheOperationSource cacheOperationSource, CacheInterceptor cacheInterceptor) {
BeanFactoryCacheOperationSourceAdvisor advisor = new BeanFactoryCacheOperationSourceAdvisor(); // 其中定义了切点
advisor.setCacheOperationSource(cacheOperationSource); // 保存缓存注解实例的对象
advisor.setAdvice(cacheInterceptor); // 缓存拦截器
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public CacheOperationSource cacheOperationSource() {
return new AnnotationCacheOperationSource(); // 保存缓存注解实例的对象
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public CacheInterceptor cacheInterceptor(CacheOperationSource cacheOperationSource) {
CacheInterceptor interceptor = new CacheInterceptor(); // 缓存拦截器
interceptor.configure(this.errorHandler, this.keyGenerator, this.cacheResolver, this.cacheManager);
interceptor.setCacheOperationSource(cacheOperationSource);
return interceptor;
}
}
缓存拦截器:对使用缓存注解的方法进行拦截,并织入缓存功能
org.springframework.cache.interceptor.CacheInterceptor
public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
CacheOperationInvoker aopAllianceInvoker = () -> {return invocation.proceed();};
Method method = invocation.getMethod();
Object target = invocation.getThis();
return execute(aopAllianceInvoker, target, method, invocation.getArguments()); // 调用父类 CacheAspectSupport 的方法
}
}
缓存切面辅助类:定义缓存切面逻辑
org.springframework.cache.interceptor.CacheAspectSupport
public abstract class CacheAspectSupport extends AbstractCacheInvoker
implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
CacheOperationSource cacheOperationSource = getCacheOperationSource(); // 保存所有缓存注解实例的对象
Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass); // 获取方法上的缓存注解集合
return execute(invoker, method, new CacheOperationContexts(operations, method, args, target, targetClass)); // new CacheOperationContexts() 对每个缓存注解创建缓存注解上下文集合
}
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
// Process any early evictions
processCacheEvicts(contexts.get(CacheEvictOperation.class), true, CacheOperationExpressionEvaluator.NO_RESULT);
// Check if we have a cached item matching the conditions
// 从缓存注解上下文集合中获取 Cacheable 缓存注解上下文集合,并尝试从缓存中取数据
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
// Collect puts from any @Cacheable miss, if no cached item is found
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
for (CachePutRequest cachePutRequest : cachePutRequests) {
cachePutRequest.apply(cacheValue);
}
// Process any late evictions
processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);
return returnValue;
}
private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
Object result = CacheOperationExpressionEvaluator.NO_RESULT;
// 遍历所有缓存注解上下文,尝试从中定义的缓存去数据
for (CacheOperationContext context : contexts) {
if (isConditionPassing(context, result)) {
Object key = generateKey(context, result);
Cache.ValueWrapper cached = findInCaches(context, key);
if (cached != null) {
return cached;
}
}
}
return null;
}
private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object key) {
// 遍历由缓存注解上下文中获取 cacheNames 定义的缓存实例,并尝试从缓存实例中获取数据
for (Cache cache : context.getCaches()) {
Cache.ValueWrapper wrapper = doGet(cache, key);
if (wrapper != null) {
return wrapper;
}
}
return null;
}
protected Cache.ValueWrapper doGet(Cache cache, Object key) {
return cache.get(key);
}
}
缓存注解上下文
缓存注解上下文集合:
public abstract class CacheAspectSupport {
// CacheAspectSupport 内部类
private class CacheOperationContexts {
private final MultiValueMap<Class<? extends CacheOperation>, CacheOperationContext> contexts;
private final boolean sync;
public CacheOperationContexts(Collection<? extends CacheOperation> operations, Method method, Object[] args, Object target, Class<?> targetClass) {
this.contexts = new LinkedMultiValueMap<>(operations.size());
for (CacheOperation op : operations) {
this.contexts.add(op.getClass(), getOperationContext(op, method, args, target, targetClass));
}
this.sync = determineSyncFlag(method);
}
}
protected CacheOperationContext getOperationContext(CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass);
return new CacheOperationContext(metadata, args, target);
}
}
缓存注解上下文:
public abstract class CacheAspectSupport {
// CacheAspectSupport 内部类
protected class CacheOperationContext implements CacheOperationInvocationContext<CacheOperation> {
private final CacheOperationMetadata metadata;
private final Object[] args;
private final Object target;
private final Collection<? extends Cache> caches;
private final Collection<String> cacheNames;
@Nullable
private Boolean conditionPassing;
public CacheOperationContext(CacheOperationMetadata metadata, Object[] args, Object target) {
this.metadata = metadata;
this.args = extractArgs(metadata.method, args);
this.target = target;
this.caches = CacheAspectSupport.this.getCaches(this, metadata.cacheResolver); // 调用缓存解析器,解析该上下文的缓存实例
this.cacheNames = createCacheNames(this.caches);
}
}
protected Collection<? extends Cache> getCaches(CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver) {
Collection<? extends Cache> caches = cacheResolver.resolveCaches(context); // 调用缓存解析器,解析该上下文的缓存实例
return caches;
}
}
缓存实例解析器
缓存实例解析器接口:从被拦截的方法的缓存注解上下文解析出缓存实例
public interface CacheResolver {
Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context);
}
抽象缓存实例解析器:从缓存管理器中获取缓存实例
public abstract class AbstractCacheResolver implements CacheResolver, InitializingBean {
private CacheManager cacheManager;
@Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
Collection<String> cacheNames = getCacheNames(context); // 从缓存注解上下文中获取缓存实例名称
Collection<Cache> result = new ArrayList<>(cacheNames.size());
for (String cacheName : cacheNames) {
Cache cache = getCacheManager().getCache(cacheName); // 根据缓存名称从缓存管理器中获取缓存实例
result.add(cache);
}
return result;
}
protected abstract Collection<String> getCacheNames(CacheOperationInvocationContext<?> context);
}
简单缓存实例解析器:从缓存注解上下文中的 cacheNames 属性获取缓存实例名称
public class SimpleCacheResolver extends AbstractCacheResolver {
public SimpleCacheResolver(CacheManager cacheManager) {
super(cacheManager);
}
@Override
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
return context.getOperation().getCacheNames();
}
}