zoukankan      html  css  js  c++  java
  • Spring 缓存切面

    缓存切面:【通知+目标方法调用】

    缓存操作执行过程:
    1)如果是同步调用【sync=true】,则首先尝试从缓存中读取数据,读取到则直接返回;
    否则执行目标方法,将结果缓存后返回。
    2)如果不是同步调用【sync=false,默认】
    2-1)执行 beforeInvocation=true 并满足条件的 CacheEvict 操作,
    2-2)从缓存操作上下文中根据缓存键读取数据【存在 @Cacheable 注解】,
        缓存未命中:则收集 @Cacheable 缓存写入请求,并执行目标方法。
        缓存命中且无满足条件的 CachePut 操作:直接读取缓存结果【目标方法不会被执行】。
    2-3)从 @CachePut 注解上收集显式的缓存写入操作。
    2-4)执行从 @Cacheable 和 @CachePut 上收集到的缓存写入操作。
    2-5)执行 beforeInvocation=false 并满足条件的 CacheEvict 操作。
    
    最佳实践:
    @CachePut 注解使用在写入和更新操作上
    @Cacheable 注解使用在读取操作上
    @CacheEvict 注解使用在删除操作上
    
    /**
     *  执行缓存操作的基础组件,附加缓存异常处理器
     */
    public abstract class AbstractCacheInvoker {
    
        protected SingletonSupplier<CacheErrorHandler> errorHandler;
    
        protected AbstractCacheInvoker() {
            // 不做任何事情的异常处理器
            this.errorHandler = SingletonSupplier.of(SimpleCacheErrorHandler::new);
        }
    
        protected AbstractCacheInvoker(CacheErrorHandler errorHandler) {
            this.errorHandler = SingletonSupplier.of(errorHandler);
        }
    
        public void setErrorHandler(CacheErrorHandler errorHandler) {
            this.errorHandler = SingletonSupplier.of(errorHandler);
        }
    
        public CacheErrorHandler getErrorHandler() {
            return this.errorHandler.obtain();
        }
    
        /**
         *  执行缓存 Get 操作
         */
        @Nullable
        protected Cache.ValueWrapper doGet(Cache cache, Object key) {
            try {
                return cache.get(key);
            }
            catch (RuntimeException ex) {
                getErrorHandler().handleCacheGetError(ex, cache, key);
                return null;  // If the exception is handled, return a cache miss
            }
        }
    
        /**
         *  执行缓存 Put 操作
         */
        protected void doPut(Cache cache, Object key, @Nullable Object result) {
            try {
                cache.put(key, result);
            }
            catch (RuntimeException ex) {
                getErrorHandler().handleCachePutError(ex, cache, key, result);
            }
        }
    
        /**
         *  执行缓存 Evict 操作
         */
        protected void doEvict(Cache cache, Object key) {
            try {
                cache.evict(key);
            }
            catch (RuntimeException ex) {
                getErrorHandler().handleCacheEvictError(ex, cache, key);
            }
        }
    
        /**
         *  执行缓存 Clear 操作
         */
        protected void doClear(Cache cache) {
            try {
                cache.clear();
            }
            catch (RuntimeException ex) {
                getErrorHandler().handleCacheClearError(ex, cache);
            }
        }
    }
    
    /**
     *  缓存切面的基础类
     */
    public abstract class CacheAspectSupport extends AbstractCacheInvoker
    implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {
        protected final Log logger = LogFactory.getLog(getClass());
        /**
         *  缓存操作元数据缓存
         */
        private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
        /**
         *  缓存操作表达式解析器
         */
        private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
        /**
         *  缓存操作源:用于将缓存注解解析为缓存操作
         */
        @Nullable
        private CacheOperationSource cacheOperationSource;
        /**
         *  单例键生成器  Supplier
         */
        private SingletonSupplier<KeyGenerator> keyGenerator = SingletonSupplier.of(SimpleKeyGenerator::new);
        /**
         *  单例缓存解析器 Supplier
         */
        @Nullable
        private SingletonSupplier<CacheResolver> cacheResolver;
        /**
         *  Bean 工厂【DefaultListableBeanFactory】
         */
        @Nullable
        private BeanFactory beanFactory;
        /**
         *  切面是否已经初始化
         */
        private boolean initialized = false;
    
        @Override
        public void afterSingletonsInstantiated() {
            if (getCacheResolver() == null) {
                // Lazily initialize cache resolver via default cache manager...
                Assert.state(beanFactory != null, "CacheResolver or BeanFactory must be set on cache aspect");
                try {
                    // 基于缓存管理器创建缓存解析器,并写入
                    setCacheManager(beanFactory.getBean(CacheManager.class));
                }
                catch (final NoUniqueBeanDefinitionException ex) {
                    throw new IllegalStateException("No CacheResolver specified, and no unique bean of type " +
                            "CacheManager found. Mark one as primary or declare a specific CacheManager to use.");
                }
                catch (final NoSuchBeanDefinitionException ex) {
                    throw new IllegalStateException("No CacheResolver specified, and no bean of type CacheManager found. " +
                            "Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.");
                }
            }
            initialized = true;
        }
    
        /**
         *  基于缓存操作执行上下文和缓存解析器读取缓存集合
         */
        protected Collection<? extends Cache> getCaches(
                CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver) {
            final Collection<? extends Cache> caches = cacheResolver.resolveCaches(context);
            if (caches.isEmpty()) {
                throw new IllegalStateException("No cache could be resolved for '" +
                        context.getOperation() + "' using resolver '" + cacheResolver +
                        "'. At least one cache should be provided per cache operation.");
            }
            return caches;
        }
    
            @Nullable
        protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
            // 缓存切面是否启用
            if (initialized) {
                // 读取目标类 Class
                final Class<?> targetClass = getTargetClass(target);
                // 读取缓存操作源
                final CacheOperationSource cacheOperationSource = getCacheOperationSource();
                if (cacheOperationSource != null) {
                    // 读取目标方法上的所有缓存操作
                    final 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();
        }
    
        protected CacheOperationContext getOperationContext(
                CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
            // 读取缓存操作元数据
            final CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass);
            return new CacheOperationContext(metadata, args, target);
        }
    
        protected CacheOperationMetadata getCacheOperationMetadata(
                CacheOperation operation, Method method, Class<?> targetClass) {
            // 缓存操作的缓存键
            final CacheOperationCacheKey cacheKey = new CacheOperationCacheKey(operation, method, targetClass);
            // 已经创建过则直接读取
            CacheOperationMetadata metadata = metadataCache.get(cacheKey);
            if (metadata == null) {
                KeyGenerator operationKeyGenerator;
                //  1)缓存操作配置了键生成器
                if (StringUtils.hasText(operation.getKeyGenerator())) {
                    // 写入指定 bean 名称的键生成器
                    operationKeyGenerator = getBean(operation.getKeyGenerator(), KeyGenerator.class);
                }
                else {
                    // 写入 SimpleKeyGenerator
                    operationKeyGenerator = getKeyGenerator();
                }
                CacheResolver operationCacheResolver;
                //  2)缓存操作配置了缓存解析器
                if (StringUtils.hasText(operation.getCacheResolver())) {
                    // 写入指定 bean 名称的缓存解析器
                    operationCacheResolver = getBean(operation.getCacheResolver(), CacheResolver.class);
                }
                // 3)缓存操作配置了缓存管理器
                else if (StringUtils.hasText(operation.getCacheManager())) {
                    final CacheManager cacheManager = getBean(operation.getCacheManager(), CacheManager.class);
                    // 基于目标缓存管理器创建 SimpleCacheResolver 并写入
                    operationCacheResolver = new SimpleCacheResolver(cacheManager);
                }
                else {
                    // 写入默认的 SimpleCacheResolver
                    operationCacheResolver = getCacheResolver();
                    Assert.state(operationCacheResolver != null, "No CacheResolver/CacheManager set");
                }
                // 创建缓存操作元数据并加入缓存
                metadata = new CacheOperationMetadata(operation, method, targetClass,
                        operationKeyGenerator, operationCacheResolver);
                metadataCache.put(cacheKey, metadata);
            }
            return metadata;
        }
    
        protected <T> T getBean(String beanName, Class<T> expectedType) {
            if (beanFactory == null) {
                throw new IllegalStateException(
                        "BeanFactory must be set on cache aspect for " + expectedType.getSimpleName() + " retrieval");
            }
            return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, expectedType, beanName);
        }
    
        /**
         * Clear the cached metadata.
         */
        protected void clearMetadataCache() {
            metadataCache.clear();
            evaluator.clear();
        }
    
        @Nullable
        protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
            // 缓存切面是否启用
            if (initialized) {
                // 读取目标类 Class
                final Class<?> targetClass = getTargetClass(target);
                // 读取缓存操作源
                final CacheOperationSource cacheOperationSource = getCacheOperationSource();
                if (cacheOperationSource != null) {
                    // 读取目标方法上的所有缓存操作
                    final 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();
        }
    
        /**
         *  执行底层目标方法
         */
        protected Object invokeOperation(CacheOperationInvoker invoker) {
            return invoker.invoke();
        }
    
        private Class<?> getTargetClass(Object target) {
            return AopProxyUtils.ultimateTargetClass(target);
        }
    
        @Nullable
        private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
            // 1)同步调用的特殊处理
            if (contexts.isSynchronized()) {
                final CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
                // 缓存操作条件是否匹配
                if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
                    // 计算缓存键
                    final Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
                    // 读取缓存
                    final Cache cache = context.getCaches().iterator().next();
                    try {
                        /**
                         *  如果缓存已经存在,则直接读取;否则执行目标方法,并将其结果值加入缓存。
                         *  并将结果值进行封装
                         */
                        return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
                    }
                    catch (final Cache.ValueRetrievalException ex) {
                        throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();
                    }
                }
                else {
                    //  缓存操作条件不匹配,则直接调用目标方法
                    return invokeOperation(invoker);
                }
            }
    
    
            /**
             *  1)处理方法调用前的缓存清除
             *  如果指定了 CacheEvictOperation 操作 && beforeInvocation==true && 满足缓存操作条件,则执行缓存清除
             */
            processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
                    CacheOperationExpressionEvaluator.NO_RESULT);
    
            /**
             *  2)从缓存操作上下文中,读取指定缓存键相关的条目
             */
            final Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
    
            // 缓存未命中,则收集 @Cacheable 缓存写入请求【结果变量 result 不可用】
            final List<CachePutRequest> cachePutRequests = new LinkedList<>();
            if (cacheHit == null) {
                collectPutRequests(contexts.get(CacheableOperation.class),
                        CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
            }
    
            Object cacheValue;
            Object returnValue;
            // 1)命中缓存
            if (cacheHit != null && !hasCachePut(contexts)) {
                // 无 CachePut 操作,则直接使用命中的缓存结果
                cacheValue = cacheHit.get();
                returnValue = wrapCacheValue(method, cacheValue);
            }
            else {
                // 缓存未命中,则执行目标方法
                returnValue = invokeOperation(invoker);
                cacheValue = unwrapReturnValue(returnValue);
            }
    
            // 收集所有显式的 @CachePut 操作
            collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
    
            // 执行从 @CachePut or @Cacheable 收集到的缓存写入操作
            for (final CachePutRequest cachePutRequest : cachePutRequests) {
                cachePutRequest.apply(cacheValue);
            }
    
            // 执行方法执行后的缓存清除操作
            processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);
            return returnValue;
        }
    
        @Nullable
        private Object wrapCacheValue(Method method, @Nullable Object cacheValue) {
            // 方法的返回结果为 Optional,则进行封装
            if (method.getReturnType() == Optional.class &&
                    (cacheValue == null || cacheValue.getClass() != Optional.class)) {
                return Optional.ofNullable(cacheValue);
            }
            return cacheValue;
        }
    
        @Nullable
        private Object unwrapReturnValue(Object returnValue) {
            return ObjectUtils.unwrapOptional(returnValue);
        }
    
        private boolean hasCachePut(CacheOperationContexts contexts) {
            // 读取 CachePutOperation 的上下文集合
            final Collection<CacheOperationContext> cachePutContexts = contexts.get(CachePutOperation.class);
            final Collection<CacheOperationContext> excluded = new ArrayList<>();
            for (final CacheOperationContext context : cachePutContexts) {
                try {
                    // 缓存操作条件不匹配,则写入 excluded
                    if (!context.isConditionPassing(CacheOperationExpressionEvaluator.RESULT_UNAVAILABLE)) {
                        excluded.add(context);
                    }
                }
                catch (final VariableNotAvailableException ex) {
                }
            }
            // 检查所有put是否已按条件排除
            return cachePutContexts.size() != excluded.size();
        }
    
        private void processCacheEvicts(
                Collection<CacheOperationContext> contexts, boolean beforeInvocation, @Nullable Object result) {
            for (final CacheOperationContext context : contexts) {
                final CacheEvictOperation operation = (CacheEvictOperation) context.metadata.operation;
                // 满足缓存清除条件,则执行缓存清除
                if (beforeInvocation == operation.isBeforeInvocation() && isConditionPassing(context, result)) {
                    performCacheEvict(context, operation, result);
                }
            }
        }
    
        private void performCacheEvict(
                CacheOperationContext context, CacheEvictOperation operation, @Nullable Object result) {
            Object key = null;
            for (final Cache cache : context.getCaches()) {
                // 1)是否清缓存中的所有条目,默认为 false
                if (operation.isCacheWide()) {
                    logInvalidating(context, operation, null);
                    // 清除缓存中的所有条目
                    doClear(cache);
                }
                else {
                    if (key == null) {
                        // 计算缓存键
                        key = generateKey(context, result);
                    }
                    logInvalidating(context, operation, key);
                    // 清除指定键关联的条目
                    doEvict(cache, key);
                }
            }
        }
    
        private void logInvalidating(CacheOperationContext context, CacheEvictOperation operation, @Nullable Object key) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invalidating " + (key != null ? "cache key [" + key + "]" : "entire cache") +
                        " for operation " + operation + " on method " + context.metadata.method);
            }
        }
    
        @Nullable
        private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
            final Object result = CacheOperationExpressionEvaluator.NO_RESULT;
            for (final CacheOperationContext context : contexts) {
                // 匹配缓存操作条件
                if (isConditionPassing(context, result)) {
                    final Object key = generateKey(context, result);
                    // 从缓存中查找值
                    final 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;
        }
    
        private void collectPutRequests(Collection<CacheOperationContext> contexts,
                @Nullable Object result, Collection<CachePutRequest> putRequests) {
            for (final CacheOperationContext context : contexts) {
                if (isConditionPassing(context, result)) {
                    final Object key = generateKey(context, result);
                    // 添加缓存写入请求
                    putRequests.add(new CachePutRequest(context, key));
                }
            }
        }
    
        @Nullable
        private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object key) {
            // 读取所有关联的缓存实例
            for (final Cache cache : context.getCaches()) {
                /**
                 *  基于缓存键读取值,如果找到则返回【
                 *  可引入本地缓存+Redis缓存模式,本地缓存优先读取】
                 */
                final 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;
        }
    
        /**
         *  缓存操作条件是否匹配
         */
        private boolean isConditionPassing(CacheOperationContext context, @Nullable Object result) {
            final boolean passing = context.isConditionPassing(result);
            if (!passing && logger.isTraceEnabled()) {
                logger.trace("Cache condition failed on method " + context.metadata.method +
                        " for operation " + context.metadata.operation);
            }
            return passing;
        }
    
        /**
         *  计算缓存键
         */
        private Object generateKey(CacheOperationContext context, @Nullable Object result) {
            final Object key = context.generateKey(result);
            if (key == null) {
                throw new IllegalArgumentException("Null key returned for cache operation (maybe you are " +
                        "using named params on classes without debug info?) " + context.metadata.operation);
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Computed cache key '" + key + "' for operation " + context.metadata.operation);
            }
            return key;
        }
    
        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) {
                contexts = new LinkedMultiValueMap<>(operations.size());
                for (final CacheOperation op : operations) {
                    // 写入映射
                    contexts.add(op.getClass(), getOperationContext(op, method, args, target, targetClass));
                }
                // 写入同步执行标识
                sync = determineSyncFlag(method);
            }
    
            /**
             *  读取指定操作的 CacheOperationContext 集合
             */
            public Collection<CacheOperationContext> get(Class<? extends CacheOperation> operationClass) {
                final Collection<CacheOperationContext> result = contexts.get(operationClass);
                return result != null ? result : Collections.emptyList();
            }
    
            public boolean isSynchronized() {
                return sync;
            }
    
            private boolean determineSyncFlag(Method method) {
                // 1)无 @Cacheable 操作,sync 为 false
                final List<CacheOperationContext> cacheOperationContexts = contexts.get(CacheableOperation.class);
                if (cacheOperationContexts == null) {  // no @Cacheable operation at all
                    return false;
                }
                boolean syncEnabled = false;
                // 2)至少存在一个 @Cacheable 操作的 sync 标识位为 true,则 sync 为 true
                for (final CacheOperationContext cacheOperationContext : cacheOperationContexts) {
                    if (((CacheableOperation) cacheOperationContext.getOperation()).isSync()) {
                        syncEnabled = true;
                        break;
                    }
                }
                /**
                 *  3)如果 sync 为 true
                 *  不能指定多个缓存操作
                 *  Cacheable 操作不能关联多个缓存
                 *  不能指定 unless 条件
                 */
                if (syncEnabled) {
                    if (contexts.size() > 1) {
                        throw new IllegalStateException(
                                "@Cacheable(sync=true) cannot be combined with other cache operations on '" + method + "'");
                    }
                    if (cacheOperationContexts.size() > 1) {
                        throw new IllegalStateException(
                                "Only one @Cacheable(sync=true) entry is allowed on '" + method + "'");
                    }
                    final CacheOperationContext cacheOperationContext = cacheOperationContexts.iterator().next();
                    final CacheableOperation operation = (CacheableOperation) cacheOperationContext.getOperation();
                    if (cacheOperationContext.getCaches().size() > 1) {
                        throw new IllegalStateException(
                                "@Cacheable(sync=true) only allows a single cache on '" + operation + "'");
                    }
                    if (StringUtils.hasText(operation.getUnless())) {
                        throw new IllegalStateException(
                                "@Cacheable(sync=true) does not support unless attribute on '" + operation + "'");
                    }
                    return true;
                }
                return false;
            }
        }
    
    
        /**
         *  缓存操作的元数据
         */
        protected static class CacheOperationMetadata {
            private final CacheOperation operation;
            private final Method method;
            private final Class<?> targetClass;
            private final Method targetMethod;
            /**
             *  封装了注解元素和目标类型的 AnnotatedElementKey
             */
            private final AnnotatedElementKey methodKey;
            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;
                targetMethod = !Proxy.isProxyClass(targetClass) ?
                        AopUtils.getMostSpecificMethod(method, targetClass) : this.method;
                        methodKey = new AnnotatedElementKey(targetMethod, targetClass);
                        this.keyGenerator = keyGenerator;
                        this.cacheResolver = cacheResolver;
            }
        }
    
    
        /**
         *  缓存操作上下文
         */
        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;
                caches = CacheAspectSupport.this.getCaches(this, metadata.cacheResolver);
                cacheNames = createCacheNames(caches);
            }
    
            @Override
            public CacheOperation getOperation() {
                return metadata.operation;
            }
    
            @Override
            public Object getTarget() {
                return target;
            }
    
            @Override
            public Method getMethod() {
                return metadata.method;
            }
    
            @Override
            public Object[] getArgs() {
                return args;
            }
    
            private Object[] extractArgs(Method method, Object[] args) {
                if (!method.isVarArgs()) {
                    return args;
                }
                final Object[] varArgs = ObjectUtils.toObjectArray(args[args.length - 1]);
                final Object[] combinedArgs = new Object[args.length - 1 + varArgs.length];
                System.arraycopy(args, 0, combinedArgs, 0, args.length - 1);
                System.arraycopy(varArgs, 0, combinedArgs, args.length - 1, varArgs.length);
                return combinedArgs;
            }
    
            protected boolean isConditionPassing(@Nullable Object result) {
                if (conditionPassing == null) {
                    // 1)注解的缓存条件不为空
                    if (StringUtils.hasText(metadata.operation.getCondition())) {
                        // 创建计算上下文
                        final EvaluationContext evaluationContext = createEvaluationContext(result);
                        // 基于 CacheOperationExpressionEvaluator 计算目标条件
                        conditionPassing = evaluator.condition(metadata.operation.getCondition(),
                                metadata.methodKey, evaluationContext);
                    }
                    else {
                        // 2)未指定条件默认匹配
                        conditionPassing = true;
                    }
                }
                return conditionPassing;
            }
    
            /**
             *  unless 条件未指定或为 false 时,才允许将结果加入到缓存中
             */
            protected boolean canPutToCache(@Nullable Object value) {
                String unless = "";
                // 1)从 CacheableOperation 读取 unless 条件
                if (metadata.operation instanceof CacheableOperation) {
                    unless = ((CacheableOperation) metadata.operation).getUnless();
                }
                // 2)从 CachePutOperation 读取 unless 条件
                else if (metadata.operation instanceof CachePutOperation) {
                    unless = ((CachePutOperation) metadata.operation).getUnless();
                }
                // 如果 unless 条件不为空,则计算其值
                if (StringUtils.hasText(unless)) {
                    final EvaluationContext evaluationContext = createEvaluationContext(value);
                    return !evaluator.unless(unless, metadata.methodKey, evaluationContext);
                }
                // 未指定,则默认将结果加入缓存中
                return true;
            }
    
            /**
             * Compute the key for the given caching operation.
             */
            @Nullable
            protected Object generateKey(@Nullable Object result) {
                // 1)基于指定的 SpEL 表达式解析缓存键
                if (StringUtils.hasText(metadata.operation.getKey())) {
                    final EvaluationContext evaluationContext = createEvaluationContext(result);
                    return evaluator.key(metadata.operation.getKey(), metadata.methodKey, evaluationContext);
                }
    
                // 2)基于键生成器生成缓存键
                return metadata.keyGenerator.generate(target, metadata.method, args);
            }
    
            private EvaluationContext createEvaluationContext(@Nullable Object result) {
                return evaluator.createEvaluationContext(caches, metadata.method, args,
                        target, metadata.targetClass, metadata.targetMethod, result, beanFactory);
            }
    
            protected Collection<? extends Cache> getCaches() {
                return caches;
            }
    
            protected Collection<String> getCacheNames() {
                return cacheNames;
            }
    
            private Collection<String> createCacheNames(Collection<? extends Cache> caches) {
                final Collection<String> names = new ArrayList<>();
                for (final Cache cache : caches) {
                    names.add(cache.getName());
                }
                return names;
            }
        }
    
    
        private class CachePutRequest {
            /**
             *  缓存操作上下文
             */
            private final CacheOperationContext context;
            /**
             *  缓存键
             */
            private final Object key;
    
            public CachePutRequest(CacheOperationContext context, Object key) {
                this.context = context;
                this.key = key;
            }
    
            public void apply(@Nullable Object result) {
                // 方法执行结果是否需要加入缓存中
                if (context.canPutToCache(result)) {
                    // 将结果加入相关的缓存中
                    for (final Cache cache : context.getCaches()) {
                        doPut(cache, key, result);
                    }
                }
            }
        }
    
        private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {
            /**
             *  缓存操作
             */
            private final CacheOperation cacheOperation;
            /**
             *  注解元素
             */
            private final AnnotatedElementKey methodCacheKey;
    
            private CacheOperationCacheKey(CacheOperation cacheOperation, Method method, Class<?> targetClass) {
                this.cacheOperation = cacheOperation;
                methodCacheKey = new AnnotatedElementKey(method, targetClass);
            }
    
            @Override
            public boolean equals(Object other) {
                if (this == other) {
                    return true;
                }
                if (!(other instanceof CacheOperationCacheKey)) {
                    return false;
                }
                final CacheOperationCacheKey otherKey = (CacheOperationCacheKey) other;
                return cacheOperation.equals(otherKey.cacheOperation) &&
                        methodCacheKey.equals(otherKey.methodCacheKey);
            }
    
            @Override
            public int hashCode() {
                return cacheOperation.hashCode() * 31 + methodCacheKey.hashCode();
            }
    
            @Override
            public String toString() {
                return cacheOperation + " on " + methodCacheKey;
            }
    
            @Override
            public int compareTo(CacheOperationCacheKey other) {
                int result = cacheOperation.getName().compareTo(other.cacheOperation.getName());
                if (result == 0) {
                    result = methodCacheKey.compareTo(other.methodCacheKey);
                }
                return result;
            }
        }
    
    }
    
    /**
     *  声明式缓存管理 MethodInterceptor
     */
    @SuppressWarnings("serial")
    public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
        @Override
        @Nullable
        public Object invoke(final MethodInvocation invocation) throws Throwable {
            // 读取目标方法
            Method method = invocation.getMethod();
            CacheOperationInvoker aopAllianceInvoker = () -> {
                try {
                    return invocation.proceed();
                }
                catch (Throwable ex) {
                    throw new CacheOperationInvoker.ThrowableWrapper(ex);
                }
            };
    
            try {
                // 执行核心操作
                return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
            }
            catch (CacheOperationInvoker.ThrowableWrapper th) {
                throw th.getOriginal();
            }
        }
    }
    
  • 相关阅读:
    tornado用户指引(三)------tornado协程使用和原理(二)
    利用tornado使请求实现异步非阻塞
    在tornado中使用异步mysql操作
    Tornado 线程池应用
    Tornado异步与延迟任务
    tornado用户指引(二)------------tornado协程实现原理和使用(一)
    Tornado用户指引(一)-----------异步和非阻塞I/O
    Tornado异步之-协程与回调
    Python核心框架tornado的异步协程的2种方式
    c++ Map使用
  • 原文地址:https://www.cnblogs.com/zhuxudong/p/10322611.html
Copyright © 2011-2022 走看看