Spring中@EnableCache的原理

@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {

}

// 导入其他类的一个bean
public class CachingConfigurationSelector extends AdviceModeImportSelector<EnableCaching> {
    public String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
            case PROXY:
                return getProxyImports() {
                List<String> result = new ArrayList<>(3);
                // 注册AutoProxyRegistrar和ProxyCachingConfiguration
                result.add(. class.getName());
                result.add(ProxyCachingConfiguration.class.getName());
                if (jsr107Present && jcacheImplPresent) {
                    result.add(PROXY_JCACHE_CONFIGURATION_CLASS);
                }
                return StringUtils.toStringArray(result);
            }
            case ASPECTJ:
                return getAspectJImports();
            default:
                return null;
        }
    }
}

// 负责注入创建AOP对象的BeanPostProcessor
// 事务注解也会注入的这类,它会负责注入创建代理对象的BeanPostProcessor
// 用来给目标类创建代理对象
class AutoProxyRegistrar {
    // 注册Bean
    // importingClassMetadata是正在解析的配置类对应的元数据信息,也就是标注@EnableTransactionManagement这个类的配置类
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 获取配置类上的所有注解
        Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
        for (String annType : annTypes) {
            // 遍历所有的注解
            AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
            // 找到一些符合AOP条件的共性,mode,proxyTargetClass等等
            Object mode = candidate.get("mode");
            Object proxyTargetClass = candidate.get("proxyTargetClass");
            // 如果符合这个条件,表示当前类需要进行AOP
            if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
                candidateFound = true;
                // 判断当前配置类的代理模式
                if (mode == AdviceMode.PROXY) {
                    // 注册创建AOP代理对象的BeanPostProcessor,InfrastructureAdvisorAutoProxyCreator
                    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                    // 如果proxyTargetClass为true,表示使用CGLIB代理
                     /*
                        三种情况
                           1. proxyTargetClass =false(默认值) 目标实现了接口 JDK代理
                           2. proxyTargetClass =false(默认值) 目标未实现接口 CGLIB代理
                           3. proxyTargetClass =true 总是CGLIB代理
                     */
                    if ((Boolean) proxyTargetClass) {
                        // 强制设置创建代理的使用使用CGLIB代理
                        AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                        return;
                    }
                }
            }
        }

    }
}

// 和事务的ProxyTransactionManagementConfiguration配置几乎类似
// 准确来说是需要创建代理对象的场景都需要下面配置,配置切面,拦截器,解析注解的数据源
class ProxyCachingConfiguration extends AbstractCachingConfiguration implements ImportAware {
    // EnableCaching的元信息
    protected AnnotationAttributes enableCaching;
    // 缓存管理器
    protected Supplier<CacheManager> cacheManager;
    // 缓存解析器
    protected Supplier<CacheResolver> cacheResolver;
    // 缓存key的生成器
    protected Supplier<KeyGenerator> keyGenerator;
    // 缓存的异常处理器
    protected Supplier<CacheErrorHandler> errorHandler;

    public void setImportMetadata(AnnotationMetadata importMetadata) {
        // 获取到EnableCaching注解的元信息
        this.enableCaching = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false));
    }

    @Bean(name = "internalCacheAdvisor")
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryCacheOperationSourceAdvisor cacheAdvisor() {
        // 创建用于缓存的切面
        BeanFactoryCacheOperationSourceAdvisor advisor = new BeanFactoryCacheOperationSourceAdvisor() {
            // 缓存操作源的切面对象
            // 切面内部的切点,是依靠CacheOperationSource来创建的
            private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
                protected CacheOperationSource getCacheOperationSource() {
                    // cacheOperationSource用来解析@CacheXXX属性源对象,内部封装了注解的元信息
                    return cacheOperationSource;
                }

            };
        }
        // 设置注解的操作元数据
        advisor.setCacheOperationSource(cacheOperationSource());
        // 设置通知,增强器,拦截器
        advisor.setAdvice(cacheInterceptor());
        // 如果开启了@EnableCaching注解
        if (this.enableCaching != null) {
            // 设置顺序
            advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
        }
        // 返回切面
        return advisor;
    }

    // 处理注解CacheXXX注解的类
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public CacheOperationSource cacheOperationSource() {
        return new AnnotationCacheOperationSource() {
            // 是否只支持public方法,默认为true
            this.publicMethodsOnly =publicMethodsOnly;
            // 创建SpringCache的注解解析器
		    this.annotationParsers =Collections.singleton(new

            SpringCacheAnnotationParser() {
                // 注解解析器支持的注解类型
                static {
                    CACHE_OPERATION_ANNOTATIONS.add(Cacheable.class);
                    CACHE_OPERATION_ANNOTATIONS.add(CacheEvict.class);
                    CACHE_OPERATION_ANNOTATIONS.add(CachePut.class);
                    // 因为上面这三个注解可以混合使用
                    // 这个注解就相当于上面三个混合使用的集合
                    CACHE_OPERATION_ANNOTATIONS.add(Caching.class);
                }
            });
        }
    }

    // 通知,增强器
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public CacheInterceptor cacheInterceptor() {
        // 新建通知,拦截器
        CacheInterceptor interceptor = new CacheInterceptor();
        // 自定义配置拦截器
        interceptor.configure(this.errorHandler, this.keyGenerator, this.cacheResolver, this.cacheManager) {
            // 异常管理器,如果没有,给默认的
            this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new);
            // 缓存key生成器,如果没有,使用默认的
            this.keyGenerator = new SingletonSupplier<>(keyGenerator, SimpleKeyGenerator::new);
            // 缓存解析器,如果没有,
            this.cacheResolver = new SingletonSupplier<>(cacheResolver, () -> SimpleCacheResolver.of(SupplierUtils.resolve(cacheManager)) {
                return(cacheManager !=null?new

                SimpleCacheResolver(cacheManager) :null);
            });
        }
        // 设置注解的属性元信息
        interceptor.setCacheOperationSource(cacheOperationSource());
        // 返回拦截器
        return interceptor;
    }
}

