SpringBoot缓存工作原理学习笔记

缓存工作原理

自动配置类:CacheAutoConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
		HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class })
public class CacheAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	//缓存管理器的自定义器
	public CacheManagerCustomizers cacheManagerCustomizers(ObjectProvider<CacheManagerCustomizer<?>> customizers) {
		return new CacheManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
	}

	@Bean
	public CacheManagerValidator cacheAutoConfigurationValidator(CacheProperties cacheProperties,
			ObjectProvider<CacheManager> cacheManager) {
		return new CacheManagerValidator(cacheProperties, cacheManager);
	}

	@ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
	@ConditionalOnBean(AbstractEntityManagerFactoryBean.class)
	static class CacheManagerEntityManagerFactoryDependsOnPostProcessor
			extends EntityManagerFactoryDependsOnPostProcessor {

		CacheManagerEntityManagerFactoryDependsOnPostProcessor() {
			super("cacheManager");
		}
	}

	/**
	 * Bean used to validate that a CacheManager exists and provide a more meaningful
	 * exception.
	 */
	static class CacheManagerValidator implements InitializingBean {

		private final CacheProperties cacheProperties;

		private final ObjectProvider<CacheManager> cacheManager;

		CacheManagerValidator(CacheProperties cacheProperties, ObjectProvider<CacheManager> cacheManager) {
			this.cacheProperties = cacheProperties;
			this.cacheManager = cacheManager;
		}

		@Override
		public void afterPropertiesSet() {
			Assert.notNull(this.cacheManager.getIfAvailable(),
					() -> "No cache manager could be auto-configured, check your configuration (caching type is '"
							+ this.cacheProperties.getType() + "')");
		}
	}

	/**
	 * {@link ImportSelector} to add {@link CacheType} configuration classes.
	 */
	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

@Configuration(proxyBeanMethods = false)
//如果容器中有cache组件
@ConditionalOnBean(Cache.class)
//如果容器中没有CacheManager组件
@ConditionalOnMissingBean(CacheManager.class)
//满足这个条件
@Conditional(CacheCondition.class)
class GenericCacheConfiguration {

	@Bean
	SimpleCacheManager cacheManager(CacheManagerCustomizers customizers, Collection<Cache> caches) {
		SimpleCacheManager cacheManager = new SimpleCacheManager();
		cacheManager.setCaches(caches);
		return customizers.customize(cacheManager);
	}
}

在这里插入图片描述
在这里插入图片描述

SimpleCacheConfiguration

	源码:
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingBean(CacheManager.class)
	@Conditional(CacheCondition.class)
	class SimpleCacheConfiguration {
	
		@Bean
		//给容器中注册了一个缓存管理器CacheManager:ConcurrentMapCacheManager
		//可以获取和创建ConcurrentMapCache类型的缓存组件,作用:将数据保存在ConcurrentMap中
		ConcurrentMapCacheManager cacheManager(CacheProperties cacheProperties,
				CacheManagerCustomizers cacheManagerCustomizers) {
			ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
			List<String> cacheNames = cacheProperties.getCacheNames();
			if (!cacheNames.isEmpty()) {
				cacheManager.setCacheNames(cacheNames);
			}
			return cacheManagerCustomizers.customize(cacheManager);
		}
	}

