Spring Cache基础组件 CacheInterceptor

相关阅读

简介

声明式缓存管理器的AOP方法拦截器,实现了MethodInterceptor接口,继承于CacheAspectSupport

核心代码

/**
 * 实现方法拦截处理逻辑
 */
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {
    Method method = invocation.getMethod();
    // 以及MethodInvocation生成CacheOperation invoker
    CacheOperationInvoker aopAllianceInvoker = () -> {
        try {
            // 简单调用MethodInvocation的proceed方法
            return invocation.proceed();
        }
        catch (Throwable ex) {
            throw new CacheOperationInvoker.ThrowableWrapper(ex);
        }
    };

    // 获取方法所在的实例
    Object target = invocation.getThis();
    Assert.state(target != null, "Target must not be null");
    try {
        // 调用CacheAspectSupport的方法完成缓存逻辑
        return execute(aopAllianceInvoker, target, method, invocation.getArguments());
    }
    catch (CacheOperationInvoker.ThrowableWrapper th) {
        throw th.getOriginal();
    }
}

继承关系

public abstract class AbstractCacheInvoker
    public abstract class CacheAspectSupport extends AbstractCacheInvoker implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton
        public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable

AbstractCacheInvoker

简介

调用缓存方法的基础组件,并且由可配置的CacheErrorHandler处理调用过程层中发生的异常;

核心代码

// 异常处理器
protected SingletonSupplier<CacheErrorHandler> errorHandler;


/**
 * 构造方法
 */
protected AbstractCacheInvoker() {
    // 异常处理器默认为SimpleCacheErrorHandler
    this.errorHandler = SingletonSupplier.of(SimpleCacheErrorHandler::new);
}

/**
 * 获取缓存值
 */
@Nullable
protected Cache.ValueWrapper doGet(Cache cache, Object key) {
    try {
        return cache.get(key);
    }
    catch (RuntimeException ex) {
        // 处理异常并返回null
        getErrorHandler().handleCacheGetError(ex, cache, key);
        return null;  // If the exception is handled, return a cache miss
    }
}

/**
 * 存入缓存值
 */
protected void doPut(Cache cache, Object key, @Nullable Object result) {
    try {
        cache.put(key, result);
    }
    catch (RuntimeException ex) {
        getErrorHandler().handleCachePutError(ex, cache, key, result);
    }
}

/**
 * 清除缓存值
 */
protected void doEvict(Cache cache, Object key, boolean immediate) {
    try {
        if (immediate) {
            // 立即清除,后续不可见
            cache.evictIfPresent(key);
        }
        else {
            cache.evict(key);
        }
    }
    catch (RuntimeException ex) {
        getErrorHandler().handleCacheEvictError(ex, cache, key);
    }
}

/**
 * 清空缓存
 */
protected void doClear(Cache cache, boolean immediate) {
    try {
        if (immediate) {
            // 立即清除,后续不可见
            cache.invalidate();
        }
        else {
            cache.clear();
        }
    }
    catch (RuntimeException ex) {
        getErrorHandler().handleCacheClearError(ex, cache);
    }
}

CacheAspectSupport

简介

缓存切面的基础类,支持Spring基础Cache框架;
使用模版模式定义了缓存切面处理流程;

核心代码

// 缓存动作元数据
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
// 缓存动作表达式解析器
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
// 缓存动作解析器
@Nullable
private CacheOperationSource cacheOperationSource;
// 缓存KEY生成器
private SingletonSupplier<KeyGenerator> keyGenerator = SingletonSupplier.of(SimpleKeyGenerator::new);
// 缓存解析器
@Nullable
private SingletonSupplier<CacheResolver> cacheResolver;
// Bean工厂
@Nullable
private BeanFactory beanFactory;
// 初始化标识
private boolean initialized = false;


/**
 * 配置
 */
public void configure(
    @Nullable Supplier<CacheErrorHandler> errorHandler, @Nullable Supplier<KeyGenerator> keyGenerator,
    @Nullable Supplier<CacheResolver> cacheResolver, @Nullable Supplier<CacheManager> cacheManager) {

    this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new);
    this.keyGenerator = new SingletonSupplier<>(keyGenerator, SimpleKeyGenerator::new);
    this.cacheResolver = new SingletonSupplier<>(cacheResolver,
        () -> SimpleCacheResolver.of(SupplierUtils.resolve(cacheManager)));
}

/**
 * 执行
 */
@Nullable
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
    // 初始化完成,已准备好
    // Check whether aspect is enabled (to cope with cases where the AJ is pulled in automatically)
    if (this.initialized) {
        // 获取最终class类型
        Class<?> targetClass = getTargetClass(target);
        CacheOperationSource cacheOperationSource = getCacheOperationSource();
        // 缓存动作解析器存在
        if (cacheOperationSource != null) {
            // 解析本方法上的缓存动作
            Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass);
            if (!CollectionUtils.isEmpty(operations)) {
                // 最终执行方法
                return execute(invoker, method,
                new CacheOperationContexts(operations, method, args, target, targetClass));
            }
        }
    }
    return invoker.invoke();
}

