Spring从版本3.1开始提供非侵入的将Cache集成到Spring应用的方式。Spring Cache提供Cache的统一抽象,支持集成各种不同的缓存解决方案。从4.1版本开始,提供了注解和更多的定制参数。
Spring Cache 抽象提供了对Java方法的缓存,使用Spring Cache缓存,当方法调用使用相同的参数,调用结果被缓存下来,当方法被再次调用时将直接返回参数结果。
org.springframework.cache.Cache 提供Spring框架中使用的Cache的统一抽象功能, 具体的实现类使用实际的缓存解决方案。
org.springframework.cache.CacheManager:Spring cache 管理API。不同的CacheManager实现提供对相应Cache实现缓存的管理,通过管理API Cache getCache(String name);方法对外提供。
org.springframework.cache.interceptor.CacheResolver 方法调用拦截使用来获取Cache实现的Resolver,通常使用相应的CacheManager实现类来获取Cache。
org.springframework.cache.interceptor. KeyGenerator: 缓存中Key的生成实现。默认的key生成器:org.springframework.cache.interceptor.SimpleKeyGenerator 类
1. 方法没有参数则使用SimpleKey.EMPTY
2. 方法只有一个参数:key=唯一参数
3. 方法有多个参数:SimpleKey(params)
可以通过实现org.springframework.cache.interceptor.KeyGenerator接口定制key生成器。
@Configuration
@EnableCaching
@Cacheable: 作用于方法之上,配置方法缓存
@Cacheable("cacheName"): 指定用于缓存结果的缓存名称,当指定多个名称时,方法调用将在多个缓存中查找相同参数的方法调用,命中即返回。
Cache 的key
指定KeyGenerator:
@Cacheable(cacheNames="XXX", keyGenerator="myKeyGenerator")。
通过SpEL指定key
@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@CachePut: @CachePut指定的方法不影响方法的执行,方法执行结果将用于更新缓存。@CachePut支持同@Cacheable一样的配置。
示例:
@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)
@CacheEvict: 触发缓存清理陈旧或无用的数据。可以配置指定数据的清理或Cache范围的清理。
示例:
@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch)
@Caching: 在一个方法上指定触发缓存的多个操作。
示例:
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)
@CacheConfig: 以上的注解都是方法级别的注解,@CacheConfig提供类级别的公共配置,该类下的方法级别配置如无指定则使用类级别上的@CacheConfig。
使用 Spring AOP切面实现Cache相关方法的拦截获取缓存和Cache请求的处理
org.springframework.cache.interceptor.CacheProxyFactoryBean
相关代码:
private Pointcut pointcut = Pointcut.TRUE;
protected Object createMainInterceptor() { this.cacheInterceptor.afterPropertiesSet(); return new DefaultPointcutAdvisor(this.pointcut, this.cacheInterceptor); } |
org.springframework.cache.interceptor.MethodInterceptor接口,
CacheAspectSupport.execute方法是Spring Cache核心处理流程,下面是主要流程的部分代码解析:
// 处理CacheEvict请求 processCacheEvicts(contexts.get(CacheEvictOperation.class), true, CacheOperationExpressionEvaluator.NO_RESULT); // 从缓存中查询是否存在缓存 Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class)); // 如未命中,生成CachePut请求:缓存条件满足 List if (cacheHit == null) { collectPutRequests(contexts.get(CacheableOperation.class), CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests); } Object cacheValue; Object returnValue; if (cacheHit != null && !hasCachePut(contexts)) { //缓存命中,并且没有Put需求,返回缓存值 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); } // 处理缓存Evicts请求 rocessCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue); return returnValue; } |