ConcurrentMapCacheManager

		源码:
		public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderAware {
			
			private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>(16);

			@Override
			@Nullable
			public Cache getCache(String name) {
				//根据名字获取组件
				Cache cache = this.cacheMap.get(name);
				if (cache == null && this.dynamic) {
					synchronized (this.cacheMap) {
						cache = this.cacheMap.get(name);
						if (cache == null) {
							//创建缓存对象
							cache = createConcurrentMapCache(name);
							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);
		
			}
		}

CacheManager

			源码:
			public interface CacheManager {
				//根据名字得到缓存组件
				@Nullable
				Cache getCache(String name);
			}

ConcurrentMapCache

			源码:
			public class ConcurrentMapCache extends AbstractValueAdaptingCache {
			
				protected ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store,
							boolean allowNullValues, @Nullable SerializationDelegate serialization) {
					super(allowNullValues);
					Assert.notNull(name, "Name must not be null");
					Assert.notNull(store, "Store must not be null");
					this.name = name;
					this.store = store;
					this.serialization = serialization;
				}
				//查询缓存的数据lookup
				@Override
				@Nullable
				protected Object lookup(Object key) {
					return this.store.get(key);
				}
				//保存数据
				@Override
				public void put(Object key, @Nullable Object value) {
					this.store.put(key, toStoreValue(value));
				}
			store
				源码:	
				private final ConcurrentMap<Object, Object> store;

			}

运行流程

核心:
	1.使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件
	2.key使用keyGenerayor生成的,默认是SimpleKeyGenerator 

@Cacheable
1.方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取
(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建,放到cacheMap里
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.去Cache中查找缓存的内容,使用一个key,默认就是方法的参数
在这里插入图片描述
key是按照某种策略生成,默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator 生成key
在这里插入图片描述

public abstract class CacheAspectSupport extends AbstractCacheInvoker implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {

	@Nullable
	private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
		Object result = CacheOperationExpressionEvaluator.NO_RESULT;
		for (CacheOperationContext context : contexts) {
			if (isConditionPassing(context, result)) {
				//生成key
				Object key = generateKey(context, result);
				Cache.ValueWrapper cached = findInCaches(context, key);
				if (cached != null) {
					return cached;
				}
				else {
					if (logger.isTraceEnabled()) {
						logger.trace("No cache entry for key '" + key + "' in cache(s) " + context.getCacheNames());
					}
				}
			}
		}
		return null;
	}
	//生成key
	private Object generateKey(CacheOperationContext context, @Nullable Object result) {
		//调用上下文,生成key
		Object key = context.generateKey(result);
		if (key == null) {
			throw new IllegalArgumentException("Null key returned for cache operation (maybe you are " +
					"using named params on classes without debug info?) " + context.metadata.operation);
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Computed cache key '" + key + "' for operation " + context.metadata.operation);
		}
		return key;
	}
	//调用上下文,生成key
	@Nullable
	protected Object generateKey(@Nullable Object result) {
		if (StringUtils.hasText(this.metadata.operation.getKey())) {
			EvaluationContext evaluationContext = createEvaluationContext(result);
			return evaluator.key(this.metadata.operation.getKey(), this.metadata.methodKey, evaluationContext);
		}
		//
		return this.metadata.keyGenerator.generate(this.target, this.metadata.method, this.args);
	}
keyGenerator
	源码:	
	private final KeyGenerator keyGenerator;
}

在这里插入图片描述

KeyGenerator

		源码:
		@FunctionalInterface
		public interface KeyGenerator {
		
			Object generate(Object target, Method method, Object... params);		
		}

SimpleKeyGenerator

			实现:KeyGenerator 
			public class SimpleKeyGenerator implements KeyGenerator {
			}

3.没有查到缓存就调用目标方法
在这里插入图片描述
4.将目标方法返回的结果,放进缓存中
在这里插入图片描述
@Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存
如果没有就运行方法并将结果放入缓存,以后在来调用就可以直接使用缓存中的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
SimpleKeyGenerator 生成key的默认策略
如果没有参数,key=new SimpleKey();
如果有一个参数,key=参数的值
如果有多个参数,key=new SimpleKey(params);
在这里插入图片描述
generateKey

	源码:
	public class SimpleKeyGenerator implements KeyGenerator {
	
		@Override
		public Object generate(Object target, Method method, Object... params) {
			return generateKey(params);
		}
		
		/**
		 * Generate a key based on the specified parameters.
		 */
		public static Object generateKey(Object... params) {
			//如果没有参数
			if (params.length == 0) {
				return SimpleKey.EMPTY;
			}
			//如果有一个参数就把这个参数返回
			if (params.length == 1) {
				Object param = params[0];
				if (param != null && !param.getClass().isArray()) {
					return param;
				}
			}
			return new SimpleKey(params);
		}	
	}

EMPTY

	源码:
	@SuppressWarnings("serial")
	public class SimpleKey implements Serializable {
		public static final SimpleKey EMPTY = new SimpleKey();
	}

之前已经运行过一次,这里有数据,直接从缓存拿数据
在这里插入图片描述
数据不为空
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值