Caffeine缓存框架使用

介绍

Caffeine是基于jdk 1.8 Version的高性能缓存库。Caffeine提供的内存缓存使用参考Google guava的API。Caffeine是基于Google Guava Cache设计经验上改进的成果。

Caffeine是使用jdk 1.8对Guava cache的重写版本,基于LRU算法实现,支持多种缓存过期策略。

在创建cache时,有许多参数可以定义

  • initialCapacity: 初始的缓存空间大小
  • maximumSize: 缓存的最大数量
  • maximumWeight: 缓存的最大权重
  • expireAfterAccess: 最后一次读或写操作后经过指定时间过期
  • expireAfterWrite: 最后一次写操作后经过指定时间过期
  • refreshAfterWrite: 创建缓存或者最近一次更新缓存后经过指定时间间隔,刷新缓存
  • weakKeys: 打开key的弱引用
  • weakValues:打开value的弱引用
  • softValues:打开value的软引用
  • recordStats:开发统计功能

使用示例

1、引入jar包

<dependency>
	<groupId>com.github.ben-manes.caffeinegroupId>
	<artifactId>caffeineartifactId>
	<version>2.8.0version>
dependency>

2、使用方式1

Cache.get(key, mappingFunction) get时,传入查询方法,首次调用会从方法中查询,后续调用从缓存中获取

public final class TestCache {
	private static final Logger log = LoggerFactory.getLogger(TestCache.class);
	private static Cache<Long, VipCardType> cache;

	private TestCache() {
	}

	public static void init() {
		log.info("---初始化缓存");
		cache = Caffeine.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build();
	}

	private static VipCardType load(Long id) {
		log.info("[TestCache] load from database:{}", id);
		IVipCardTypeService service = SpringContextHolder.getBean(IVipCardTypeService.class);
		VipCardType entity = service.getEntity(id);
		return entity;
	}

	public static VipCardType getEntity(Long id) {
		if (id == null || id == 0) {
			return null;
		}
		log.info("[TestCache] [start] :{}", id);
		VipCardType type = cache.get(id, (k) -> load(k));
		log.info("[TestCache] [end] :{}", id);
		return type;
	}

}

3、使用方式2

使用LoadingCache,build时,直接传入查询方法,调用时,直接get就可以

public final class TestCache2 {
	private static final Logger log = LoggerFactory.getLogger(TestCache2.class);
	private static LoadingCache<Long, VipCardType> cache;

	private TestCache2() {
	}

	public static void init() {
		log.info("---初始化缓存");
		cache = Caffeine.newBuilder().refreshAfterWrite(5, TimeUnit.MINUTES).build(id -> load(id));
	}

	private static VipCardType load(Long id) {
		log.info("[TestCache2] load from database:{}", id);
		IVipCardTypeService service = SpringContextHolder.getBean(IVipCardTypeService.class);
		VipCardType entity = service.getEntity(id);
		return entity;
	}

	public static VipCardType getEntity(Long id) {
		if (id == null || id == 0) {
			return null;
		}
		log.info("[TestCache2] [start] :{}", id);
		VipCardType type = cache.get(id);
		log.info("[TestCache2] [end] :{}", id);
		return type;
	}

}

4、使用方式3

使用异步缓存AsyncLoadingCache,get时返回CompletableFuture,在需要时再次get获取实际值

public final class TestCache3 {
	private static final Logger log = LoggerFactory.getLogger(TestCache3.class);
	private static AsyncLoadingCache<Long, VipCardType> cache;

	private TestCache3() {
	}

	public static void init() {
		log.info("---初始化缓存");
		cache = Caffeine.newBuilder().refreshAfterWrite(5, TimeUnit.MINUTES).buildAsync(id -> load(id));
	}

	private static VipCardType load(Long id) {
		log.info("[TestCache3] load from database:{}", id);
		IVipCardTypeService service = SpringContextHolder.getBean(IVipCardTypeService.class);
		VipCardType entity = service.getEntity(id);
		return entity;
	}

	public static VipCardType getEntity(Long id) {
		if (id == null || id == 0) {
			return null;
		}
		try {
			log.info("[TestCache3] [start] :{}", id);
			VipCardType type = cache.get(id).get();
			log.info("[TestCache3] [end] :{}", id);
			return type;
		} catch (Exception e) {
			log.error("", e);
			return null;
		}
	}

}

4、测试

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = VipServer.class)
public class CaffeineCacheTest {

	@Test
	public void test() throws ApplicationException {
		TestCache.init();
		TestCache2.init();
		TestCache3.init();
		TestCache.getEntity(2L);
		TestCache.getEntity(2L);
		TestCache2.getEntity(2L);
		TestCache2.getEntity(2L);
		TestCache3.getEntity(2L);
		TestCache3.getEntity(2L);
	}

}

输出结果:

TestCache     : [TestCache] [start] :2
TestCache     : [TestCache] load from database:2
TestCache     : [TestCache] [end] :2
TestCache     : [TestCache] [start] :2
TestCache     : [TestCache] [end] :2
TestCache2    : [TestCache2] [start] :2
TestCache2    : [TestCache2] load from database:2
TestCache2    : [TestCache2] [end] :2
TestCache2    : [TestCache2] [start] :2
TestCache2    : [TestCache2] [end] :2
TestCache3    : [TestCache3] [start] :2
TestCache3    : [TestCache3] load from database:2
TestCache3    : [TestCache3] [end] :2
TestCache3    : [TestCache3] [start] :2
TestCache3    : [TestCache3] [end] :2

从输入结果,可以看出,第一次get时,调用了load方法,第二次get时,没有调用

总结

  1. Caffeine是目前性能最好的进程缓存,比常用的Guava cache要高几倍
  2. Caffeine基于jdk1.8重写,可以使用lambda表达式简化代码,代码更加简洁
  3. Caffeine可以和spring cache集成,方便使用

你可能感兴趣的:(框架)