相关阅读
简介
解析缓存动作的接口,由CacheInterceptor
调用;
实现类知道如何从配置、源级别或者其它地方元数据获取缓存动作定义;
核心代码
/**
* 判断是否需要对当前类的所有方法进行解析
*/
default boolean isCandidateClass(Class<?> targetClass) {
return true;
}
/**
* 返回指定类的指定方法上所有SpringCache注解定义的缓存动作
*/
@Nullable
Collection<CacheOperation> getCacheOperations(Method method, @Nullable Class<?> targetClass);
实现子类
public interface CacheOperationSource
public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource
public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperationSource implements Serializable
AbstractFallbackCacheOperationSource
简介
定义了getCacheOperations
方法的算法模板,并提供两个抽象方法由子类实现算法细节;
核心代码
// null值的替代,ConcurrentHashMap不存null值
private static final Collection<CacheOperation> NULL_CACHING_ATTRIBUTE = Collections.emptyList()
// CacheOperation缓存集合
private final Map<Object, Collection<CacheOperation>> attributeCache = new ConcurrentHashMap<>(1024);
/**
* 获取指定方法的缓存动作集合
* 算法模板
*/
@Nullable
public Collection<CacheOperation> getCacheOperations(Method method, @Nullable Class<?> targetClass) {
// Object的方法没有缓存
if (method.getDeclaringClass() == Object.class) {
return null;
}
// 根据类和方法生成缓存KEY
Object cacheKey = getCacheKey(method, targetClass);
// 根据KEY,查缓存MAP,如果已经解析过,则直接返回
Collection<CacheOperation> cached = this.attributeCache.get(cacheKey);
if (cached != null) {
return (cached != NULL_CACHING_ATTRIBUTE ? cached : null);
}
else {
// 缓存MAP中不存在,则需要解析指定类的指定方法上的SpringCache动作
Collection<CacheOperation> cacheOps = computeCacheOperations(method, targetClass);
// 将解析结果存入缓存MAP,以便下次直接返回
if (cacheOps != null) {
if (logger.isTraceEnabled()) {
logger.trace("Adding cacheable method '" + method.getName() + "' with attribute: " + cacheOps);
}
this.attributeCache.put(cacheKey, cacheOps);
}
else {
this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE);
}
return cacheOps;
}
}
/**
* 根据类和方法生成缓存KEY
* 要求:
* 1. 重载的方法的KEY要不同
* 2. 同一类的不同实例的方法的KEY要相同
*/
protected Object getCacheKey(Method method, @Nullable Class<?> targetClass) {
return new MethodClassKey(method, targetClass);
}
/**
* 解析SpringCache动作
*/
@Nullable
private Collection<CacheOperation> computeCacheOperations(Method method, @Nullable Class<?> targetClass) {
// 如果方法不是public并且只允许public有缓存动作
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 找到method的真正实现
// 例如:Ifoo.bar(), target is DefaultFoo(implements Ifoo), so method is DefaultFoo.bar()
// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged.
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 第一次解析,根据method
// First try is the method in the target class.
Collection<CacheOperation> opDef = findCacheOperations(specificMethod);
if (opDef != null) {
return opDef;
}
// 第二次解析,根据target class
// Second try is the caching operation on the target class.
opDef = findCacheOperations(specificMethod.getDeclaringClass());
if (opDef != null && ClassUtils.isUserLevelMethod(method)) {
return opDef;
}
// 如果被解析的method不是原始入参,那么根据原始入参method再走一遍解析过程
if (specificMethod != method) {
// Fallback is to look at the original method.
opDef = findCacheOperations(method);
if (opDef != null) {
return opDef;
}
// Last fallback is the class of the original method.
opDef = findCacheOperations(method.getDeclaringClass());
if (opDef != null && ClassUtils.isUserLevelMethod(method)) {
return opDef;
}
}
return null;
}
/**
* 是否只支持public方法拥有SpringCache动作
*/
protected boolean allowPublicMethodsOnly() {
return false;
}
/**
* 获取类上的SpringCache动作
* 算法细节,由子类实现
*/
@Nullable
protected abstract Collection<CacheOperation> findCacheOperations(Class<?> clazz);
/**
* 获取方法上的SpringCache动作
* 算法细节,由子类实现
*/
@Nullable
protected abstract Collection<CacheOperation> findCacheOperations(Method method);
AnnotationCacheOperationSource
简介
CacheOperationSource
接口的实现,解析注释格式的缓存元数据;
核心代码
// 是否只允许public方法拥有SpringCache,默认true
private final boolean publicMethodsOnly;
// 解析器集合,默认只包括SpringCacheAnnotationParser
private final Set<CacheAnnotationParser> annotationParsers;
/**
* 构造方法
*/
public AnnotationCacheOperationSource() {
this(true);
}
/**
* 构造方法
*/
public AnnotationCacheOperationSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = Collections.singleton(new SpringCacheAnnotationParser());
}
/**
* 回调模式实现根据class获取类上的SpringCache动作
*/
@Nullable
protected Collection<CacheOperation> findCacheOperations(Class<?> clazz) {
return determineCacheOperations(parser -> parser.parseCacheAnnotations(clazz));
}
/**
* 回调模式实现根据method获取方法上的SpringCache动作
*/
@Nullable
protected Collection<CacheOperation> findCacheOperations(Method method) {
return determineCacheOperations(parser -> parser.parseCacheAnnotations(method));
}
/**
* 解析SpringCache动作
*/
@Nullable
protected Collection<CacheOperation> determineCacheOperations(CacheOperationProvider provider) {
Collection<CacheOperation> ops = null;
// 遍历解析器集合,综合所有解析器的结果
for (CacheAnnotationParser parser : this.annotationParsers) {
Collection<CacheOperation> annOps = provider.getCacheOperations(parser);
if (annOps != null) {
if (ops == null) {
ops = annOps;
}
else {
// 合并已有结果
Collection<CacheOperation> combined = new ArrayList<>(ops.size() + annOps.size());
combined.addAll(ops);
combined.addAll(annOps);
ops = combined;
}
}
}
return ops;
}
/**
* 是否只允许public方法拥有SpringCache动作
*/
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
/**
* 判断是否需要对当前类的所有方法进行解析
*/
public boolean isCandidateClass(Class<?> targetClass) {
// 遍历解析器集合,只要满足其中一个就需要解析,否则不解析
for (CacheAnnotationParser parser : this.annotationParsers) {
if (parser.isCandidateClass(targetClass)) {
return true;
}
}
return false;
}