/**
 * 执行
 */
@Nullable
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);
        }
    }

    // 处理发生在方法执行前的CacheEvict动作
    // Process any early evictions
    processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
            CacheOperationExpressionEvaluator.NO_RESULT);

    // 判断是否命中一个缓存值
    // Check if we have a cached item matching the conditions
    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) {
        // 如果没有命中缓存,Cacheable需要将方法返回值放入缓存,即CachePut
        collectPutRequests(contexts.get(CacheableOperation.class),
                CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
    }

    // 缓存值
    Object cacheValue;
    // 方法返回值
    Object returnValue;

    // 如果命中缓存且不需要执行CachePut动作,则直接使用缓存值
    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);
    }

    // 收集CachePut动作,与未命中缓存值的Cacheable动作合一
    // Collect any explicit @CachePuts
    collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);

    // 处理put动作
    // Process any collected put requests, either from @CachePut or a @Cacheable miss
    for (CachePutRequest cachePutRequest : cachePutRequests) {
        cachePutRequest.apply(cacheValue);
    }

    // 处理发生在方法执行后的CacheEvict动作
    // Process any late evictions
    processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);

    return returnValue;
}

/**
 * 处理CacheEvict注解
 */
private void processCacheEvicts(
    Collection<CacheOperationContext> contexts, boolean beforeInvocation, @Nullable Object result) {
    // 遍历CacheEvict动作
    for (CacheOperationContext context : contexts) {
        CacheEvictOperation operation = (CacheEvictOperation) context.metadata.operation;
        if (beforeInvocation == operation.isBeforeInvocation() && isConditionPassing(context, result)) {
            performCacheEvict(context, operation, result);
        }
    }
}

/**
 * 执行CacheEvict动作
 */
private void performCacheEvict(
    CacheOperationContext context, CacheEvictOperation operation, @Nullable Object result) {
    Object key = null;
    // 遍历cache动作上下文的所有缓存
    for (Cache cache : context.getCaches()) {
        // 缓存是否全部清除
        if (operation.isCacheWide()) {
            logInvalidating(context, operation, null);
            doClear(cache);
        }
        else {
            if (key == null) {
                key = generateKey(context, result);
            }
            logInvalidating(context, operation, key);
            // 请求单个缓存KEY
            doEvict(cache, key);
        }
    }
}

/**
 * 从允许执行的Cacheable动作中找到一个存在的缓存值
 */
@Nullable
private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
    Object result = CacheOperationExpressionEvaluator.NO_RESULT;
    // 遍历Cacheable动作
    for (CacheOperationContext context : contexts) {
        // 允许执行
        if (isConditionPassing(context, result)) {
            Object key = generateKey(context, result);
            // 查找缓存值
            Cache.ValueWrapper cached = findInCaches(context, key);
            if (cached != null) {
                // 命中缓存就返回
                return cached;
            }
            else {
                if (logger.isTraceEnabled()) {
                logger.trace("No cache entry for key '" + key + "' in cache(s) " + context.getCacheNames());
                }
            }
        }
    }
    return null;
}

/**
 * 从缓存动作上下文查找缓存值
 */
@Nullable
private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object key) {
    // 遍历缓存
    for (Cache cache : context.getCaches()) {
        // 查找指定缓存KEY
        Cache.ValueWrapper wrapper = doGet(cache, key);
        if (wrapper != null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Cache entry for key '" + key + "' found in cache '" + cache.getName() + "'");
            }
            return wrapper;
        }
    }
    return null;
}

/**
 * 收集CachePut动作
 */
private void collectPutRequests(Collection<CacheOperationContext> contexts,
    @Nullable Object result, Collection<CachePutRequest> putRequests) {
    // 遍历cache动作
    for (CacheOperationContext context : contexts) {
        // 允许执行
        if (isConditionPassing(context, result)) {
            Object key = generateKey(context, result);
            // Cacheable类似于CachePut
            putRequests.add(new CachePutRequest(context, key));
        }
    }
}

/**
 * 是否需要执行CachePut动作
 */
private boolean hasCachePut(CacheOperationContexts contexts) {
    // Evaluate the conditions *without* the result object because we don't have it yet…
    // 获取CachePut动作
    Collection<CacheOperationContext> cachePutContexts = contexts.get(CachePutOperation.class);
    Collection<CacheOperationContext> excluded = new ArrayList<>();
    // 遍历所有CachePut动作
    for (CacheOperationContext context : cachePutContexts) {
        try {
            if (!context.isConditionPassing(CacheOperationExpressionEvaluator.RESULT_UNAVAILABLE)) {
                // 无法执行的CachePut动作
                excluded.add(context);
            }
        }
        catch (VariableNotAvailableException ex) {
            // Ignoring failure due to missing result, consider the cache put has to proceed
        }
    }
    // 是否有需要执行的CachePut动作
    // Check if all puts have been excluded by condition
    return (cachePutContexts.size() != excluded.size());
}

