Caffeine是基于jdk 1.8 Version的高性能缓存库。Caffeine提供的内存缓存使用参考Google guava的API。Caffeine是基于Google Guava Cache设计经验上改进的成果。
Caffeine是使用jdk 1.8对Guava cache的重写版本,基于LRU算法实现,支持多种缓存过期策略。
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.0</version>
</dependency>
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;
}
}
使用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;
}
}
使用异步缓存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;
}
}
}
@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时,没有调用