// 通过AutoProxyRegistrar注入的,为了创建代理对象
class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
    // 创建代理对象
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            // 获取缓存Key
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // 是否被提前引用,已经创建过代理对象了
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 创建代理对象,如果需要的话,具体的详见SpringAop原理,获取提前引用对象以及wrapIfNecessary是否需要创建代理对象原理
                return wrapIfNecessary(bean, beanName, cacheKey) {
                    // 这里讲缓存相关代理的实现
                    // 获取到可以作用到Bean的切面
                    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null) {
                        // 找到合格的切面
                        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName) {
                            // 从容器中找所有Advisor的切面,这个时候就可以找到上面注册的这个
                            // BeanFactoryCacheOperationSourceAdvisor
                            List<Advisor> candidateAdvisors = findCandidateAdvisors();
                            // 从所有的candidateAdvisors切面中,筛选作用于当前Bean的切面
                            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName)
                            {
                                // 遍历所有的切面
                                for (Advisor candidate : candidateAdvisors) {
                                    // 调用canApply
                                    if (canApply(candidate, clazz, hasIntroductions) {
                                        // BeanFactoryCacheOperationSourceAdvisor
                                        // 这个切面就是切点类型的切面
                                        if (advisor instanceof PointcutAdvisor) {
                                            PointcutAdvisor pca = (PointcutAdvisor) advisor;
                                            return canApply(pca.getPointcut(), targetClass, hasIntroductions) {
                                                // 先通过切点中的类匹配器来对目标类进行校验
                                                // 创建的是CacheOperationSourcePointcut切点
                                                // 	private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
                                                //		protected CacheOperationSource getCacheOperationSource() {
                                                //			return cacheOperationSource;
                                                //		}
                                                //	};
                                                // 创建切点的时候,设置了一个默认的类过滤器CacheOperationSourceClassFilter
                                                // protected CacheOperationSourcePointcut() {
                                                //     setClassFilter(new CacheOperationSourceClassFilter());
                                                // }
                                                // 调用CacheOperationSourceClassFilter的matchs方法
                                                if (!pc.getClassFilter().matches(targetClass) {
                                                    // bean为CacheManager,不处理
                                                    if (CacheManager.class.isAssignableFrom(clazz)) {
                                                        return false;
                                                    }
                                                    // 获取到缓存操作数据源,在注册BeanFactoryCacheOperationSourceAdvisor的Bean的时候设置了
                                                    // 为AnnotationCacheOperationSource
                                                    CacheOperationSource cas = getCacheOperationSource();
                                                    // 调用该类的校验方法
                                                    // isCandidateClass方法就是校验bean是否是Java内部的类,以及注解是不是java内部的注解
                                                    // 如果不是java内部的,统一返回true
                                                    return (cas == null || cas.isCandidateClass(clazz));
                                                }){
                                                    // 类都匹配失败,就没必要匹配方法了
                                                    return false;
                                                }
                                                // 上面类型匹配成功,开始匹配方法,毕竟方法才能执行
                                                // 获取的就是CacheOperationSourcePointcut切点本身
                                                MethodMatcher methodMatcher = pc.getMethodMatcher();
                                                if (methodMatcher == MethodMatcher.TRUE) {
                                                    return true;
                                                }
                                                // 保存所有的类,因为类可能会实现接口,接口中又有默认方法
                                                // 总之就是要校验所有类或者接口的所有方法
                                                Set<Class<?>> classes = new LinkedHashSet<>();
                                                // 如果不是jdk代理,将目标类也添加进去,因为jdk代理返回的是接口
                                                if (!Proxy.isProxyClass(targetClass)) {
                                                    classes.add(ClassUtils.getUserClass(targetClass));
                                                }
                                                // 在添加目标类实现的所有接口
                                                classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
                                                // 遍历所有的类和接口
                                                for (Class<?> clazz : classes) {
                                                    // 获取类中所有的方法
                                                    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                                                    for (Method method : methods) {
                                                        // 调用方法匹配器的匹配方法
                                                        return methodMatcher.matches(method, targetClass)){
                                                            // 获取缓存操作的数据源
                                                            CacheOperationSource cas = getCacheOperationSource();
                                                            // 获取有没有缓存相关的注解信息
                                                            return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)
                                                            {
                                                                // 获取缓存Key,防止重复操作
                                                                Object cacheKey = getCacheKey(method, targetClass);
                                                                // 获取是否操作过
                                                                Collection<CacheOperation> cached = this.attributeCache.get(cacheKey);
                                                                // 如果之前操作过,直接返回之前的结果
                                                                if (cached != null) {
                                                                    return (cached != NULL_CACHING_ATTRIBUTE ? cached : null);
                                                                }
                                                                // 之前没有解析过缓存相关注解
                                                                else {
                                                                    // 计算缓存操作,解析缓存注解信息
                                                                    // 这里和事务注解逻辑几乎一样
                                                                    Collection<CacheOperation> cacheOps = computeCacheOperations(method, targetClass)
                                                                    {
                                                                        // 如何设置了只允许public方法,但是方法又不是public,不处理
                                                                        // allowPublicMethodsOnly默认为true
                                                                        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
                                                                            return null;
                                                                        }
                                                                        // method是从外面传递过来的,要单独处理JDK动态代理
                                                                        // specificMethod是被调用的类的方法对象,method可能是原始方法,CBLIB方法,也可能是接口的方法对象
                                                                        // 例如:targetClass = B  B impl A  =>  B.test()  此时,specificMethod = B.test() , method = A.test()
                                                                        Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

                                                                        // 第一次解析,解析正在处理的目标类中方法的缓存注解
                                                                        Collection<CacheOperation> opDef = findCacheOperations(specificMethod)
                                                                        {
                                                                            // 解析缓存注解
                                                                            CacheOperationProvider provider = parser -> parser.parseCacheAnnotations(method)
                                                                            {
                                                                                // 创建默认的缓存配置
                                                                                DefaultCacheConfig defaultConfig = new DefaultCacheConfig(method.getDeclaringClass());
                                                                                // 解析注解
                                                                                return parseCacheAnnotations(defaultConfig, method)
                                                                                {
                                                                                    // 正式解析注解
                                                                                    Collection<CacheOperation> ops = parseCacheAnnotations(cachingConfig, ae, false)
                                                                                    {
                                                                                        // CACHE_OPERATION_ANNOTATIONS在静态代码块初始化了包含Cacheable,CacheEvict,CachePut,Caching
                                                                                        // 获取方法中存在的缓存相关的注解信息
                                                                                        Collection<? extends Annotation> anns = (localOnly ?
                                                                                                // 只会解析当前元素本身上的注解,例如接口上有注解,实现类中也有注解,此时只会返回元素本身的注解
                                                                                                AnnotatedElementUtils.getAllMergedAnnotations(ae, CACHE_OPERATION_ANNOTATIONS) :
                                                                                                // 会考虑元素的继承,例如接口上有注解,实现类中也有注解,此时会返回两个注解
                                                                                                AnnotatedElementUtils.findAllMergedAnnotations(ae, CACHE_OPERATION_ANNOTATIONS));
                                                                                        // 不存在,返回null
                                                                                        if (anns.isEmpty()) {
                                                                                            return null;
                                                                                        }
                                                                                        // 存在缓存注解
                                                                                        final Collection<CacheOperation> ops = new ArrayList<>(1);
                                                                                        // 过滤Cacheable注解,进行处理
                                                                                        anns.stream().filter(ann -> ann instanceof Cacheable).forEach(ann -> ops.add(parseCacheableAnnotation(ae, cachingConfig, (Cacheable) ann)
                                                                                        {
                                                                                            // 就是根据注解创建CacheableOperation对象,下面几个都一样
                                                                                            CacheableOperation.Builder builder = new CacheableOperation.Builder();
                                                                                            builder.setName(ae.toString());
                                                                                            builder.setCacheNames(cacheable.cacheNames());
                                                                                            builder.setSync(cacheable.sync());
                                                                                            CacheableOperation op = builder.build();
                                                                                            // 校验注解参数是否合法
                                                                                            validateCacheOperation(ae, op)
                                                                                            {
                                                                                                // KeyGenerator是bean的名称,会通过这个KeyGeneratorBean来生成缓存key,如果给定了key,又给定了生成器,抛出异常
                                                                                                if (StringUtils.hasText(operation.getKey()) && StringUtils.hasText(operation.getKeyGenerator())) {
                                                                                                    throw new IllegalStateException("Invalid cache annotation configuration on '");
                                                                                                }
                                                                                                // 缓存管理器的bean与缓存解析器的bean也不能同时存在
                                                                                                if (StringUtils.hasText(operation.getCacheManager()) && StringUtils.hasText(operation.getCacheResolver())) {
                                                                                                    throw new IllegalStateException("Invalid cache annotation configuration on '");
                                                                                                }
                                                                                            }
                                                                                        }));
                                                                                        // 过滤CacheEvict注解,进行处理
                                                                                        anns.stream().filter(ann -> ann instanceof CacheEvict).forEach(ann -> ops.add(parseEvictAnnotation(ae, cachingConfig, (CacheEvict) ann)));
                                                                                        // 过滤CachePut注解,进行处理
                                                                                        anns.stream().filter(ann -> ann instanceof CachePut).forEach(ann -> ops.add(parsePutAnnotation(ae, cachingConfig, (CachePut) ann)));
                                                                                        // 过滤Caching注解,进行处理
                                                                                        anns.stream().filter(ann -> ann instanceof Caching).forEach(ann -> parseCachingAnnotation(ae, cachingConfig, (Caching) ann, ops));
                                                                                        return ops;
                                                                                    }
                                                                                    // 如果解析到了缓存注解包装的CacheOperation信息,并且存在多个
                                                                                    // 表示可能类与接口中方法中都声明了相同缓存注解,所以存在多个
                                                                                    // 总之这里多次解析就是防止解析重复的注解
                                                                                    if (ops != null && ops.size() > 1) {
                                                                                        // 需要重新解析一遍,参数为true:表示直接解析当前Bean中的方法的注解,继承的注解不处理
                                                                                        Collection<CacheOperation> localOps = parseCacheAnnotations(cachingConfig, ae, true);
                                                                                        // 返回解析到的注解
                                                                                        if (localOps != null) {
                                                                                            return localOps;
                                                                                        }
                                                                                    }
                                                                                    return ops;
                                                                                }
                                                                            } ;
                                                                            // 确定类中以及方法中所有的缓存操作
                                                                            return determineCacheOperations(provider) {
                                                                            // 使用缓存注解解析器解析缓存注解
                                                                            for (CacheAnnotationParser parser : this.annotationParsers) {
                                                                                // 解析完成之后缓存注解信息被封装成CacheOperation
                                                                                Collection<CacheOperation> annOps = provider.getCacheOperations(parser);
                                                                                // 如果存在缓存注解信息
                                                                                if (annOps != null) {
                                                                                    // 赋值给ops
                                                                                    if (ops == null) {
                                                                                        ops = annOps;
                                                                                    }
                                                                                    // 如果ops不为空,将又有的缓存注解信息与新解析的缓存注解信息合并
                                                                                    else {
                                                                                        Collection<CacheOperation> combined = new ArrayList<>(ops.size() + annOps.size());
                                                                                        combined.addAll(ops);
                                                                                        combined.addAll(annOps);
                                                                                        ops = combined;
                                                                                    }
                                                                                }
                                                                            }
                                                                            // 返回解析过后的注解信息
                                                                            return ops;
                                                                        }
                                                                        }
                                                                        // 如果解析到了缓存注解信息,直接结束,因为可以确定需要aop
                                                                        if (opDef != null) {
                                                                            return opDef;
                                                                        }

                                                                        // 第二次解析,正在调用的目标类中的方法中不存在缓存注解,再解析该类上的注解
                                                                        opDef = findCacheOperations(specificMethod.getDeclaringClass());
                                                                        // 类中解析到了,表示也需要代理
                                                                        if (opDef != null && ClassUtils.isUserLevelMethod(method)) {
                                                                            return opDef;
                                                                        }
                                                                        // specificMethod是被调用的类的方法对象,根据上面注释代码,method可能是原始方法,CBLIB方法,也可能是接口的方法对象
                                                                        // 例如:targetClass = B  B impl A  =>  B.test()  此时,specificMethod = B.test() , method = A.test()
                                                                        // specificMethod != method,表示该方法是继承或者实现过来的,不是自身的方法
                                                                        if (specificMethod != method) {
                                                                            // 再通过method本身来找方法上的注解
                                                                            opDef = findCacheOperations(method);
                                                                            if (opDef != null) {
                                                                                return opDef;
                                                                            }
                                                                            // 最后在找method所属的类或者接口上的注解
                                                                            opDef = findCacheOperations(method.getDeclaringClass());
                                                                            if (opDef != null && ClassUtils.isUserLevelMethod(method)) {
                                                                                return opDef;
                                                                            }
                                                                        }
                                                                        // 都没找到,表示不需要代理
                                                                        return null;
                                                                    }
                                                                    if (cacheOps != null) {
                                                                        // 解析到了缓存的注解信息,缓存
                                                                        this.attributeCache.put(cacheKey, cacheOps);
                                                                    } else {
                                                                        // 没有解析到,标记该类没有解析到缓存注解
                                                                        this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE);
                                                                    }
                                                                    return cacheOps;
                                                                }
                                                            }));
                                                        }
                                                    }
                                                }
                                            }
                                        } else {
                                            // 没有切入点的切面,默认都可用
                                            return true;
                                        }
                                    }){
                                        // 保存可用的切面
                                        eligibleAdvisors.add(candidate);
                                    }
                                }
                            }
                            // 给子类实现,扩展可用的切面
                            extendAdvisors(eligibleAdvisors);
                            // 如果存在可用的切面,进行排序
                            if (!eligibleAdvisors.isEmpty()) {
                                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
                            }
                            // 返回可用的切面
                            return eligibleAdvisors;
                        }
                    }
                    // 如果specificInterceptors为空,没找到可用的切面
                    // 否则需要创建代理
                    if (specificInterceptors != DO_NOT_PROXY) {
                        Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                        return proxy;
                    }
                }
            }
        }
        return bean;
    }
}

