要在项目中使用下本地缓存,方便更快的调用数据, 查询了很多文档发现都比较冗余,于是自己摸索了好一会才整理出一套能用的模板。文末附上了完整代码
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
/**
* 自定义的key生成规则.
* @return
*/
@Bean("dataKeyGenerator")
public KeyGenerator dataKeyGenerator() {
return (o, method, objects) -> method.getName() + "_" + Arrays.asList(objects);
}
@Bean
public CacheManager cacheManager(Ticker ticker) {
// 缓存的数据,有效期60分钟,可以一次性配置多个
CaffeineCache dataClustersCache = buildCache("data_types_clusters", ticker, 60);
CaffeineCache dataHostCache = buildCache("data_types_hosts", ticker, 60);
SimpleCacheManager manager = new SimpleCacheManager();
// 一起放入
manager.setCaches(Arrays.asList(dataClustersCache, dataHostCache));
return manager;
}
expireAfterWrite 最后一次写入后经过固定时间过期
expireAfterAccess 最后一次写入或访问后经过固定时间过期
refreshAfterWrite 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存
一般使用用expireAfterWrite 即可
private CaffeineCache buildCache(String name, Ticker ticker, int minutesToExpire) {
return new CaffeineCache(name, Caffeine.newBuilder()
.expireAfterWrite(minutesToExpire, TimeUnit.MINUTES)
.maximumSize(100)
.ticker(ticker)
.build());
}
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Ticker;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/** springboot的caffeine本地缓存配置.
*/
@Slf4j
@Configuration
public class CacheConfig {
@Data
public static class CacheSpec {
private Integer timeout;
private Integer max = 200;
}
@Bean
public CacheManager cacheManager(Ticker ticker) {
// 下拉框的数据,有效期60分钟
CaffeineCache dataTest1 = buildCache("data_types_test1", ticker, 60);
CaffeineCache dataTest2 = buildCache("data_types_test2", ticker, 60);
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(Arrays.asList(dataTest1 , dataTest2 ));
return manager;
}
private CaffeineCache buildCache(String name, Ticker ticker, int minutesToExpire) {
return new CaffeineCache(name, Caffeine.newBuilder()
.expireAfterWrite(minutesToExpire, TimeUnit.MINUTES)
.maximumSize(100)
.ticker(ticker)
.build());
}
/**
* 自定义的key生成规则.
* @return
*/
@Bean("dataKeyGenerator")
public KeyGenerator dataKeyGenerator() {
return (o, method, objects) -> method.getName() + "_" + Arrays.asList(objects);
}
@Bean
public Ticker ticker() {
return Ticker.systemTicker();
}
}
使用的时候只需要把cacheManager中自己需要的key,写入即可
启动方法类上添加注解@EnableCaching
@Override
@Cacheable(cacheNames = "data_types_test1", keyGenerator = "dataKeyGenerator")
public List<String> test() {
return xxx;
}
CV后要修改的其实就是一个manager,以及自己要使用的方法上添加下对应的cacheable注解即可。
注意一个问题,controller调用service的test()会调用缓存,但是如果是service内部间的调用test(), 并不会触发缓存。目前也不知道原因。