目录
从spring3.1开始,Spring引入了对Cache的支持。其使用方法和原理都类似于Spring对事务管理的支持。Spring Cache是作用在方法上的。
核心思想
当调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring Cache时要保证缓存的方法对于相同的方法参数要有相同的返回结果。
使用Spring Cache需要做两方面的事:
- 声明某些方法使用缓存
- 配置Spring对Cache的支持
与Spring对事务管理的支持一样,Spring对Cache的支持也有基于注解和基于XML配置两种方式。下面我们先来看看基于注解的方式。
1.1 概述
Spring为我们提供了几个注解来支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素。
1.2 @Cacheable使用
ex1:
@Cacheable(cacheNames = CacheConstants.TEST, key = "#args[0]+'_'+#args[1]", unless = "#result == null")
ex2:
@Cacheable(value = CacheConstants.TEST, key = "#bean.payType +'_'+ #bean.shopNo",
condition = "#result != null && #result.size() != 0", sync = true)
public Map<String, String> getHost(Bean bean) {
......
}
字段释义:
value:等同于cacheNames用于指定缓存名称;
key:指定缓存的key,可以使用spel表达式构建
keyGenerator:(需要自己配置对应的bean)指定key的生成策略根据参数生成key,和key互斥
condition:指定缓存生效的条件,对请求参数进行判断unless:是指定条件下进行缓存,是在返回之后判断是否进行缓存,是对结果进行判断
cacheManager: 指定自定义的缓存管理器(可以详细配置缓存的各种属性,过期时间,序列化方式等,可以指定缓存实现方式,比如整合guava本地缓存或者Redis分布式缓存)sync:是否同步,true/false。在一个多线程的环境中,某些操作可能被相同的参数并发地调用,这样同一个 value 值可能被多次计算(或多次访问 db),这样就达不到缓存的目的。针对这些可能高并发的操作,我们可以使用 sync 参数来告诉底层的缓存提供者将缓存的入口锁住,这样就只能有一个线程计算操作的结果值,而其它线程需要等待,这样就避免了 n-1 次数据库访问
1.3 整合Redisson缓存
@EnableCaching
@Configuration
public class LocalCacheConfig {
@Bean("cacheManager")
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<>(4);
// 配置失效策略
config.put(CacheConstants.TEST, new CacheConfig(3 * 60 * 1000, 2 * 60 * 1000));
config.put("ttl3", new CacheConfig(3 * 60 * 1000, 2 * 60 * 1000));
config.put("ttl5", new CacheConfig(5 * 60 * 1000, 3 * 60 * 1000));
config.put("ttl10", new CacheConfig(10 * 60 * 1000, 5 * 60 * 1000));
RedissonSpringCacheManager cacheManager = new RedissonSpringCacheManager(redissonClient, config);
// 默认jack序列化
cacheManager.setCodec(new JsonJacksonCodec());
cacheManager.setAllowNullValues(false);
return cacheManager;
}
}
1.4 整合Guava本地缓存
@Slf4j
@EnableCaching
@Configuration
public class LocalCacheConfig {
@Bean("cacheManager")
public CacheManager cacheManager() {
SimpleCacheManager manager = new SimpleCacheManager();
List<Cache> list = new ArrayList();
GuavaCache testCache = new GuavaCache(CacheConstants.TEST,
CacheBuilder.newBuilder()
.concurrencyLevel(500)
.recordStats()
.maximumSize(1024)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build());
list.add(testCache);
manager.setCaches(list);
return manager;
}
}