// 目标方法执行拦截器
// 先看文Spring中JDK动态代理和CBLIB代理的拦截逻辑
// 因为创建的代理对象调用目标方法都会执行代理对象的拦截器逻辑
// 这个拦截逻辑就是获取符合条件的所有拦截的一个集合,然后一一执行
// 我们Asycn注解的话,只有一个拦截器,就是给定的CacheInterceptor
public class CacheInterceptor extends CacheAspectSupport implements SmartInitializingSingleton, MethodInterceptor {
    // 所有的bean都初始化完毕的回调
    public void afterSingletonsInstantiated() {
        // 如果不存在缓存解析器
        if (getCacheResolver() == null) {
            // 通过默认缓存管理器延迟初始化缓存解析器
            try {
                // 从Spring容器中获取CacheManager缓存管理器,并且到拦截器中
                setCacheManager(this.beanFactory.getBean(CacheManager.class)) {
                    // 实际上是设置缓存解析器,将缓存管理器封装到缓存解析器中,默认为SimpleCacheResolver
                    this.cacheResolver = SingletonSupplier.of(new SimpleCacheResolver(cacheManager));
                }
            }
            // 没有缓存管理器,则抛出异常
            catch (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.");
            }
        }
        // 标记当前类已经初始化完毕
        this.initialized = true;
    }

