Spring Boot缓存配置不同到期时间

/ Java / 没有评论 / 2252浏览

在缓存配置中,比如spring.cache.caffeine.spec=maximumSize=500,expireAfterWrite=10s,所有的缓存的到期策略都是一样的,如果我们要实现不同数据的缓存到期时间不一致,可以用自定义CacheManager

不同的缓存内容

@Cacheable("student")
public Student getOne(int id) {
    log.info("load one student");
    return studentMapper.selectOne(id);
}
@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的工作,我们可以修改配置来新增缓存

caching.specs.student.timeout=2
caching.specs.person.timeout=10
@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();
    }
}

参考