Spring 缓存切面
Posted 竺旭东
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 缓存切面相关的知识,希望对你有一定的参考价值。
缓存切面:【通知+目标方法调用】
缓存操作执行过程:
1)如果是同步调用【sync=true】,则首先尝试从缓存中读取数据,读取到则直接返回;
否则执行目标方法,将结果缓存后返回。
2)如果不是同步调用【sync=false,默认】
2-1)执行 beforeInvocation=true 并满足条件的 CacheEvict 操作,
2-2)从缓存操作上下文中根据缓存键读取数据【存在 @Cacheable 注解】,
缓存未命中:则收集 @Cacheable 缓存写入请求,并执行目标方法。
缓存命中且无满足条件的 CachePut 操作:直接读取缓存结果【目标方法不会被执行】。
2-3)从 @CachePut 注解上收集显式的缓存写入操作。
2-4)执行从 @Cacheable 和 @CachePut 上收集到的缓存写入操作。
2-5)执行 beforeInvocation=false 并满足条件的 CacheEvict 操作。
最佳实践:
@CachePut 注解使用在写入和更新操作上
@Cacheable 注解使用在读取操作上
@CacheEvict 注解使用在删除操作上
/**
* 执行缓存操作的基础组件,附加缓存异常处理器
*/
public abstract class AbstractCacheInvoker {
protected SingletonSupplier<CacheErrorHandler> errorHandler;
protected AbstractCacheInvoker() {
// 不做任何事情的异常处理器
this.errorHandler = SingletonSupplier.of(SimpleCacheErrorHandler::new);
}
protected AbstractCacheInvoker(CacheErrorHandler errorHandler) {
this.errorHandler = SingletonSupplier.of(errorHandler);
}
public void setErrorHandler(CacheErrorHandler errorHandler) {
this.errorHandler = SingletonSupplier.of(errorHandler);
}
public CacheErrorHandler getErrorHandler() {
return this.errorHandler.obtain();
}
/**
* 执行缓存 Get 操作
*/
@Nullable
protected Cache.ValueWrapper doGet(Cache cache, Object key) {
try {
return cache.get(key);
}
catch (RuntimeException ex) {
getErrorHandler().handleCacheGetError(ex, cache, key);
return null; // If the exception is handled, return a cache miss
}
}
/**
* 执行缓存 Put 操作
*/
protected void doPut(Cache cache, Object key, @Nullable Object result) {
try {
cache.put(key, result);
}
catch (RuntimeException ex) {
getErrorHandler().handleCachePutError(ex, cache, key, result);
}
}
/**
* 执行缓存 Evict 操作
*/
protected void doEvict(Cache cache, Object key) {
try {
cache.evict(key);
}
catch (RuntimeException ex) {
getErrorHandler().handleCacheEvictError(ex, cache, key);
}
}
/**
* 执行缓存 Clear 操作
*/
protected void doClear(Cache cache) {
try {
cache.clear();
}
catch (RuntimeException ex) {
getErrorHandler().handleCacheClearError(ex, cache);
}
}
}
/**
* 缓存切面的基础类
*/
public abstract class CacheAspectSupport extends AbstractCacheInvoker
implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {
protected final Log logger = LogFactory.getLog(getClass());
/**
* 缓存操作元数据缓存
*/
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
/**
* 缓存操作表达式解析器
*/
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
/**
* 缓存操作源:用于将缓存注解解析为缓存操作
*/
@Nullable
private CacheOperationSource cacheOperationSource;
/**
* 单例键生成器 Supplier
*/
private SingletonSupplier<KeyGenerator> keyGenerator = SingletonSupplier.of(SimpleKeyGenerator::new);
/**
* 单例缓存解析器 Supplier
*/
@Nullable
private SingletonSupplier<CacheResolver> cacheResolver;
/**
* Bean 工厂【DefaultListableBeanFactory】
*/
@Nullable
private BeanFactory beanFactory;
/**
* 切面是否已经初始化
*/
private boolean initialized = false;
@Override
public void afterSingletonsInstantiated() {
if (getCacheResolver() == null) {
// Lazily initialize cache resolver via default cache manager...
Assert.state(beanFactory != null, "CacheResolver or BeanFactory must be set on cache aspect");
try {
// 基于缓存管理器创建缓存解析器,并写入
setCacheManager(beanFactory.getBean(CacheManager.class));
}
catch (final NoUniqueBeanDefinitionException ex) {
throw new IllegalStateException("No CacheResolver specified, and no unique bean of type " +
"CacheManager found. Mark one as primary or declare a specific CacheManager to use.");
}
catch (final NoSuchBeanDefinitionException ex) {
throw new IllegalStateException("No CacheResolver specified, and no bean of type CacheManager found. " +
"Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.");
}
}
initialized = true;
}
/**
* 基于缓存操作执行上下文和缓存解析器读取缓存集合
*/
protected Collection<? extends Cache> getCaches(
CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver) {
final Collection<? extends Cache> caches = cacheResolver.resolveCaches(context);
if (caches.isEmpty()) {
throw new IllegalStateException("No cache could be resolved for ‘" +
context.getOperation() + "‘ using resolver ‘" + cacheResolver +
"‘. At least one cache should be provided per cache operation.");
}
return caches;
}
@Nullable
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
// 缓存切面是否启用
if (initialized) {
// 读取目标类 Class
final Class<?> targetClass = getTargetClass(target);
// 读取缓存操作源
final CacheOperationSource cacheOperationSource = getCacheOperationSource();
if (cacheOperationSource != null) {
// 读取目标方法上的所有缓存操作
final Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
// 执行缓存操作和目标方法
return execute(invoker, method,
new CacheOperationContexts(operations, method, args, target, targetClass));
}
}
}
// 未启用缓存切面,则直接调用目标方法
return invoker.invoke();
}
protected CacheOperationContext getOperationContext(
CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
// 读取缓存操作元数据
final CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass);
return new CacheOperationContext(metadata, args, target);
}
protected CacheOperationMetadata getCacheOperationMetadata(
CacheOperation operation, Method method, Class<?> targetClass) {
// 缓存操作的缓存键
final CacheOperationCacheKey cacheKey = new CacheOperationCacheKey(operation, method, targetClass);
// 已经创建过则直接读取
CacheOperationMetadata metadata = metadataCache.get(cacheKey);
if (metadata == null) {
KeyGenerator operationKeyGenerator;
// 1)缓存操作配置了键生成器
if (StringUtils.hasText(operation.getKeyGenerator())) {
// 写入指定 bean 名称的键生成器
operationKeyGenerator = getBean(operation.getKeyGenerator(), KeyGenerator.class);
}
else {
// 写入 SimpleKeyGenerator
operationKeyGenerator = getKeyGenerator();
}
CacheResolver operationCacheResolver;
// 2)缓存操作配置了缓存解析器
if (StringUtils.hasText(operation.getCacheResolver())) {
// 写入指定 bean 名称的缓存解析器
operationCacheResolver = getBean(operation.getCacheResolver(), CacheResolver.class);
}
// 3)缓存操作配置了缓存管理器
else if (StringUtils.hasText(operation.getCacheManager())) {
final CacheManager cacheManager = getBean(operation.getCacheManager(), CacheManager.class);
// 基于目标缓存管理器创建 SimpleCacheResolver 并写入
operationCacheResolver = new SimpleCacheResolver(cacheManager);
}
else {
// 写入默认的 SimpleCacheResolver
operationCacheResolver = getCacheResolver();
Assert.state(operationCacheResolver != null, "No CacheResolver/CacheManager set");
}
// 创建缓存操作元数据并加入缓存
metadata = new CacheOperationMetadata(operation, method, targetClass,
operationKeyGenerator, operationCacheResolver);
metadataCache.put(cacheKey, metadata);
}
return metadata;
}
protected <T> T getBean(String beanName, Class<T> expectedType) {
if (beanFactory == null) {
throw new IllegalStateException(
"BeanFactory must be set on cache aspect for " + expectedType.getSimpleName() + " retrieval");
}
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, expectedType, beanName);
}
/**
* Clear the cached metadata.
*/
protected void clearMetadataCache() {
metadataCache.clear();
evaluator.clear();
}
@Nullable
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
// 缓存切面是否启用
if (initialized) {
// 读取目标类 Class
final Class<?> targetClass = getTargetClass(target);
// 读取缓存操作源
final CacheOperationSource cacheOperationSource = getCacheOperationSource();
if (cacheOperationSource != null) {
// 读取目标方法上的所有缓存操作
final Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
// 执行缓存操作和目标方法
return execute(invoker, method,
new CacheOperationContexts(operations, method, args, target, targetClass));
}
}
}
// 未启用缓存切面,则直接调用目标方法
return invoker.invoke();
}
/**
* 执行底层目标方法
*/
protected Object invokeOperation(CacheOperationInvoker invoker) {
return invoker.invoke();
}
private Class<?> getTargetClass(Object target) {
return AopProxyUtils.ultimateTargetClass(target);
}
@Nullable
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
// 1)同步调用的特殊处理
if (contexts.isSynchronized()) {
final CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
// 缓存操作条件是否匹配
if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
// 计算缓存键
final Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
// 读取缓存
final Cache cache = context.getCaches().iterator().next();
try {
/**
* 如果缓存已经存在,则直接读取;否则执行目标方法,并将其结果值加入缓存。
* 并将结果值进行封装
*/
return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));
}
catch (final Cache.ValueRetrievalException ex) {
throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();
}
}
else {
// 缓存操作条件不匹配,则直接调用目标方法
return invokeOperation(invoker);
}
}
/**
* 1)处理方法调用前的缓存清除
* 如果指定了 CacheEvictOperation 操作 && beforeInvocation==true && 满足缓存操作条件,则执行缓存清除
*/
processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
CacheOperationExpressionEvaluator.NO_RESULT);
/**
* 2)从缓存操作上下文中,读取指定缓存键相关的条目
*/
final Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
// 缓存未命中,则收集 @Cacheable 缓存写入请求【结果变量 result 不可用】
final List<CachePutRequest> cachePutRequests = new LinkedList<>();
if (cacheHit == null) {
collectPutRequests(contexts.get(CacheableOperation.class),
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
}
Object cacheValue;
Object returnValue;
// 1)命中缓存
if (cacheHit != null && !hasCachePut(contexts)) {
// 无 CachePut 操作,则直接使用命中的缓存结果
cacheValue = cacheHit.get();
returnValue = wrapCacheValue(method, cacheValue);
}
else {
// 缓存未命中,则执行目标方法
returnValue = invokeOperation(invoker);
cacheValue = unwrapReturnValue(returnValue);
}
// 收集所有显式的 @CachePut 操作
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
// 执行从 @CachePut or @Cacheable 收集到的缓存写入操作
for (final CachePutRequest cachePutRequest : cachePutRequests) {
cachePutRequest.apply(cacheValue);
}
// 执行方法执行后的缓存清除操作
processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);
return returnValue;
}
@Nullable
private Object wrapCacheValue(Method method, @Nullable Object cacheValue) {
// 方法的返回结果为 Optional,则进行封装
if (method.getReturnType() == Optional.class &&
(cacheValue == null || cacheValue.getClass() != Optional.class)) {
return Optional.ofNullable(cacheValue);
}
return cacheValue;
}
@Nullable
private Object unwrapReturnValue(Object returnValue) {
return ObjectUtils.unwrapOptional(returnValue);
}
private boolean hasCachePut(CacheOperationContexts contexts) {
// 读取 CachePutOperation 的上下文集合
final Collection<CacheOperationContext> cachePutContexts = contexts.get(CachePutOperation.class);
final Collection<CacheOperationContext> excluded = new ArrayList<>();
for (final CacheOperationContext context : cachePutContexts) {
try {
// 缓存操作条件不匹配,则写入 excluded
if (!context.isConditionPassing(CacheOperationExpressionEvaluator.RESULT_UNAVAILABLE)) {
excluded.add(context);
}
}
catch (final VariableNotAvailableException ex) {
}
}
// 检查所有put是否已按条件排除
return cachePutContexts.size() != excluded.size();
}
private void processCacheEvicts(
Collection<CacheOperationContext> contexts, boolean beforeInvocation, @Nullable Object result) {
for (final CacheOperationContext context : contexts) {
final CacheEvictOperation operation = (CacheEvictOperation) context.metadata.operation;
// 满足缓存清除条件,则执行缓存清除
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 (final Cache cache : context.getCaches()) {
// 1)是否清缓存中的所有条目,默认为 false
if (operation.isCacheWide()) {
logInvalidating(context, operation, null);
// 清除缓存中的所有条目
doClear(cache);
}
else {
if (key == null) {
// 计算缓存键
key = generateKey(context, result);
}
logInvalidating(context, operation, key);
// 清除指定键关联的条目
doEvict(cache, key);
}
}
}
private void logInvalidating(CacheOperationContext context, CacheEvictOperation operation, @Nullable Object key) {
if (logger.isTraceEnabled()) {
logger.trace("Invalidating " + (key != null ? "cache key [" + key + "]" : "entire cache") +
" for operation " + operation + " on method " + context.metadata.method);
}
}
@Nullable
private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
final Object result = CacheOperationExpressionEvaluator.NO_RESULT;
for (final CacheOperationContext context : contexts) {
// 匹配缓存操作条件
if (isConditionPassing(context, result)) {
final Object key = generateKey(context, result);
// 从缓存中查找值
final 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 (final CacheOperationContext context : contexts) {
if (isConditionPassing(context, result)) {
final Object key = generateKey(context, result);
// 添加缓存写入请求
putRequests.add(new CachePutRequest(context, key));
}
}
}
@Nullable
private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object key) {
// 读取所有关联的缓存实例
for (final Cache cache : context.getCaches()) {
/**
* 基于缓存键读取值,如果找到则返回【
* 可引入本地缓存+Redis缓存模式,本地缓存优先读取】
*/
final 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;
}
/**
* 缓存操作条件是否匹配
*/
private boolean isConditionPassing(CacheOperationContext context, @Nullable Object result) {
final boolean passing = context.isConditionPassing(result);
if (!passing && logger.isTraceEnabled()) {
logger.trace("Cache condition failed on method " + context.metadata.method +
" for operation " + context.metadata.operation);
}
return passing;
}
/**
* 计算缓存键
*/
private Object generateKey(CacheOperationContext context, @Nullable Object result) {
final 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;
}
private class CacheOperationContexts {
/**
* 缓存操作与缓存操作上下文的映射
*/
private final MultiValueMap<Class<? extends CacheOperation>, CacheOperationContext> contexts;
private final boolean sync;
public CacheOperationContexts(Collection<? extends CacheOperation> operations, Method method,
Object[] args, Object target, Class<?> targetClass) {
contexts = new LinkedMultiValueMap<>(operations.size());
for (final CacheOperation op : operations) {
// 写入映射
contexts.add(op.getClass(), getOperationContext(op, method, args, target, targetClass));
}
// 写入同步执行标识
sync = determineSyncFlag(method);
}
/**
* 读取指定操作的 CacheOperationContext 集合
*/
public Collection<CacheOperationContext> get(Class<? extends CacheOperation> operationClass) {
final Collection<CacheOperationContext> result = contexts.get(operationClass);
return result != null ? result : Collections.emptyList();
}
public boolean isSynchronized() {
return sync;
}
private boolean determineSyncFlag(Method method) {
// 1)无 @Cacheable 操作,sync 为 false
final List<CacheOperationContext> cacheOperationContexts = contexts.get(CacheableOperation.class);
if (cacheOperationContexts == null) { // no @Cacheable operation at all
return false;
}
boolean syncEnabled = false;
// 2)至少存在一个 @Cacheable 操作的 sync 标识位为 true,则 sync 为 true
for (final CacheOperationContext cacheOperationContext : cacheOperationContexts) {
if (((CacheableOperation) cacheOperationContext.getOperation()).isSync()) {
syncEnabled = true;
break;
}
}
/**
* 3)如果 sync 为 true
* 不能指定多个缓存操作
* Cacheable 操作不能关联多个缓存
* 不能指定 unless 条件
*/
if (syncEnabled) {
if (contexts.size() > 1) {
throw new IllegalStateException(
"@Cacheable(sync=true) cannot be combined with other cache operations on ‘" + method + "‘");
}
if (cacheOperationContexts.size() > 1) {
throw new IllegalStateException(
"Only one @Cacheable(sync=true) entry is allowed on ‘" + method + "‘");
}
final CacheOperationContext cacheOperationContext = cacheOperationContexts.iterator().next();
final CacheableOperation operation = (CacheableOperation) cacheOperationContext.getOperation();
if (cacheOperationContext.getCaches().size() > 1) {
throw new IllegalStateException(
"@Cacheable(sync=true) only allows a single cache on ‘" + operation + "‘");
}
if (StringUtils.hasText(operation.getUnless())) {
throw new IllegalStateException(
"@Cacheable(sync=true) does not support unless attribute on ‘" + operation + "‘");
}
return true;
}
return false;
}
}
/**
* 缓存操作的元数据
*/
protected static class CacheOperationMetadata {
private final CacheOperation operation;
private final Method method;
private final Class<?> targetClass;
private final Method targetMethod;
/**
* 封装了注解元素和目标类型的 AnnotatedElementKey
*/
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;
targetMethod = !Proxy.isProxyClass(targetClass) ?
AopUtils.getMostSpecificMethod(method, targetClass) : this.method;
methodKey = new AnnotatedElementKey(targetMethod, targetClass);
this.keyGenerator = keyGenerator;
this.cacheResolver = cacheResolver;
}
}
/**
* 缓存操作上下文
*/
protected class CacheOperationContext implements CacheOperationInvocationContext<CacheOperation> {
private final CacheOperationMetadata metadata;
private final Object[] args;
private final Object target;
private final Collection<? extends Cache> caches;
private final Collection<String> cacheNames;
@Nullable
private Boolean conditionPassing;
public CacheOperationContext(CacheOperationMetadata metadata, Object[] args, Object target) {
this.metadata = metadata;
this.args = extractArgs(metadata.method, args);
this.target = target;
caches = CacheAspectSupport.this.getCaches(this, metadata.cacheResolver);
cacheNames = createCacheNames(caches);
}
@Override
public CacheOperation getOperation() {
return metadata.operation;
}
@Override
public Object getTarget() {
return target;
}
@Override
public Method getMethod() {
return metadata.method;
}
@Override
public Object[] getArgs() {
return args;
}
private Object[] extractArgs(Method method, Object[] args) {
if (!method.isVarArgs()) {
return args;
}
final Object[] varArgs = ObjectUtils.toObjectArray(args[args.length - 1]);
final Object[] combinedArgs = new Object[args.length - 1 + varArgs.length];
System.arraycopy(args, 0, combinedArgs, 0, args.length - 1);
System.arraycopy(varArgs, 0, combinedArgs, args.length - 1, varArgs.length);
return combinedArgs;
}
protected boolean isConditionPassing(@Nullable Object result) {
if (conditionPassing == null) {
// 1)注解的缓存条件不为空
if (StringUtils.hasText(metadata.operation.getCondition())) {
// 创建计算上下文
final EvaluationContext evaluationContext = createEvaluationContext(result);
// 基于 CacheOperationExpressionEvaluator 计算目标条件
conditionPassing = evaluator.condition(metadata.operation.getCondition(),
metadata.methodKey, evaluationContext);
}
else {
// 2)未指定条件默认匹配
conditionPassing = true;
}
}
return conditionPassing;
}
/**
* unless 条件未指定或为 false 时,才允许将结果加入到缓存中
*/
protected boolean canPutToCache(@Nullable Object value) {
String unless = "";
// 1)从 CacheableOperation 读取 unless 条件
if (metadata.operation instanceof CacheableOperation) {
unless = ((CacheableOperation) metadata.operation).getUnless();
}
// 2)从 CachePutOperation 读取 unless 条件
else if (metadata.operation instanceof CachePutOperation) {
unless = ((CachePutOperation) metadata.operation).getUnless();
}
// 如果 unless 条件不为空,则计算其值
if (StringUtils.hasText(unless)) {
final EvaluationContext evaluationContext = createEvaluationContext(value);
return !evaluator.unless(unless, metadata.methodKey, evaluationContext);
}
// 未指定,则默认将结果加入缓存中
return true;
}
/**
* Compute the key for the given caching operation.
*/
@Nullable
protected Object generateKey(@Nullable Object result) {
// 1)基于指定的 SpEL 表达式解析缓存键
if (StringUtils.hasText(metadata.operation.getKey())) {
final EvaluationContext evaluationContext = createEvaluationContext(result);
return evaluator.key(metadata.operation.getKey(), metadata.methodKey, evaluationContext);
}
// 2)基于键生成器生成缓存键
return metadata.keyGenerator.generate(target, metadata.method, args);
}
private EvaluationContext createEvaluationContext(@Nullable Object result) {
return evaluator.createEvaluationContext(caches, metadata.method, args,
target, metadata.targetClass, metadata.targetMethod, result, beanFactory);
}
protected Collection<? extends Cache> getCaches() {
return caches;
}
protected Collection<String> getCacheNames() {
return cacheNames;
}
private Collection<String> createCacheNames(Collection<? extends Cache> caches) {
final Collection<String> names = new ArrayList<>();
for (final Cache cache : caches) {
names.add(cache.getName());
}
return names;
}
}
private class CachePutRequest {
/**
* 缓存操作上下文
*/
private final CacheOperationContext context;
/**
* 缓存键
*/
private final Object key;
public CachePutRequest(CacheOperationContext context, Object key) {
this.context = context;
this.key = key;
}
public void apply(@Nullable Object result) {
// 方法执行结果是否需要加入缓存中
if (context.canPutToCache(result)) {
// 将结果加入相关的缓存中
for (final Cache cache : context.getCaches()) {
doPut(cache, key, result);
}
}
}
}
private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {
/**
* 缓存操作
*/
private final CacheOperation cacheOperation;
/**
* 注解元素
*/
private final AnnotatedElementKey methodCacheKey;
private CacheOperationCacheKey(CacheOperation cacheOperation, Method method, Class<?> targetClass) {
this.cacheOperation = cacheOperation;
methodCacheKey = new AnnotatedElementKey(method, targetClass);
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof CacheOperationCacheKey)) {
return false;
}
final CacheOperationCacheKey otherKey = (CacheOperationCacheKey) other;
return cacheOperation.equals(otherKey.cacheOperation) &&
methodCacheKey.equals(otherKey.methodCacheKey);
}
@Override
public int hashCode() {
return cacheOperation.hashCode() * 31 + methodCacheKey.hashCode();
}
@Override
public String toString() {
return cacheOperation + " on " + methodCacheKey;
}
@Override
public int compareTo(CacheOperationCacheKey other) {
int result = cacheOperation.getName().compareTo(other.cacheOperation.getName());
if (result == 0) {
result = methodCacheKey.compareTo(other.methodCacheKey);
}
return result;
}
}
}
/**
* 声明式缓存管理 MethodInterceptor
*/
@SuppressWarnings("serial")
public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
@Override
@Nullable
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 {
// 执行核心操作
return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
}
catch (CacheOperationInvoker.ThrowableWrapper th) {
throw th.getOriginal();
}
}
}
以上是关于Spring 缓存切面的主要内容,如果未能解决你的问题,请参考以下文章