    // 拦截器的拦截方法
    public Object invoke(final MethodInvocation invocation) throws Throwable {
        // 获取方法对象
        Method method = invocation.getMethod();
        // 将拦截器链逻辑封装成一个函数,在下面execute进行回调
        CacheOperationInvoker aopAllianceInvoker = () -> {
            // 执行下一个拦截器
            return invocation.proceed();
        };
        // 执行目标方法
        return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments()) {
            // 是否初始化了,在afterSingletonsInstantiated方法中会初始化Cache解析器并且标识初始化成功
            if (this.initialized) {
                // 获取目标类
                Class<?> targetClass = getTargetClass(target);
                // 获取操作缓存注解的数据源对象
                CacheOperationSource cacheOperationSource = getCacheOperationSource();
                // 这个数据源肯定不为空,注册bean的时候注册了
                if (cacheOperationSource != null) {
                    // 从缓存数据源中根据方法和目标类获取解析好的注解信息
                    // 因为在这之前,在是否需要创建代理对象的时候,就解析了该这些缓存注解
                    // Object cacheKey = getCacheKey(method, targetClass);进行缓存的
                    Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass);
                    // 如果存在缓存注解
                    if (!CollectionUtils.isEmpty(operations)) {
                        // 真正执行,详见下面execute方法
                        return execute(invoker, method, new CacheOperationContexts(operations, method, args, target, targetClass){
                            this.contexts = new LinkedMultiValueMap<>(operations.size());
                            // 将所有的缓存操作,按照类型分类,存入contexts中
                            for (CacheOperation op : operations) {
                                this.contexts.add(op.getClass(), getOperationContext(op, method, args, target, targetClass){
                                    // 获取缓存的元数据
                                    CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass){
                                        // 元数据的缓存Key
                                        CacheOperationCacheKey cacheKey = new CacheOperationCacheKey(operation, method, targetClass);
                                        // 是否已经处理过
                                        CacheOperationMetadata metadata = this.metadataCache.get(cacheKey);
                                        // 没有处理过
                                        if (metadata == null) {
                                            // 获取Key的生成器
                                            KeyGenerator operationKeyGenerator;
                                            // 如果注解标记了生成器
                                            if (StringUtils.hasText(operation.getKeyGenerator())) {
                                                // 从spring中获取
                                                operationKeyGenerator = getBean(operation.getKeyGenerator(), KeyGenerator.class);
                                            }
                                            else {
                                                //
                                                operationKeyGenerator = getKeyGenerator(){
                                                    // 使用默认的SimpleKeyGenerator
                                                    // 	private SingletonSupplier<KeyGenerator> keyGenerator = SingletonSupplier.of(SimpleKeyGenerator::new);
                                                    return this.keyGenerator.obtain();
                                                }
                                            }
                                            // 获取缓存解析器
                                            CacheResolver operationCacheResolver;
                                            // 如果注解中中配置了指定的缓存解析器
                                            if (StringUtils.hasText(operation.getCacheResolver())) {
                                                // 从Spring中获取
                                                operationCacheResolver = getBean(operation.getCacheResolver(), CacheResolver.class);
                                            }
                                            // 如果没有注解设置缓存解析器,但是设置了缓存管理器
                                            else if (StringUtils.hasText(operation.getCacheManager())) {
                                                // 获取缓存管理器
                                                CacheManager cacheManager = getBean(operation.getCacheManager(), CacheManager.class);
                                                // 创建新的SimpleCacheResolver解析器
                                                operationCacheResolver = new SimpleCacheResolver(cacheManager);
                                            }
                                            // 如果注解都没配置
                                            else {
                                                // 获取当前类的缓存解析器
                                                // 也就是说有没有手动给当前CacheInterceptor类设置缓存管理器或者缓存解析器
                                                // 如果设置了就有,如果没有设置,就抛异常
                                                operationCacheResolver = getCacheResolver();
                                                Assert.state(operationCacheResolver != null, "No CacheResolver/CacheManager set");
                                            }
                                            // 封装成元数据对象
                                            metadata = new CacheOperationMetadata(operation, method, targetClass,operationKeyGenerator, operationCacheResolver);
                                            // 缓存起来
                                            this.metadataCache.put(cacheKey, metadata);
                                        }
                                        return metadata;
                                    }
                                    // 创建缓存操作的上下文
                                    return new CacheOperationContext(metadata, args, target){
                                        this.metadata = metadata;
                                        this.args = extractArgs(metadata.method, args);
                                        this.target = target;
                                        // 自动根据命名空间解析缓存
                                        this.caches = CacheAspectSupport.this.getCaches(this, metadata.cacheResolver){
                                            // 使用缓存解析器解析缓存
                                            Collection<? extends Cache> caches = cacheResolver.resolveCaches(context){
                                                // 获取缓存命名空间
                                                Collection<String> cacheNames = getCacheNames(context){
                                                    // 获取注解中的命名空间
                                                    return context.getOperation().getCacheNames();
                                                }
                                                // 根据名称获取的所有缓存
                                                Collection<Cache> result = new ArrayList<>(cacheNames.size());
                                                // 遍历所有的命名空间
                                                for (String cacheName : cacheNames) {
                                                    // 通过缓存管理器获取对应命名空间的缓存
                                                    // 这里根据不同的缓存管理器来操作,有不同的实现,我们只讲ConcurrentMapCacheManager
                                                    Cache cache = getCacheManager().getCache(cacheName){
                                                        // 缓map中获取之前加载过的缓存对象
                                                        Cache cache = this.cacheMap.get(name);
                                                        // 之前没有缓存过,并且是动态的(默认为true)
                                                        // 如果单独设置了cacheNames,dynamic会变为false
                                                        // public void setCacheNames(@Nullable Collection<String> cacheNames) {
                                                        //     if (cacheNames != null) {
                                                        //         for (String name : cacheNames) {
                                                        //             this.cacheMap.put(name, createConcurrentMapCache(name));
                                                        //         }
                                                        //         this.dynamic = false;
                                                        //     }
                                                        //     else {
                                                        //         this.dynamic = true;
                                                        //     }
                                                        // }
                                                        if (cache == null && this.dynamic) {
                                                            // 双重校验
                                                            synchronized (this.cacheMap) {
                                                                cache = this.cacheMap.get(name);
                                                                if (cache == null) {
                                                                    // 创建缓存
                                                                    cache = createConcurrentMapCache(name){
                                                                        SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
                                                                        // 创建缓存对象
                                                                        return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256),isAllowNullValues(), actualSerialization);
                                                                    }
                                                                    // 保存起来
                                                                    this.cacheMap.put(name, cache);
                                                                }
                                                            }
                                                        }
                                                        return cache;
                                                    }
                                                    if (cache == null) {
                                                        throw new IllegalArgumentException("Cannot find cache named '" +cacheName + "' for " + context.getOperation());
                                                    }
                                                    // 保存缓存
                                                    result.add(cache);
                                                }
                                                return result;
                                            }
                                            return caches;
                                        }
                                        this.cacheNames = createCacheNames(this.caches){
                                            Collection<String> names = new ArrayList<>();
                                            // 获取缓存的名称
                                            for (Cache cache : caches) {
                                                names.add(cache.getName());
                                            }
                                            return names;
                                        }
                                    }
                                });
                            }
                            // 获取方法中@Cacheable注解上是否标记了sync的值,如果没有,就是false
                            // 它标记了多个线程是否可以同时查询这个缓存,如果不同步,多个线程可能会出现多次放入缓存操作
                            this.sync = determineSyncFlag(method){
                                // 获取@Cacheable类型的缓存
                                List<CacheOperationContext> cacheOperationContexts = this.contexts.get(CacheableOperation.class);
                                // 如果没有就不需要管
                                if (cacheOperationContexts == null) {
                                    return false;
                                }
                                boolean syncEnabled = false;
                                // 遍历所有的@Cacheable方法
                                for (CacheOperationContext cacheOperationContext : cacheOperationContexts) {
                                    // 获取注解中的值
                                    if (((CacheableOperation) cacheOperationContext.getOperation()).isSync()) {
                                        // 如果为true,表示开启了同步
                                        syncEnabled = true;
                                        break;
                                    }
                                }
                                // 如果开启了同步,要校验
                                if (syncEnabled) {
                                    // 这个方法只能有Cacheable注解,不能有其他的缓存注解
                                    if (this.contexts.size() > 1) {
                                        throw new IllegalStateException("@Cacheable(sync=true) cannot be combined with other cache operations on '" + method + "'");
                                    }
                                    // 并且只能有一个Cacheable注解
                                    if (cacheOperationContexts.size() > 1) {
                                        throw new IllegalStateException("Only one @Cacheable(sync=true) entry is allowed on '" + method + "'");
                                    }
                                    //
                                    CacheOperationContext cacheOperationContext = cacheOperationContexts.iterator().next();
                                    CacheableOperation operation = (CacheableOperation) cacheOperationContext.getOperation();
                                    // 只能操作一个cacheNames命名空间中的缓存
                                    if (cacheOperationContext.getCaches().size() > 1) {
                                        throw new IllegalStateException("@Cacheable(sync=true) only allows a single cache on '" + operation + "'");
                                    }
                                    // 缓存开启同步的情况下,不能配置unless
                                    // unless和condition有点类似,它是表示当前unless标注的条件不满足的情况下,才会更新缓存,它可以引用最终的结果作为el表达式
                                    // 而condition决定是否需要执行该缓存,一个是开始决定,一个是结束决定
                                    if (StringUtils.hasText(operation.getUnless())) {
                                        throw new IllegalStateException("@Cacheable(sync=true) does not support unless attribute on '" + operation + "'");
                                    }
                                    return true;
                                }
                                return false;
                            }
                        });
                    }
                }
            }
            // 如果没有初始化,说明缓存管理器没有设置,无法处理缓存,直接执行invocation.proceed();方法
            return invoker.invoke();
        }
    }

    // 执行缓存操作
    private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
        // return execute(invoker, method, new CacheOperationContexts(operations, method, args, target, targetClass));
        // 获取方法中@Cacheable注解上是否标记了sync的值,如果没有,就是false
        // 它标记了多个线程是否可以同时查询这个缓存,多个线程可能会出现多次放入缓存操作
        if (contexts.isSynchronized()) {
            // 获取所有的@Cacheable的注解信息
            CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
            // 如果condition条件符合,下面有解析
            if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
                // 获取key,下面也有解析
                Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
                // 获取@Cacheable注解的命名空间的所有缓存
                Cache cache = context.getCaches().iterator().next();
                // 执行目标方法
                Object result = invokeOperation(invoker);
                // 将目标方法拆包,可能需要从Optional中提取出来,也可能不需要
                Callable<Object> valueLoader = () -> unwrapReturnValue(result);
                // 再包装成Optional对象
                return wrapCacheValue(method, cache.get(key, valueLoader));
            } else {
                // 直接执行目标方法
                return invokeOperation(invoker);
            }
        }


        // 第一步: 处理标了执行目标方法之前就要删除缓存的操作@CacheEvict
        // 执行删除缓存操作,处理@CacheEvict标注了目标方法执行之前beforeInvocation删除缓存的操作
        // 无论目标方法是否出现异常,缓存都删除成功
        processCacheEvicts(contexts.get(CacheEvictOperation.class), true, CacheOperationExpressionEvaluator.NO_RESULT) {
            // 遍历所有的CacheEvict注解信息
            for (CacheOperationContext context : contexts) {
                // 获取注解的元信息
                CacheEvictOperation operation = (CacheEvictOperation) context.metadata.operation;
                // 传递的参数为true:,判断如果注解标注了beforeInvocation=true(默认值为false)
                // true表示在方法执行之前删除缓存,否则在方法之后删除缓存
                // 再需要判断在注解中设置了condition是否符合条件,只有符合条件才会删除
                // @CacheEvict(value = "myCache", key = "#userId", condition = "#result != null")
                if (beforeInvocation == operation.isBeforeInvocation()
                        && isConditionPassing(context, result) {
                    // 是否被解析过表达式
                    if (this.conditionPassing == null) {
                        // 如果设置了条件
                        if (StringUtils.hasText(this.metadata.operation.getCondition())) {
                            // 创建一个计算上下文对象
                            EvaluationContext evaluationContext = createEvaluationContext(result) {
                                // 封装缓存相关的信息对象
                                CacheExpressionRootObject rootObject = new CacheExpressionRootObject(caches, method, args, target, targetClass);
                                // 创建缓存计算上下文
                                CacheEvaluationContext evaluationContext = new CacheEvaluationContext(rootObject, targetMethod, args, getParameterNameDiscoverer());
                                // 传递的result为NO_RESULT
                                if (result == RESULT_UNAVAILABLE) {
                                    evaluationContext.addUnavailableVariable(RESULT_VARIABLE);
                                }
                                // 如何有结果,就会将返回结果保存到计算上下文中
                                else if (result != NO_RESULT) {
                                    evaluationContext.setVariable(RESULT_VARIABLE, result);
                                }
                                // 如果为NO_RESULT,表示为初始化,给计算上下文中设置对应的Bean解析器,用于解析条件中可能存在的beanName
                                if (beanFactory != null) {
                                    evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
                                }
                                return evaluationContext;
                            }
                            // 使用计算器计算条件是否符合
                            // 内部使用new SpelExpressionParser()解析spel表达式,然后在进行判断
                            this.conditionPassing = evaluator.condition(this.metadata.operation.getCondition(),this.metadata.methodKey, evaluationContext);
                        } else {
                            // 如果没有设定condition条件,就不需要校验
                            this.conditionPassing = true;
                        }
                    }
                    // 返回是否符合条件
                    return this.conditionPassing;
                })
                {
                    // 删除缓存
                    performCacheEvict(context, operation, result){
                        // 获取缓存Key
                        Object key = null;
                        // 遍历所有的缓存
                        for (Cache cache : context.getCaches()) {
                            // 注解是否配置了allEntries属性,默认为false
                            // 如果为true,表示清空缓存
                            if (operation.isCacheWide()) {
                                // 清空缓存
                                doClear(cache, operation.isBeforeInvocation()){
                                    try {
                                        // 是否立即清理,isBeforeInvocation传递的为true
                                        if (immediate) {
                                            // 删除缓存,执行缓存的失效逻辑,这个是不同的实现
                                            // 现在我们讲基于内存的ConcurrentMapCache实现
                                            cache.invalidate(){
                                                // 	private final ConcurrentMap<Object, Object> store;
                                                boolean notEmpty = !this.store.isEmpty();
                                                this.store.clear();
                                                return notEmpty;
                                            }
                                        }
                                        else {
                                            cache.clear();{
                                                this.store.clear();
                                            }
                                        }
                                    }
                                    catch (RuntimeException ex) {
                                        // 如果清理缓存发生异常,使用异常处理器处理
                                        getErrorHandler().handleCacheClearError(ex, cache);
                                    }
                                }
                            }
                            else {
                                // 如果没有设置allEntries属性,表示只删除当前key
                                if (key == null) {
                                    // 生成一个key
                                    key = generateKey(context, result){
                                        return context.generateKey(result){
                                            // 如果注解设置了key
                                            if (StringUtils.hasText(this.metadata.operation.getKey())) {
                                                // 内部使用new SpelExpressionParser()解析spel表达式,获取到真实的key
                                                EvaluationContext evaluationContext = createEvaluationContext(result);
                                                return evaluator.key(this.metadata.operation.getKey(), this.metadata.methodKey, evaluationContext);
                                            }
                                            // 如果没有设置key,使用给定的key生成器生成key
                                            // keyGenerator:Spring存在使用Spring配置的keyGenerator,如果不存在使用默认的SimpleKeyGenerator
                                            return this.metadata.keyGenerator.generate(this.target, this.metadata.method, this.args);
                                        }
                                    }
                                }
                                doEvict(cache, key, operation.isBeforeInvocation()){
                                    try {
                                        // 是否立即清理
                                        // 现在我们讲基于内存的ConcurrentMapCache实现
                                        if (immediate) {
                                            cache.evictIfPresent(key){
                                                return (this.store.remove(key) != null);
                                            }
                                        }
                                        else {
                                            cache.evict(key){
                                                this.store.remove(key);
                                            }
                                        }
                                    }
                                    catch (RuntimeException ex) {
                                        // 如果清理缓存发生异常,使用异常处理器处理
                                        getErrorHandler().handleCacheEvictError(ex, cache, key);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // 第二步,检查@Cacheable注解,查询缓存是否命中
        // 检查当前方法是否有@Cacheable匹配条件的缓存项
        Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class)){
            // 默认的结果值
            Object result = CacheOperationExpressionEvaluator.NO_RESULT;
            // 遍历所有的Cacheable类型注解信息
            for (CacheOperationContext context : contexts) {
                // 判断注解的condition是否符合条件,上面有详细解释
                if (isConditionPassing(context, result)) {
                    // 生成key,上面有详细解释
                    Object key = generateKey(context, result);
                    // 查找缓存值
                    Cache.ValueWrapper cached = findInCaches(context, key){
                        // 找到当前注解标注的命名空间中的所有缓存
                        for (Cache cache : context.getCaches()) {
                            // 获取缓存值
                            Cache.ValueWrapper wrapper = doGet(cache, key){
                                return cache.get(key);
                            }
                            if (wrapper != null) {
                                return wrapper;
                            }
                        }
                        return null;
                    }
                    // 找到了对应的缓存
                    if (cached != null) {
                        return cached;
                    }
                }
            }
            return null;
        }

        // 如果没有命中缓存,表示缓存是新增的,新建一个put操作
        // 如果没有找到缓存项,保存需要缓存的key的请求
        List<CachePutRequest> cachePutRequests = new LinkedList<>();
        // 如果没有找到缓存项,缓存命中
        if (cacheHit == null) {
            // 没有缓存命中,表示该方法需要被缓存,添加一个添加缓存的请求,后面统一添加
            collectPutRequests(contexts.get(CacheableOperation.class),CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests){
                // 遍历所有的@Cacheable注解信息
                for (CacheOperationContext context : contexts) {
                    // condition条件通过
                    if (isConditionPassing(context, result)) {
                        // 生成Key
                        Object key = generateKey(context, result);
                        // 保存一个增加缓存的请求对象
                        putRequests.add(new CachePutRequest(context, key));
                    }
                }
            }
        }

        Object cacheValue;
        Object returnValue;

        // 如果找到了缓存信息,表示缓存命中
        if (cacheHit != null
                // 判断是否存在有要保存的缓存
                && !hasCachePut(contexts){
                    // 获取CachePut注解信息
                    Collection<CacheOperationContext> cachePutContexts = contexts.get(CachePutOperation.class);
                    // 需要排除的缓存
                    Collection<CacheOperationContext> excluded = new ArrayList<>();
                    // 遍历所有的CachePut注解信息
                    for (CacheOperationContext context : cachePutContexts) {
                        // 如果不匹配condition
                        if (!context.isConditionPassing(CacheOperationExpressionEvaluator.RESULT_UNAVAILABLE)) {
                            // 当前注解信息排除
                            excluded.add(context);
                        }
                    }
                    // 检查是否所有的CachePut注解都被排除了
                    return (cachePutContexts.size() != excluded.size());
                })
        {
            // 如果没有put请求,则只使用缓存命中操作,因为可能这个方法同时存在缓存新增和缓存修改注解
            // 直接获取缓存的值
            cacheValue = cacheHit.get();
            // 包装缓存值
            returnValue = wrapCacheValue(method, cacheValue){
                // 统一将值封装为Optional对象
                if (method.getReturnType() == Optional.class && (cacheValue == null || cacheValue.getClass() != Optional.class)) {
                    return Optional.ofNullable(cacheValue);
                }
                return cacheValue;
            }
        } else {
            // 如果没有找到缓存,表示缓存没有命中
            returnValue = invokeOperation(invoker){
                // 执行目标方法
                return invoker.invoke();
            }
            // 将值进行拆包,就是将Optional中的值拆出来
            cacheValue = unwrapReturnValue(returnValue){
                return ObjectUtils.unwrapOptional(returnValue);
            }
        }

        // 第三步: 处理所有的put操作,并缓存起来
        // 继续收集所有添加的缓存,上面有这个代码解释
        collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);

        // 遍历所有的put添加缓存请求
        // 处理任何收集到的新增请求,无论是来自@CachePut还是@Cacheable miss
        for (CachePutRequest cachePutRequest : cachePutRequests) {
            // 执行请求
            cachePutRequest.apply(cacheValue){
                // 判断是否可以put
                if (this.context.canPutToCache(result){
                    // 解析注解中的unless条件
                    String unless = "";
                    // 根据不同类型,解析不同注解中的unless值
                    if (this.metadata.operation instanceof CacheableOperation) {
                        unless = ((CacheableOperation) this.metadata.operation).getUnless();
                    }
                    else if (this.metadata.operation instanceof CachePutOperation) {
                        unless = ((CachePutOperation) this.metadata.operation).getUnless();
                    }
                    // 解析unless的el表达式
                    if (StringUtils.hasText(unless)) {
                        EvaluationContext evaluationContext = createEvaluationContext(value);
                        // 解析unless条件,前面加一个"!",表示值与unless的值对立才添加缓存
                        return !evaluator.unless(unless, this.metadata.methodKey, evaluationContext);
                    }
                    // 没有unless条件
                    return true;
                })
                {
                    // 遍历所有的缓存
                    for (Cache cache : this.context.getCaches()) {
                        // 将当前key和结果保存到缓存中
                        doPut(cache, this.key, result){
                            cache.put(key, result);{
                                // 调用的是ConcurrentMapCache的实现
                                this.store.put(key, toStoreValue(value));
                            }
                        }
                    }
                }
            }
        }

        // 第四步: 和第一步一样,执行删除的时机一个再执行目标方法删除,一个在执行目标方法之后执行
        // 执行删除缓存操作,处理@CacheEvict的默认情况,上面有完全一样的代码解释
        // 上面执行的是在目标方法之前删除,现在是目标方法之后删除,执行时机不一样,其他的完全一样
        processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);
        // 返回目标方法执行的结果
        return returnValue;
    }

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值