SpringBoot Cache 深入

这上一篇文章中我们熟悉了SpringBoot Cache的基本使用,接下来我们看下它的执行流程

  1. CacheAutoConfiguration 自动装配类

    根据图中标注,看到它引用了CachingConfigurationSelector这个类

a2.png
 静态内部类,实现了 selectImports()这个方法 ,这个方法用于添加配置类

 通过debugger观察 imports[]数组,在控制台中看到 SimpleCacheConfiguration类的配置生效
     static class CacheConfigurationImportSelector implements ImportSelector {

     @Override
     public String[] selectImports(AnnotationMetadata importingClassMetadata) {
         CacheType[] types = CacheType.values();
         String[] imports = new String[types.length];
         for (int i = 0; i < types.length; i++) {
             imports[i] = CacheConfigurations.getConfigurationClass(types[i]);
         }
         return imports;
     }

 }
  1. SimpleCacheConfiguration 配置类

    创建ConcurrentMapCacheManager对象 ,给容器注册了CacheManage=>ConcurrentMapCacheManager

    @Bean
    public ConcurrentMapCacheManager cacheManager() {
     ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
     List<String> cacheNames = this.cacheProperties.getCacheNames();
     if (!cacheNames.isEmpty()) {
         cacheManager.setCacheNames(cacheNames);
     }
     return this.customizerInvoker.customize(cacheManager);
    }
    
  1. ConcurrentMapCacheManager 类
    [图片上传失败...(image-2a6db9-1530901912375)]
b2.png

找到getCache()这个方法,根据方法名就可以知道这是获取缓存的方法

    @Override
    @Nullable
    public Cache getCache(String name) {
        Cache cache = this.cacheMap.get(name);
        if (cache == null && this.dynamic) {//判断是否为null
            synchronized (this.cacheMap) {//加锁
                cache = this.cacheMap.get(name);
                if (cache == null) {
                    cache = createConcurrentMapCache(name);//保存至createConcurrentMapCache
                    this.cacheMap.put(name, cache);
                }
            }
        }
        return cache;
    }

createConcurrentMapCache方法

protected Cache createConcurrentMapCache(String name) {
        SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
        return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256),
                isAllowNullValues(), actualSerialization);

    }

回到ConcurrentHashMap类,找到lookup()这个方法 ,这个缓存Key是怎么得到的呢,对这个方法打断点,看它的调用栈

@Override
    @Nullable
    protected Object lookup(Object key) {
        return this.store.get(key);
    }

e2.png

进入generatorKey()这个方法


c3.png

找到这个接口,是不是有了熟悉的感觉,这就是自定义主键生成策略需要实现的接口


d2.png

致此,整合流程也就走完了,这里增加一点内容关于@Caching
这个注解相当于把 @CachePut、 @CacheEvict、@Cacheable这三个注解组合在一起,增加了灵活性,使用与之前类似,就不展开了
f2.png

如理解有误,请指正

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,981评论 19 139
  • JSR107 Java Caching定义了5个核心接口,分别是CachingProvider, CacheMan...
    匆匆岁月阅读 1,477评论 0 1
  • 本文转自被遗忘的博客 Spring Cache 缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下...
    quiterr阅读 1,103评论 0 8
  • 今天读完了第四章和第五章。早上读到手不释卷,打心想眼儿里有点喜欢这个作者,可以看得出他的知识关联整合的能力超强。这...
    刘小麦同学阅读 412评论 0 0
  • 估计很多朋友看到这个题目,第一反应会不会看错了!其实没有看错,这个故事是我们大人要讲给孩子听的故事!当我看到幼儿园...
    Cinko阅读 8,958评论 0 17