/**
 * 缓存动作上下文
 * 内部类
 */
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;


    /**
     * cache注解的condition是否满足
     */
    protected boolean isConditionPassing(@Nullable Object result) {
        // 如果还未判断过,则进行判断;否则直接使用
        if (this.conditionPassing == null) {
            // condition属性不存在则默认为true
            if (StringUtils.hasText(this.metadata.operation.getCondition())) {
                // 根据result得出评估上下文
                EvaluationContext evaluationContext = createEvaluationContext(result);
                // 得出结论
                this.conditionPassing = evaluator.condition(this.metadata.operation.getCondition(),
                        this.metadata.methodKey, evaluationContext);
            }
            else {
                this.conditionPassing = true;
            }
        }
        return this.conditionPassing;
    }

    /**
     * 是否可以存入缓存
     */
    protected boolean canPutToCache(@Nullable Object value) {
        String unless = "";
        // Cacheable注解
        if (this.metadata.operation instanceof CacheableOperation) {
            unless = ((CacheableOperation) this.metadata.operation).getUnless();
        }
        // CachePut注解
        else if (this.metadata.operation instanceof CachePutOperation) {
            unless = ((CachePutOperation) this.metadata.operation).getUnless();
        }
        if (StringUtils.hasText(unless)) {
            EvaluationContext evaluationContext = createEvaluationContext(value);
            // 反逻辑
            return !evaluator.unless(unless, this.metadata.methodKey, evaluationContext);
        }
        return true;
    }
}


/**
 * 缓存动作上下文管理器
 * 内部类
 */
private class CacheOperationContexts {

    // cache动作上下文集合
    private final MultiValueMap<Class<? extends CacheOperation>, CacheOperationContext> contexts;
    // 同步标识
    private final boolean sync;


    /**
     * 构造方法
     * 集中管理CacheOperationSource解析出来的CacheOperation
     */
    public CacheOperationContexts(Collection<? extends CacheOperation> operations, Method method,
        Object[] args, Object target, Class<?> targetClass) {
        // 遍历cache operation集合
        this.contexts = new LinkedMultiValueMap<>(operations.size());
        for (CacheOperation op : operations) {
            // 添加cache operation上下文
            this.contexts.add(op.getClass(), getOperationContext(op, method, args, target, targetClass));
        }
        this.sync = determineSyncFlag(method);
    }

    /**
     * 获取某CacheOperation的所有上下文信息
     */
    public Collection<CacheOperationContext> get(Class<? extends CacheOperation> operationClass) {
        Collection<CacheOperationContext> result = this.contexts.get(operationClass);
        return (result != null ? result : Collections.emptyList());
    }
}


/**
 * 缓存动作的元数据
 * 内部类
 */
protected static class CacheOperationMetadata {

    // 缓存动作
    private final CacheOperation operation;
    // 方法
    private final Method method;
    // 目标类对象
    private final Class<?> targetClass;
    // 目标方法
    private final Method targetMethod;
    // 注解元素KEY
    private final AnnotatedElementKey methodKey;
    // 缓存KEY生成器
    private final KeyGenerator keyGenerator;
    // 缓存解析器
    private final CacheResolver cacheResolver;


    /**
     * 构造方法
     */
    public CacheOperationMetadata(CacheOperation operation, Method method, Class<?> targetClass,
            KeyGenerator keyGenerator, CacheResolver cacheResolver) {
        // 存储缓存动作的参数
        this.operation = operation;
        this.method = BridgeMethodResolver.findBridgedMethod(method);
        this.targetClass = targetClass;
        this.targetMethod = (!Proxy.isProxyClass(targetClass) ?
                AopUtils.getMostSpecificMethod(method, targetClass) : this.method);
        this.methodKey = new AnnotatedElementKey(this.targetMethod, targetClass);
        this.keyGenerator = keyGenerator;
        this.cacheResolver = cacheResolver;
    }
}


/**
 * CachePut动作
 * 内部类
 */
private class CachePutRequest {

    // 缓存动作上下文
    private final CacheOperationContext context;
    // 缓存KEY
    private final Object key;


    /**
     * 执行CachePut动作
     */
    public void apply(@Nullable Object result) {
        // 可以执行PUT动作
        if (this.context.canPutToCache(result)) {
            for (Cache cache : this.context.getCaches()) {
                // 将结果存入缓存
                doPut(cache, this.key, result);
            }
        }
    }
}


/**
 * 缓存动作KEY
 * 内部类
 */
private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {

    // 缓存动作
    private final CacheOperation cacheOperation;
    // 注解元素KEY
    private final AnnotatedElementKey methodCacheKey;


    /**
     * 比较
     */
    @Override
    public int compareTo(CacheOperationCacheKey other) {
         int result =     this.cacheOperation.getName().compareTo(other.cacheOperation.getName());
         if (result == 0) {
            result = this.methodCacheKey.compareTo(other.methodCacheKey);
         }
         return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值