1.spring cache代理类简介
结构
2.spring cache代理类源码解读
2.1.缓存切面(PointCut)
作用
根据缓存注解生成一个切面,如果条件匹配会进行拦截;
抽象类CacheOperationSourcePointcut
abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
//**使用CacheOperationSourceClassFilter类过滤器
protected CacheOperationSourcePointcut() {
setClassFilter(new CacheOperationSourceClassFilter());
}
//**是否匹配
public boolean matches(Method method, Class<?> targetClass) {
//**获取缓存操作源
CacheOperationSource cas = getCacheOperationSource();
//**如果缓存操作源不为空 && 缓存操作源能获取到目标方法上的缓存操作,则需拦截目标方法
return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)));
}
//**获取缓存操作源
protected abstract CacheOperationSource getCacheOperationSource();
//**缓存操作类过滤器
private class CacheOperationSourceClassFilter implements ClassFilter {
//**是否匹配
public boolean matches(Class<?> clazz) {
//**如果目标类是CacheManager的子类,则返回false
if (CacheManager.class.isAssignableFrom(clazz)) {
return false;
}
//**获取缓存操作源
CacheOperationSource cas = getCacheOperationSource();
//**如果缓存操作源不为空 && 缓存操作源能处理目标类,则返回true
return (cas == null || cas.isCandidateClass(clazz));
}
}
}
缓存切面BeanFactoryCacheOperationSourceAdvisor.pointcut
在BeanFactoryCacheOperationSourceAdvisor中有一个匿名实现;
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
//**在ProxyCachingConfiguration创建BeanFactoryCacheOperationSourceAdvisor时设置为AnnotationCacheOperationSource
protected CacheOperationSource getCacheOperationSource() {
return cacheOperationSource;
}
};
2.2.缓存顾问(Advisor)
作用
基于cache操作的Advisor,调用缓存切面(Pointcut)判断是否拦截(是否有缓存注解),如果匹配在调用CacheInterceptor运行处理缓存的额外逻辑;
抽象类AbstractBeanFactoryPointcutAdvisor
public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
private BeanFactory beanFactory;
//**处理缓存的额外逻辑,volatile保证线程安全
private transient volatile Advice advice;
//**上面advice的名称
private String adviceBeanName;
//**advice锁
private transient volatile Object adviceMonitor = new Object();
//**设置advice名称
public void setAdviceBeanName(@Nullable String adviceBeanName) {
this.adviceBeanName = adviceBeanName;
}
//**重置advice锁
private void resetAdviceMonitor() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
this.adviceMonitor = ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
}
else {
this.adviceMonitor = new Object();
}
}
//**设置advice,为什么使用synchronized加锁,因为advice虽然是volatile,但赋值操作没有原子性
public void setAdvice(Advice advice) {
synchronized (this.adviceMonitor) {
this.advice = advice;
}
}
//**获取advice
public Advice getAdvice() {
//**如果设置了advice,直接返回advice
Advice advice = this.advice;
if (advice != null) {
return advice;
}
//**没有设置advice的话,advice名称和beanFactory不能为空
Assert.state(this.adviceBeanName != null, "'adviceBeanName' must be specified");
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
//**如果名称为adviceBeanName的advice为单例,从beanFactory获取该advice,然后返回该advice
//**单例,多线程调用获取advice的也是同一个实例,所以不用加锁
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
else {//**否则,加锁(保证多线程调用线程安全),然后从beanFactory获取该advice,然后返回该advice
//**多例,多线程调用获取advice不一定是同一个实例,所以需要加锁
synchronized (this.adviceMonitor) {
advice = this.advice;
if (advice == null) {
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
}
return advice;
}
}
}
//**序列化支持
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
resetAdviceMonitor();
}
}
缓存顾问BeanFactoryCacheOperationSourceAdvisor
public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
//**缓存操作源
private CacheOperationSource cacheOperationSource;
//**缓存切面
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
protected CacheOperationSource getCacheOperationSource() {
return cacheOperationSource;
}
};
//**设置缓存操作源
public void setCacheOperationSource(CacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
}
//**设置类过滤器
public void setClassFilter(ClassFilter classFilter) {
this.pointcut.setClassFilter(classFilter);
}
}
2.3.缓存拦截器(Interceptor)
作用
- 处理缓存的额外逻辑;
- 在执行缓存操作逻辑时,如果发生异常,调用缓存错误处理方法;
缓存拦截器CacheInterceptor
本类是缓存操作的入口,执行缓存相关操作的代码从这里开始;
//**方法拦截接口
public interface MethodInterceptor extends Interceptor {
//**拦截后调用的逻辑
Object invoke(MethodInvocation invocation) throws Throwable;
}
public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
//**处理缓存的额外逻辑
public Object invoke(final MethodInvocation invocation) throws Throwable {
//**要调用的目标方法
Method method = invocation.getMethod();
//**定义调用目标方法,获取返回值的函数,当前没有调用
CacheOperationInvoker aopAllianceInvoker = () -> {
try {
return invocation.proceed();
}
catch (Throwable ex) {
throw new CacheOperationInvoker.ThrowableWrapper(ex);
}
};
try {
//**调用父类CacheAspectSupport处理缓存操作
return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
}
catch (CacheOperationInvoker.ThrowableWrapper th) {
throw th.getOriginal();
}
}
}
缓存切面支持CacheAspectSupport
本类是缓存操作真正的处理逻辑,本类的核心又在execute方法;
- 实现了SmartInitializingSingleton接口:Spring会在所有单例的bean实例化后调用afterSingletonsInstantiated方法;
- 实现了BeanFactoryAware接口:Spring会调用setBeanFactory方法注入beanFactory;
- 实现了InitializingBean接口:Spring会调用afterPropertiesSet方法,并且会在上面两个方法之后运行。执行顺序参见springboot-bean生命周期;
public abstract class CacheAspectSupport extends AbstractCacheInvoker
implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {
//**缓存操作元数据
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
//**SpEL执行器
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
//**缓存操作源
private CacheOperationSource cacheOperationSource;
//**键生成器,默认为SimpleKeyGenerator
private SingletonSupplier<KeyGenerator> keyGenerator = SingletonSupplier.of(SimpleKeyGenerator::new);
//**获取缓存
private SingletonSupplier<CacheResolver> cacheResolver;
private BeanFactory beanFactory;
//**初始化标识
private boolean initialized = false;
//**配置默认值
public void configure(Supplier<CacheErrorHandler> errorHandler, Supplier<KeyGenerator> keyGenerator,
Supplier<CacheResolver> cacheResolver, Supplier<CacheManager> cacheManager) {
//**errorHandler默认使用SimpleCacheErrorHandler
this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new);
//**keyGenerator默认使用SimpleKeyGenerator
this.keyGenerator = new SingletonSupplier<>(keyGenerator, SimpleKeyGenerator::new);
//**cacheResolver默认使用SimpleCacheResolver
this.cacheResolver = new SingletonSupplier<>(cacheResolver,
() -> SimpleCacheResolver.of(SupplierUtils.resolve(cacheManager)));
}
//**设置缓存操作源
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
Assert.notEmpty(cacheOperationSources, "At least 1 CacheOperationSource needs to be specified");
//**如果设置了多个缓存操作源,就自动使用组合缓存操作源
this.cacheOperationSource = (cacheOperationSources.length > 1 ?
new CompositeCacheOperationSource(cacheOperationSources) : cacheOperationSources[0]);
}
//**设置CacheManager时,会初始化CacheResolver
public void setCacheManager(CacheManager cacheManager) {
this.cacheResolver = SingletonSupplier.of(new SimpleCacheResolver(cacheManager));
}
//**验证缓存操作源不能为空
public void afterPropertiesSet() {
Assert.state(getCacheOperationSource() != null, "...");
}
//**所有单例的bean实例化后调用,进行一些初始化工作
public void afterSingletonsInstantiated() {
//**如果没有设置CacheResolver,则从spring上下文中获取CacheManager,然后调用setCacheManager初始化CacheResolver
if (getCacheResolver() == null) {
Assert.state(this.beanFactory != null, "CacheResolver or BeanFactory must be set on cache aspect");
try {
setCacheManager(this.beanFactory.getBean(CacheManager.class));
}
catch (NoUniqueBeanDefinitionException ex) {
throw new IllegalStateException("No CacheResolver specified, ...");
}
catch (NoSuchBeanDefinitionException ex) {
throw new IllegalStateException("No CacheResolver specified, ...");
}
}
//**初始化标识
this.initialized = true;
}
//**返回方法的全限定名
protected String methodIdentification(Method method, Class<?> targetClass) {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
return ClassUtils.getQualifiedMethodName(specificMethod);
}
//**获取Cache集合
protected Collection<? extends Cache> getCaches(
CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver) {
//**调用cacheResolver获取Cache
Collection<? extends Cache> caches = cacheResolver.resolveCaches(context);
//**Cache不能为空
if (caches.isEmpty()) {
throw new IllegalStateException("No cache could be resolved for ...");
}
return caches;
}
//**获取缓存操作上下文
protected CacheOperationContext getOperationContext(
CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
//**根据缓存操作,方法名和目标类获取缓存操作元数据
CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass);
//**创建缓存操作上下文
return new CacheOperationContext(metadata, args, target);
}
//**获取缓存操作元数据
protected CacheOperationMetadata getCacheOperationMetadata(
CacheOperation operation, Method method, Class<?> targetClass) {
//**创建缓存操作元数据的key,key为CacheOperationCacheKey对象
CacheOperationCacheKey cacheKey = new CacheOperationCacheKey(operation, method, targetClass);
//**先从metadataCache中获取缓存操作元数据
CacheOperationMetadata metadata = this.metadataCache.get(cacheKey);
//**如果不存在,则创建缓存操作元数据,并存储到metadataCache中
if (metadata == null) {
//**如果缓存注解配置了KeyGenerator,则从spring上下文中获取该bean,如果没有,则获取当前类的了KeyGenerator
KeyGenerator operationKeyGenerator;
if (StringUtils.hasText(operation.getKeyGenerator())) {
operationKeyGenerator = getBean(operation.getKeyGenerator(), KeyGenerator.class);
}
else {
operationKeyGenerator = getKeyGenerator();
}
//**如果缓存注解配置了CacheResolver,则从spring上下文中获取该bean
//**如果没有配置CacheResolver,但配置了CacheManager,则从spring上下文中获取该bean,并创建CacheResolver
//**如果既没有CacheResolver,也没有配置CacheManager,则获取当前类的CacheResolver
CacheResolver operationCacheResolver;
if (StringUtils.hasText(operation.getCacheResolver())) {
operationCacheResolver = getBean(operation.getCacheResolver(), CacheResolver.class);
}
else if (StringUtils.hasText(operation.getCacheManager())) {
CacheManager cacheManager = getBean(operation.getCacheManager(), CacheManager.class);
operationCacheResolver = new SimpleCacheResolver(cacheManager);
}
else {
operationCacheResolver = getCacheResolver();
Assert.state(operationCacheResolver != null, "No CacheResolver/CacheManager set");
}
//**创建缓存操作元数据,并存储到metadataCache中
metadata = new CacheOperationMetadata(operation, method, targetClass,
operationKeyGenerator, operationCacheResolver);
this.metadataCache.put(cacheKey, metadata);
}
return metadata;
}
//**从spring上下文获取bean
protected <T> T getBean(String beanName, Class<T> expectedType) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory must be set ...");
}
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.beanFactory, expectedType, beanName);
}
//**清除缓存操作元数据metadataCache
protected void clearMetadataCache() {
this.metadataCache.clear();
this.evaluator.clear();
}
//**解析、拼装参数
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
//**如果已经初始化
if (this.initialized) {
//**获取对象的类
Class<?> targetClass = getTargetClass(target);
//**获取当前类的缓存操作源
CacheOperationSource cacheOperationSource = getCacheOperationSource();
//**如果缓存操作源不为空
if (cacheOperationSource != null) {
//**调用缓存操作源获取当前执行方法的缓存操作
Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass);
//**如果当前执行方法的缓存操作不为空
if (!CollectionUtils.isEmpty(operations)) {
//**创建CacheOperationContexts,然后执行缓存操作的逻辑
return execute(invoker, method,
new CacheOperationContexts(operations, method, args, target, targetClass));
}
}
}
return invoker.invoke();
}
//**调用CacheOperationInvoker,即CacheInterceptor中定义的调用目标方法的函数
protected Object invokeOperation(CacheOperationInvoker invoker) {
return invoker.invoke();
}
//**获取对象的类
private Class<?> getTargetClass(Object target) {
return AopProxyUtils.ultimateTargetClass(target);
}
//**真正执行缓存操作的逻辑
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
//**如果设置了sync=true
if (contexts.isSynchronized()) {
//**获取缓存操作上下文(CacheOperationContexts的determineSyncFlag验证了只有一个
//**@Cacheable注解的情况下才能设置sync=true,所以这里没有遍历,而是直接获取)
CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
//**如果condition表达式通过,从缓存中获取值
//**result传入了NO_RESULT,代表@Cacheable(sync=true)时,condition里#result获取不到方法的返回值
if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
//**获取缓存的key值(@Cacheable的key里#result也获取不到方法的返回值)
Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
//**获取Cache(sync=true时,只能有一个Cache,所以这里也没有遍历,而是直接获取)
Cache cache = context.getCaches().iterator().next();
try {
//**从缓存中获取值(如果没有则执行当前方法获取返回值,并设置到缓存中)
//**如果当前方法的返回值是Optional,但是获取的值不是,则把返回值包装成Optional(不会缓存Optional)
//**注意:真正的同步操作是Cache接口的get(Object key, Callable<T> valueLoader)定义,非本类实现
return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
}
catch (Cache.ValueRetrievalException ex) {
ReflectionUtils.rethrowRuntimeException(ex.getCause());
}
}
else {//**如果condition表达式没有通过,则执行当前方法获取返回值
return invokeOperation(invoker);
}
}
//**执行移除缓存(beforeInvocation=true),@CacheEvict注解的key里#result获取不到方法的返回值
processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
CacheOperationExpressionEvaluator.NO_RESULT);
//**执行获取缓存
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
//**执行获取缓存时未命中,收集修改缓存的请求(@Cacheable未命中缓存时,缓存修改缓存)
List<CachePutRequest> cachePutRequests = new LinkedList<>();
if (cacheHit == null) {
collectPutRequests(contexts.get(CacheableOperation.class),
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
}
Object cacheValue;
Object returnValue;
//**如果@Cacheable命中的缓存并且没有@CachePut,则包装返回值
if (cacheHit != null && !hasCachePut(contexts)) {
cacheValue = cacheHit.get();
returnValue = wrapCacheValue(method, cacheValue);
}
else {//**否则调用当前方法获取返回值,并解除包装
returnValue = invokeOperation(invoker);
cacheValue = unwrapReturnValue(returnValue);
}
//**收集@CachePut
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
//**执行修改缓存
for (CachePutRequest cachePutRequest : cachePutRequests) {
cachePutRequest.apply(cacheValue);
}
//**执行移除缓存(beforeInvocation=false)
processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);
return returnValue;
}
//**包装返回值,如果当前方法的返回值是Optional,但是获取的值不是,则把返回值包装成Optional
private Object wrapCacheValue(Method method, @Nullable Object cacheValue) {
if (method.getReturnType() == Optional.class &&
(cacheValue == null || cacheValue.getClass() != Optional.class)) {
return Optional.ofNullable(cacheValue);
}
return cacheValue;
}
//**解除包装返回值
private Object unwrapReturnValue(Object returnValue) {
return ObjectUtils.unwrapOptional(returnValue);
}
//**是否有有效的@CachePut操作
private boolean hasCachePut(CacheOperationContexts contexts) {
//**获取所有的CachePutOperation
Collection<CacheOperationContext> cachePutContexts = contexts.get(CachePutOperation.class);
//**遍历所有的CachePutOperation,计算condition表达式是否通过
Collection<CacheOperationContext> excluded = new ArrayList<>();
for (CacheOperationContext context : cachePutContexts) {
try {
//**result传入了RESULT_UNAVAILABLE,代表@CachePut的condition里#result不可用
if (!context.isConditionPassing(CacheOperationExpressionEvaluator.RESULT_UNAVAILABLE)) {
excluded.add(context);
}
}
catch (VariableNotAvailableException ex) { }
}
//**只要有一个condition通过,则返回true
return (cachePutContexts.size() != excluded.size());
}
//**遍历所有CacheEvictOperation,判断是否执行移除缓存
private void processCacheEvicts(
Collection<CacheOperationContext> contexts, boolean beforeInvocation, @Nullable Object result) {
for (CacheOperationContext context : contexts) {
CacheEvictOperation operation = (CacheEvictOperation) context.metadata.operation;
//**上面beforeInvocation为true和false各调了一次,但只有和@CacheEvict中配置的beforeInvocation相同的会生效
if (beforeInvocation == operation.isBeforeInvocation() && isConditionPassing(context, result)) {
performCacheEvict(context, operation, result);
}
}
}
//**执行移除缓存
private void performCacheEvict(
CacheOperationContext context, CacheEvictOperation operation, @Nullable Object result) {
Object key = null;
for (Cache cache : context.getCaches()) {
//**如果设置了allEntries=true,清除所有缓存
if (operation.isCacheWide()) {
logInvalidating(context, operation, null);
doClear(cache, operation.isBeforeInvocation());
}
else {
//**否则生成缓存的key值,删除指定key的缓存
if (key == null) {
key = generateKey(context, result);
}
logInvalidating(context, operation, key);
doEvict(cache, key, operation.isBeforeInvocation());
}
}
}
//**执行获取缓存
private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
Object result = CacheOperationExpressionEvaluator.NO_RESULT;
//**遍历所有的CacheableOperation
for (CacheOperationContext context : contexts) {
//**如果condition通过,@Cacheable的condition里#result获取不到返回值
if (isConditionPassing(context, result)) {
//**生成缓存的key值,@Cacheable的key里#result获取不到返回值
Object key = generateKey(context, result);
//**获取缓存值(从多个Cache中获取第一个匹配key的值)
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;
}
//**收货修改缓存的请求
private void collectPutRequests(Collection<CacheOperationContext> contexts,
@Nullable Object result, Collection<CachePutRequest> putRequests) {
for (CacheOperationContext context : contexts) {
if (isConditionPassing(context, result)) {
Object key = generateKey(context, result);
putRequests.add(new CachePutRequest(context, key));
}
}
}
//**获取缓存值(从多个Cache中获取第一个匹配key的值)
private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object key) {
for (Cache cache : context.getCaches()) {
Cache.ValueWrapper wrapper = doGet(cache, key);
if (wrapper != null) {
if (logger.isTraceEnabled()) {
logger.trace("Cache entry for key '" + key + "' found in cache '" + cache.getName() + "'");
}
return wrapper;
}
}
return null;
}
//**condition表达式是否通过
//**result传入NO_RESULT代表condition中#result获取不到返回值,传入RESULT_UNAVAILABLE代表#result不可用
private boolean isConditionPassing(CacheOperationContext context, @Nullable Object result) {
boolean passing = context.isConditionPassing(result);
if (!passing && logger.isTraceEnabled()) {
logger.trace("Cache condition failed on method ..." + context.metadata.operation);
}
return passing;
}
//**生成缓存的key值
//**result传入NO_RESULT代表key中#result获取不到返回值,传入RESULT_UNAVAILABLE代表#result不可用
private Object generateKey(CacheOperationContext context, @Nullable Object result) {
Object key = context.generateKey(result);
if (key == null) {
throw new IllegalArgumentException("Null key ...) " + context.metadata.operation);
}
if (logger.isTraceEnabled()) {
logger.trace("Computed cache key '" + key + "' for operation " + context.metadata.operation);
}
return key;
}
//**CacheOperationContexts源码解析参见上篇文章(springboot-redis cache基础类2.4小节)
private class CacheOperationContexts {
...
}
//**缓存操作元数据
protected static class CacheOperationMetadata {
private final CacheOperation operation;
private final Method method;
private final Class<?> targetClass;
private final Method targetMethod;
private final AnnotatedElementKey methodKey;
private final KeyGenerator keyGenerator;
private final CacheResolver cacheResolver;
public CacheOperationMetadata(CacheOperation operation, Method method, Class<?> targetClass,
KeyGenerator keyGenerator, CacheResolver cacheResolver) {
this.operation = operation;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.targetClass = targetClass;
this.targetMethod = (!Proxy.isProxyClass(targetClass) ?
AopUtils.getMostSpecificMethod(method, targetClass) : this.method);
this.methodKey = new AnnotatedElementKey(this.targetMethod, targetClass);
this.keyGenerator = keyGenerator;
this.cacheResolver = cacheResolver;
}
}
//**CacheOperationContext源码解析参见上篇文章(springboot-redis cache基础类2.4小节)
protected class CacheOperationContext implements CacheOperationInvocationContext<CacheOperation> {
...
}
//**缓存修改请求
private class CachePutRequest {
//**缓存操作上下文
private final CacheOperationContext context;
//**缓存的key值
private final Object key;
public CachePutRequest(CacheOperationContext context, Object key) {
this.context = context;
this.key = key;
}
//**修改缓存
public void apply(@Nullable Object result) {
if (this.context.canPutToCache(result)) {
for (Cache cache : this.context.getCaches()) {
doPut(cache, this.key, result);
}
}
}
}
//**缓存操作元数据metadataCache的key
private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {
private final CacheOperation cacheOperation;
private final AnnotatedElementKey methodCacheKey;
...
}
}