Spring Cache基础组件 CacheAnnotationParser

相关阅读

简介

定义解析已知的缓存注解类型策的略接口;
AnnotationCacheOperationSource委托它们实现解析Spring的缓存注解:@Cacheable/@CachePut/@CacheEvict/@Caching

核心代码

/**
 * 判断targetClass是否需要本parser解析缓存动作
 */
default boolean isCandidateClass(Class<?> targetClass) {
    return true;
}

/**
 * 解析指定类上的缓存注解
 */
@Nullable
Collection<CacheOperation> parseCacheAnnotations(Class<?> type);

/**
 * 解析指定方法上的缓存注解
 */
@Nullable
Collection<CacheOperation> parseCacheAnnotations(Method method);

实现子类

public interface CacheAnnotationParser
    public class SpringCacheAnnotationParser implements CacheAnnotationParser, Serializable

SpringCacheAnnotationParser

简介

解析SpringCache的注解的策略实现;

核心代码

// 默认拥有SpringCache的注解:@Cacheable/@CachePut/@CacheEvict/@Caching
private static final Set<Class<? extends Annotation>> CACHE_OPERATION_ANNOTATIONS = new LinkedHashSet<>(8);
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);
}

/**
 * 判断targetClass是否需要本parser解析缓存动作
 */
public boolean isCandidateClass(Class<?> targetClass) {
    // targetClass的类/方法/属性上是否有SpringCache的任意一个注解
    return AnnotationUtils.isCandidateClass(targetClass, CACHE_OPERATION_ANNOTATIONS);
}

/**
 * 解析指定类上的缓存注解
 */
@Nullable
public Collection<CacheOperation> parseCacheAnnotations(Class<?> type) {
    // 获取类上的全局Cache配置,即@CacheConfig注解
    DefaultCacheConfig defaultConfig = new DefaultCacheConfig(type);
    return parseCacheAnnotations(defaultConfig, type);
}

/**
 * 解析指定方法上的缓存注解
 */
@Nullable
public Collection<CacheOperation> parseCacheAnnotations(Method method) {
    // 获取类上的全局Cache配置,即@CacheConfig注解
    DefaultCacheConfig defaultConfig = new DefaultCacheConfig(method.getDeclaringClass());
    return parseCacheAnnotations(defaultConfig, method);
}

/**
 * 解析缓存注解
 */
@Nullable
private Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig, AnnotatedElement ae) {
    // 全面搜索整个类层次结构(包括超类和实现的接口)拥有的注解信息
    Collection<CacheOperation> ops = parseCacheAnnotations(cachingConfig, ae, false);
    if (ops != null && ops.size() > 1) {
        // 搜索直接声明的注解以及任何@Inherited超类拥有的注解信息
        // More than one operation found -> local declarations override interface-declared ones...
        Collection<CacheOperation> localOps = parseCacheAnnotations(cachingConfig, ae, true);
        if (localOps != null) {
            // 直接声明的注解信息优先于类层次结构声明的注解信息
            return localOps;
        }
    }
    return ops;
}

/**
 * 解析缓存注解
 */
@Nullable
private Collection<CacheOperation> parseCacheAnnotations(
    DefaultCacheConfig cachingConfig, AnnotatedElement ae, boolean localOnly) {
    // 搜索SpringCache注解信息
    Collection<? extends Annotation> anns = (localOnly ?
        AnnotatedElementUtils.getAllMergedAnnotations(ae, CACHE_OPERATION_ANNOTATIONS) :
        AnnotatedElementUtils.findAllMergedAnnotations(ae, CACHE_OPERATION_ANNOTATIONS));
    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)));
    // 解析@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;
}

/**
 * 解析@Cacheable注解
 */
