package com.farriver.bwf.service.config.cache; import io.jsonwebtoken.lang.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.lang.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; /** * 开发者可以通过自定义CacheResolver实现动态选择CacheManager, * 如下通过代码实现多种缓存机制: * 优先从堆内存读取缓存,堆内存缓存不存在时再从redis读取缓存, * redis缓存不存在时最后从mysql读取数据,并将读取到的数据依次写到redis和堆内存中。 */ public class CustomCacheResolver implements CacheResolver, InitializingBean { private static final Logger logger = LoggerFactory.getLogger(CustomCacheResolver.class); @Nullable private List cacheManagerList; public CustomCacheResolver() { } public CustomCacheResolver(List cacheManagerList) { this.cacheManagerList = cacheManagerList; } public void setCacheManagerList(@Nullable List cacheManagerList) { this.cacheManagerList = cacheManagerList; } public List getCacheManagerList() { return cacheManagerList; } @Override public void afterPropertiesSet() { Assert.notNull(this.cacheManagerList, "CacheManager is required"); } @Override public Collection resolveCaches(CacheOperationInvocationContext cacheOperationInvocationContext) { Collection cacheNames = getCacheNames(cacheOperationInvocationContext); if (cacheNames == null) { return Collections.emptyList(); } Collection result = new ArrayList<>(); for (CacheManager cacheManager : getCacheManagerList()) { for (String cacheName : cacheNames) { Cache cache = cacheManager.getCache(cacheName); if (cache == null) { throw new IllegalArgumentException("Cannot find cache named '" + cacheName + "' for" + cacheOperationInvocationContext.getOperation()); } result.add(cache); } } return result; } private Collection getCacheNames(CacheOperationInvocationContext cacheOperationInvocationContext) { return cacheOperationInvocationContext.getOperation().getCacheNames(); } }