IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringCache基础组件 CacheAnnotationParser -> 正文阅读

[Java知识库]SpringCache基础组件 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);
        }
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:07:59  更:2021-11-28 11:09:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:31:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码