private CacheableOperation parseCacheableAnnotation(
    AnnotatedElement ae, DefaultCacheConfig defaultConfig, Cacheable cacheable) {
    CacheableOperation.Builder builder = new CacheableOperation.Builder();

    // 根据@Cacheable的属性设置CacheableOperation.Builder
    builder.setName(ae.toString());
    builder.setCacheNames(cacheable.cacheNames());
    builder.setCondition(cacheable.condition());
    builder.setUnless(cacheable.unless());
    builder.setKey(cacheable.key());
    builder.setKeyGenerator(cacheable.keyGenerator());
    builder.setCacheManager(cacheable.cacheManager());
    builder.setCacheResolver(cacheable.cacheResolver());
    builder.setSync(cacheable.sync());

    // 结合类的全局Cache配置得到最终CacheableOperation.Builder
    defaultConfig.applyDefault(builder);
    // 根据CacheableOperation.Builder生成CacheOperation
    CacheableOperation op = builder.build();
    // 校验CacheOperation
    validateCacheOperation(ae, op);

    return op;
}

/**
 * 解析@Cacheable注解
 */
private CacheEvictOperation parseEvictAnnotation(
    AnnotatedElement ae, DefaultCacheConfig defaultConfig, CacheEvict cacheEvict) {
    CacheEvictOperation.Builder builder = new CacheEvictOperation.Builder();

    // 根据@CacheEvict的属性设置CacheEvictOperation.Builder
    builder.setName(ae.toString());
    builder.setCacheNames(cacheEvict.cacheNames());
    builder.setCondition(cacheEvict.condition());
    builder.setKey(cacheEvict.key());
    builder.setKeyGenerator(cacheEvict.keyGenerator());
    builder.setCacheManager(cacheEvict.cacheManager());
    builder.setCacheResolver(cacheEvict.cacheResolver());
    builder.setCacheWide(cacheEvict.allEntries());
    builder.setBeforeInvocation(cacheEvict.beforeInvocation());

    // 结合类的全局Cache配置得到最终CacheEvictOperation.Builder
    defaultConfig.applyDefault(builder);
    // 根据CacheEvictOperation.Builder生成CacheOperation
    CacheEvictOperation op = builder.build();
    // 校验CacheOperation
    validateCacheOperation(ae, op);

    return op;
}

/**
 * 解析@Cacheable注解
 */
private CacheOperation parsePutAnnotation(
    AnnotatedElement ae, DefaultCacheConfig defaultConfig, CachePut cachePut) {
    CachePutOperation.Builder builder = new CachePutOperation.Builder();

    // 根据@CachePut的属性设置CachePutOperation.Builder
    builder.setName(ae.toString());
    builder.setCacheNames(cachePut.cacheNames());
    builder.setCondition(cachePut.condition());
    builder.setUnless(cachePut.unless());
    builder.setKey(cachePut.key());
    builder.setKeyGenerator(cachePut.keyGenerator());
    builder.setCacheManager(cachePut.cacheManager());
    builder.setCacheResolver(cachePut.cacheResolver());

    // 结合类的全局Cache配置得到最终CachePutOperation.Builder
    defaultConfig.applyDefault(builder);
    // 根据CachePutOperation.Builder生成CacheOperation
    CachePutOperation op = builder.build();
    // 校验CacheOperation
    validateCacheOperation(ae, op);

    return op;
}

/**
 * 解析@Cacheable注解
 * @Caching就是@Cacheable/@CacheEvict/@CachePut的集合
 */
private void parseCachingAnnotation(
    AnnotatedElement ae, DefaultCacheConfig defaultConfig, Caching caching, Collection<CacheOperation> ops) {
    // 解析包含的@Cacheable
    Cacheable[] cacheables = caching.cacheable();
    for (Cacheable cacheable : cacheables) {
        ops.add(parseCacheableAnnotation(ae, defaultConfig, cacheable));
    }

    // 解析包含的@CacheEvict
    CacheEvict[] cacheEvicts = caching.evict();
    for (CacheEvict cacheEvict : cacheEvicts) {
        ops.add(parseEvictAnnotation(ae, defaultConfig, cacheEvict));
    }

    // 解析包含的@CachePut
    CachePut[] cachePuts = caching.put();
    for (CachePut cachePut : cachePuts) {
        ops.add(parsePutAnnotation(ae, defaultConfig, cachePut));
    }
}

