参考该文,结合个人经验,实践如下 ,简单对比几个方案。
1) 本地HashMap 手动存取:适合 缓存的总个数已知,并且value值不变的情况,比如 :
public static Map<Integer, String> map = new HashMap<Integer, String>() {
{
put(101, "北京,CN.BJ");
put(102, "上海,CN.SH");
put(103, "天津,CN.TJ");
put(104, "重庆,CN.CQ");
put(111, "西藏,CN.XZ");
put(112, "新疆,CN.XJ");
put(113, "海南,CN.HA");
put(114, "河北,CN.HB");
put(115, "浙江,CN.ZJ");
put(131, "安徽,CN.AH");
put(141, "吉林,CN.JL");
//。。。。。。省略
put(142, "广西,CN.GX");
put(143, "贵州,CN.GZ");
put(144, "陕西,CN.SA");
put(145, "青海,CN.QH");
put(146, "宁夏,CN.NX");
put(151, "香港,CN.HK");
put(152, "澳门,CN.MA");
put(153, "台湾,CN.TA"); // 中华民国和中华人民共和国什么关系?所谓的中国,到底是哪个?TW和大陆什么关系?
}
2)仅使用 @Cacheable 注解 ,其他的自动化的东西spring帮你搞定,适合快速开发测试用。
不要在生产线上用,因为有问题:1》 不能设置过期策略,2》不能设置总大小,容易OOM
原理:spring 默认使用 SimpleCache 实现类,默认 key 的策略 是 对所有参数 取 hashcode
3)@cacheable + 第三方 cache 实现类 ,比如 guava,EhCache 。
3.1) 因为 Ehcache 需要配置烦人的xml,放弃。这里介绍 guava cache ,代码如下
配置类:
import com.google.common.cache.CacheBuilder;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.guava.GuavaCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 配置 guava cache
* 参考 https://cloud.tencent.com/developer/article/1058752
* @author stormfeng
* @date 2021-02-22 16:12
*/
@Configuration
@EnableCaching
public class CachingConfig extends CachingConfigurerSupport {
@Override
@Bean
public CacheManager cacheManager() {
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(buildCaches("1s", "5min", "30min", "1day"));
return manager;
}
/**
* guava cache
*/
private List<Cache> buildCaches(String... cacheNames) {
List<Cache> result = new ArrayList<>();
for (String cacheName : cacheNames) {
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder()
.initialCapacity(100) // 初始化容量
.maximumSize(1000) // 最大容量
.recordStats();
switch (cacheName) {
case "1s":
builder.expireAfterWrite(1, TimeUnit.SECONDS);
break;
case "5min":
builder.expireAfterWrite(5, TimeUnit.MINUTES);
break;
case "30min":
builder.expireAfterWrite(30, TimeUnit.MINUTES);
break;
default:
builder.expireAfterWrite(1, TimeUnit.DAYS);
break;
}
GuavaCache guavaCache = new GuavaCache(cacheName,builder.build());
result.add(guavaCache);
}
return result;
}
}
使用:
/**
* 缓存生成后,保存 30 min
*/
@Cacheable(cacheNames = "30min",sync = true,key="#root.methodName + #games.hashCode() + #date")
@Override
public Object getObject(List games,String date){
// 。。。。。。
return null;
}
待续