zoukankan      html  css  js  c++  java
  • 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);
      }
      
    2. 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
    如理解有误,请指正

  • 相关阅读:
    面象对象设计原则之七:合成复用原则(Composition/Aggregate Reuse Principle, CARP)
    GRASP软件设计的模式和原则
    UniDAC 安装教程
    Delphi 实现检测线程类TThread是否结束
    DELPHI线程例子-FC
    Delphi Stringlist Delimiter如何区分TAB和空格
    DBGrid1
    UTF-8 delphi 函数
    未测试 Delphi读写UTF-8、Unicode格式文本文件
    mysql + unidac 使用事务例子
  • 原文地址:https://www.cnblogs.com/tanoak/p/10545246.html
Copyright © 2011-2022 走看看