/**
 * 校验CacheOperation
 */
private void validateCacheOperation(AnnotatedElement ae, CacheOperation operation) {
    // key和keyGenerator二者存其一
    if (StringUtils.hasText(operation.getKey()) && StringUtils.hasText(operation.getKeyGenerator())) {
        throw new IllegalStateException("Invalid cache annotation configuration on '" +
                ae.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " +
                "These attributes are mutually exclusive: either set the SpEL expression used to" +
                "compute the key at runtime or set the name of the KeyGenerator bean to use.");
    }
    // cacheManager和cacheResolver二者存其一
    if (StringUtils.hasText(operation.getCacheManager()) && StringUtils.hasText(operation.getCacheResolver())) {
        throw new IllegalStateException("Invalid cache annotation configuration on '" +
                ae.toString() + "'. Both 'cacheManager' and 'cacheResolver' attributes have been set. " +
                "These attributes are mutually exclusive: the cache manager is used to configure a" +
                "default cache resolver if none is set. If a cache resolver is set, the cache manager" +
                "won't be used.");
    }
}

/**
 * 静态内部类,定义CacheOperation的默认缓存配置
 * 配置来源于类上的@CacheConfig注解
 */
private static class DefaultCacheConfig {
    // 目标类
    private final Class<?> target;
    // 缓存标识符
    private String[] cacheNames;
    // KEY生成器
    private String keyGenerator;
    // 缓存管理器
    private String cacheManager;
    // 缓存解析器
    private String cacheResolver;
    // 初始化标识
    private boolean initialized = false;


    /**
     * 根据builder生成cache operation配置
     */
    public void applyDefault(CacheOperation.Builder builder) {
        // 还未解析过target类的@CacheConfig(全局Cache配置),需要先获取类的全局Cache配置
        if (!this.initialized) {
            // 获取类上的@CacheConfig注解
            CacheConfig annotation = AnnotatedElementUtils.findMergedAnnotation(this.target, CacheConfig.class);
            if (annotation != null) {
                // 不存在,则使用@CacheConfig的配置作为默认配置,方法(或者属性)若有Cache配置则使用方法或者属性上的配置
                this.cacheNames = annotation.cacheNames();
                this.keyGenerator = annotation.keyGenerator();
                this.cacheManager = annotation.cacheManager();
                this.cacheResolver = annotation.cacheResolver();
            }
            // target类已经解析过全局Cache配置,无需再次解析
            this.initialized = true;
        }

        // 如果方法未配置缓存标识符,则使用类上的配置
        if (builder.getCacheNames().isEmpty() && this.cacheNames != null) {
            builder.setCacheNames(this.cacheNames);
        }
        // 如果方法未配置KEY/KEY生成器,则使用类上的配置
        if (!StringUtils.hasText(builder.getKey()) && !StringUtils.hasText(builder.getKeyGenerator()) &&
                StringUtils.hasText(this.keyGenerator)) {
            builder.setKeyGenerator(this.keyGenerator);
        }

        // 如果方法配置了缓存管理器或者缓存解析器,则无需类上的配置
        if (StringUtils.hasText(builder.getCacheManager()) || StringUtils.hasText(builder.getCacheResolver())) {
            // One of these is set so we should not inherit anything
        }
        // 使用类上的缓存解析器
        else if (StringUtils.hasText(this.cacheResolver)) {
            builder.setCacheResolver(this.cacheResolver);
        }
        // 使用类上的缓存管理器
        else if (StringUtils.hasText(this.cacheManager)) {
            builder.setCacheManager(this.cacheManager);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值