@Configuration
public class CaffeineCacheConfiguration {
@Bean
@ConfigurationProperties(prefix = "caffeine")
public Map<String, String> cacheSpecs() {
return new HashMap<>();
}
@Bean
public CacheManager cacheManager() {
Map<String, String> cacheSpecs = cacheSpecs();
SimpleCaffeineCacheManager manager = new SimpleCaffeineCacheManager(cacheSpecs);
if (!cacheSpecs.isEmpty()) {
List<CaffeineCache> caches = cacheSpecs.entrySet().stream()
.map(entry -> buildCache(entry.getKey(), entry.getValue())).collect(Collectors.toList());
manager.setCaches(caches);
}
return manager;
}
private CaffeineCache buildCache(String name, String cfg) {
CacheConfig cacheConfig = new CacheConfig(cfg);
final Caffeine<Object, Object> caffeineBuilder = Caffeine.newBuilder()
.expireAfterWrite(cacheConfig.getExpire(), TimeUnit.SECONDS).maximumSize(cacheConfig.getSize());
return new CaffeineCache(name, caffeineBuilder.build());
}
private class SimpleCaffeineCacheManager extends SimpleCacheManager {
private Map<String, String> cacheSpecs;
public SimpleCaffeineCacheManager(Map<String, String> cacheSpecs) {
super();
this.cacheSpecs = cacheSpecs;
}
@Override
protected Cache getMissingCache(String name) {
String cfg = this.cacheSpecs.get(name);
if (StringUtils.isBlank(cfg)) {
cfg = this.cacheSpecs.get("default");
if (cfg == null)
throw new IllegalArgumentException(String.format("Undefined [default] caffeine cache"));
}
return buildCache(name, cfg);
}
}
/**
* 缓存配置
*/
private class CacheConfig {
private long size = 0L;
private long expire = 0L;
public CacheConfig(String cfg) {
String[] cfgs = cfg.split(",");
if (cfgs.length == 1) {
String sSize = cfgs[0].trim();
this.size = Long.parseLong(sSize);
} else if (cfgs.length == 2) {
String sSize = cfgs[0].trim();
String sExpire = cfgs[1].trim();
this.size = Long.parseLong(sSize);
char unit = Character.toLowerCase(sExpire.charAt(sExpire.length() - 1));
this.expire = Long.parseLong(sExpire.substring(0, sExpire.length() - 1));
switch (unit) {
case 's':// seconds
break;
case 'm':// minutes
this.expire *= 60;
break;
case 'h':// hours
this.expire *= 3600;
break;
case 'd':// days
this.expire *= 86400;
break;
default:
throw new IllegalArgumentException("Unknown expire unit:" + unit);
}
}
}
public long getSize() {
return size;
}
public long getExpire() {
return expire;
}
@Override
public String toString() {
return String.format("[SIZE:%d,EXPIRE:%d]", size, expire);
}
}
}
application.properities
### cache
spring.cache.type=caffeine
#########################################
# Caffeine configuration
# caffeine.[name] = size, xxxx[s|m|h|d]
#########################################
caffeine.default=10, 10m
caffeine.sales=1000, 30m