介绍

Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。

缓存和ConcurrentMap有点相似,但还是有所区别。最根本的区别是ConcurrentMap将会持有所有加入到缓存当中的元素,直到它们被从缓存当中手动移除。

但是,Caffeine的缓存Cache 通常会被配置成自动驱逐缓存中元素,以限制其内存占用。在某些场景下,LoadingCache和AsyncLoadingCache 因为其自动加载缓存的能力将会变得非常实用。

基本使用

GitHub 官方文档:https://github.com/ben-manes/caffeine/wiki/Home-zh-CN

项目集成

使用 Caffeine 作为一级缓存,Redis 作为二级缓存。先从 Caffeine 读取缓存,如果读不到则到 Redis 中读取,如果还没有则返回 null.

模块使用了 Redis 作为二级缓存,使用 stringRedisTemplate 模板,Jedis 作为客户端。

Spring 配置

@Configuration
public class Config {
@Bean
public AbstractStringFirstCache stringFirstCache() {
// 可以随意更换底层实现,比如我们可以使用 Guava Cache,只需要 new GuavaCache() 并继承 AbstractStringFirstCache 即可
return new CaffeineCache();
} @Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
return new StringRedisTemplate(factory);
} @Bean
public JedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("localhost", 6379);
return new JedisConnectionFactory(config);
}
}

核心代码


// 核心接口
public interface FirstCache<K, V> {
V get(@NonNull K key); void set(@NonNull K key, V value); void delete(@NonNull K key);
} public abstract class AbstractFirstCache<K, V> implements FirstCache<K, V> {
} public abstract class AbstractStringFirstCache extends AbstractFirstCache<String, String> {
abstract void set(@NonNull String key, String value, Long expertTime, TimeUnit timeUnit);
} public class CaffeineCache extends AbstractStringFirstCache { Log log = LogFactory.get(); //Hutool api @Autowired
private StringRedisTemplate stringRedisTemplate; LoadingCache<String, String> caffeineCache; public CaffeineCache() {
LoadingCache<String, String> cache = Caffeine.newBuilder()
.recordStats()
.initialCapacity(100)
.maximumSize(1000)
.writer(new CacheWriter<String, String>() {
@Override
public void write(String key, String value) {
log.info("caffeineCache write key=" + key + ", value=" + value);
} @Override
public void delete(String key, String value, RemovalCause cause) {
log.info("caffeineCache delete key=" + key);
}
})
.expireAfterWrite(30, TimeUnit.SECONDS) //一个元素将会在其创建或者最近一次被更新之后的一段时间后被认定为过期项
.build(new CacheLoader<String, String>() {
// 查询二级缓存
@Override
public @Nullable String load(@NonNull String s) throws Exception {
String value = stringRedisTemplate.opsForValue().get(s);
if (StrUtil.isEmpty(value)) {
return null;
}
return value;
}
});
caffeineCache = cache;
} @Override
public String get(String key) {
//查找缓存,如果缓存不存在则生成缓存元素
String value = caffeineCache.get(key);
log.info("get key from caffeineCache, key: " + key);
return value;
} @Override
public void set(String key, String value) {
//放入二级缓存
stringRedisTemplate.opsForValue().set(key, value);
stringRedisTemplate.expire(key, 15, TimeUnit.MINUTES);
} @Override
void set(String key, String value, Long expertTime, TimeUnit timeUnit) {
stringRedisTemplate.opsForValue().set(key, value);
stringRedisTemplate.expire(key, expertTime, timeUnit);
} @Override
public void delete(String key) {
caffeineCache.invalidate(key);
stringRedisTemplate.delete(key);
log.info("delete key from caffeineCache, key: " + key);
}
}

工具类

@Component
public class CaffeineCacheUtils { static AbstractStringFirstCache cache; @Autowired
public void setCache(AbstractStringFirstCache cache) {
CaffeineCacheUtils.cache = cache;
} /**
* 查找缓存,如果缓存不存在则生成缓存元素
*
* @return value or null
*/
public static String get(@NonNull String key) {
return cache.get(key);
} /**
* 设置缓存,默认 15min
*/
public static void set(@NonNull String key, String value) {
cache.set(key, value);
} /**
* 设置缓存,提供时间和时间单位
*/
public static void set(@NonNull String key, String value, @NonNull Long expertTime, @NonNull TimeUnit timeUnit) {
cache.set(key, value, expertTime, timeUnit);
} /**
* 删除缓存
*/
public static void delete(@NonNull String key) {
cache.delete(key);
}
}

