这上一篇文章中我们熟悉了SpringBoot Cache的基本使用,接下来我们看下它的执行流程
-
CacheAutoConfiguration 自动装配类
根据图中标注,看到它引用了CachingConfigurationSelector这个类
静态内部类,实现了 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; } }复制代码
-
SimpleCacheConfiguration 配置类
创建ConcurrentMapCacheManager对象 ,给容器注册了CacheManage=>ConcurrentMapCacheManager
@Beanpublic ConcurrentMapCacheManager cacheManager() { ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); List
cacheNames = this.cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { cacheManager.setCacheNames(cacheNames); } return this.customizerInvoker.customize(cacheManager);}复制代码 -
ConcurrentMapCacheManager 类 [图片上传失败...(image-2a6db9-1530901912375)]
找到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); }复制代码
这个注解相当于把 @CachePut、 @CacheEvict、@Cacheable这三个注解组合在一起,增加了灵活性,使用与之前类似,就不展开了复制代码