在缓存配置中,比如
spring.cache.caffeine.spec=maximumSize=500,expireAfterWrite=10s
,所有的缓存的到期策略都是一样的,如果我们要实现不同数据的缓存到期时间不一致,可以用自定义CacheManager
不同的缓存内容
- 缓存student
@Cacheable("student")
public Student getOne(int id) {
log.info("load one student");
return studentMapper.selectOne(id);
}
- 缓存person
@Cacheable("person")
public Person getOne(int id) {
log.info("load one person");
return personMapper.selectOne(id);
}
自定义CacheManager
@Bean
public CacheManager cacheManager(Ticker ticker) {
CaffeineCache messageCache = buildCache("person", ticker, 10);
CaffeineCache notificationCache = buildCache("student", ticker, 2);
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(Arrays.asList(messageCache, notificationCache));
return manager;
}
private CaffeineCache buildCache(String name, Ticker ticker, int secondsToExpire) {
return new CaffeineCache(name, Caffeine.newBuilder()
.expireAfterWrite(secondsToExpire, TimeUnit.SECONDS)
.maximumSize(100)
.ticker(ticker)
.build());
}
@Bean
public Ticker ticker() {
return Ticker.systemTicker();
}
上面配置中,缓存person是10秒过期,student是2秒过期
缺点
这种方式可以实现不同缓存的不同到期时间,但是后面再新增缓存数据的话,都需要再在CacheManager中配置
改进版:更灵活的配置
为了缓解每次新增缓存都要修改CacheManager
的工作,我们可以修改配置来新增缓存
application.properties
caching.specs.student.timeout=2
caching.specs.person.timeout=10
CacheConfiguration
@Configuration
@ConfigurationProperties(prefix = "caching")
@Data
@Slf4j
@Component
public class CacheConfiguration {
@Data
public static class CacheSpec {
private Integer timeout;
private Integer max = 200;
}
private Map<String, CacheSpec> specs;
@Bean
public CacheManager cacheManager(Ticker ticker) {
SimpleCacheManager manager = new SimpleCacheManager();
if (specs != null) {
List<CaffeineCache> caches =
specs.entrySet().stream()
.map(entry -> buildCache(entry.getKey(),
entry.getValue(),
ticker))
.collect(Collectors.toList());
manager.setCaches(caches);
}
return manager;
}
private CaffeineCache buildCache(String name, CacheSpec cacheSpec, Ticker ticker) {
log.info("Cache {} specified timeout of {} min, max of {}", name, cacheSpec.getTimeout(), cacheSpec.getMax());
final Caffeine<Object, Object> caffeineBuilder
= Caffeine.newBuilder()
.expireAfterWrite(cacheSpec.getTimeout(), TimeUnit.SECONDS)
.maximumSize(cacheSpec.getMax())
.ticker(ticker);
return new CaffeineCache(name, caffeineBuilder.build());
}
@Bean
public Ticker ticker() {
return Ticker.systemTicker();
}
}
网友评论