Caffeine 缓存库的更多相关文章

  1. 高性能 Java 缓存库 — Caffeine

    http://www.baeldung.com/java-caching-caffeine 作者:baeldung 译者:oopsguy.com 1.介绍 在本文中,我们来看看 Caffeine - ...

  2. [译]高性能缓存库Caffeine介绍及实践

    概览 本文我们将介绍Caffeine-一个Java高性能缓存库.缓存和Map之间的一个根本区别是缓存会将储存的元素逐出.逐出策略决定了在什么时间应该删除哪些对象,逐出策略直接影响缓存的命中率,这是缓存 ...

  3. Caffeine缓存的简单介绍

    1.简介 在本文中,我们将了解Caffeine,一个用于Java的高性能缓存库. 缓存和Map之间的一个根本区别是缓存会清理存储的项目. 一个清理策略会决定在某个给定时间哪些对象应该被删除,这个策略直 ...

  4. Caffeine缓存

    在本文中,我们来看看 Caffeine — 一个高性能的 Java 缓存库. 缓存和 Map 之间的一个根本区别在于缓存可以回收存储的 item. 回收策略为在指定时间删除哪些对象.此策略直接影响缓存 ...

  5. picasso-强大的Android图片下载缓存库

    编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! pica ...

  6. 基于memcached的单机轻量级通用缓存库minicached的实现

    一.前言 之前拜读过淘宝子柳的<淘宝技术这十年>之大作,深知缓存技术在系统优化中起着一个举足轻重的作用.无论是文件系统静态文件,数据库的访问,乃至网络数据的请求,只要是与内存访问速度相差较 ...

  7. picasso_强大的Android图片下载缓存库

    tag: android pic skill date: 2016/07/09 title: picasso-强大的Android图片下载缓存库 [本文转载自:泡在网上的日子 参考:http://bl ...

  8. 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选

    毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.i ...

  9. PHP缓存库phpFastCache

    phpFastCache是一个开源的PHP缓存库,只提供一个简单的PHP文件,可方便集成到已有项目,支持多种缓存方法,包括:apc, memcache, memcached, wincache, fi ...

随机推荐

  1. 如何用Python判断一个文件是否被占用?

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 今天有同学问,用os模块的access()能否判断一个文件是否被占用?直觉上,这是行不通的,因为ac ...

  2. python干货:pop()函数的用法 [弹出删除功能]

    什么是弹出功能? 使用pop()删除元素是将元素从列表中删弹出,术语弹出(pop)源自这样的类比:列表像一个栈,而删除列表末尾的元素就相当于弹出栈顶元素 方法pop()删除并返回列表中的最后一个元素. ...

  3. 庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署

    庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署 一.简介      我们在上一篇文章<庐山真面目之八微服务架构 NetCore 基于 Dockerfile ...

  4. 顶会两篇论文连发,华为云医疗AI低调中崭露头角

    摘要:2020年国际医学图像计算和计算机辅助干预会议(MICCAI 2020),论文接收结果已经公布.华为云医疗AI团队和华中科技大学合作的2篇研究成果入选. 同时两篇研究成果被行业顶会收录,华为云医 ...

  5. NET 5 爬虫框架/抓取数据

    爬虫大家或多或少的都应该接触过的,爬虫有风险,抓数需谨慎.  爬虫有的是抓请求,有的是抓网页再解析 本着研究学习的目的,记录一下在 .NET Core 下抓取数据的实际案例.爬虫代码一般具有时效性,当 ...

  6. webform中配置服务器控件的样式

    前台 Style <asp:Label ID="Label1" runat="server" Text="Label" Style=& ...

  7. Python代码打包成exe可执行程序

    首先,打包成exe可执行程序是针对windows平台来说的. 目前比较主流的打包工具就是pyinstaller. 参考:Using PyInstaller 首先安装pyinstaller: pip i ...

  8. 一个简单的struts2项目

    1.新建一个 Dynamic Web Project 项目 2.配置 struts.xml文件 <?xml version="1.0" encoding="UTF- ...

  9. 单细胞分析实录(1): 认识Cell Hashing

    这是一个新系列 差不多是一年以前,我定导后没多久,接手了读研后的第一个课题.合作方是医院,和我对接的是一名博一的医学生,最开始两边的老师很排斥常规的单细胞文章思路,即各大类细胞分群.注释.描述,所以起 ...

  10. System类常用方法

    System类常用方法 public static long currentTimeMills() 获取当前系统时间,以毫秒值为单位的当前时间. public static void arraycop ...