Caffeine Cache使用

221 阅读2分钟

1. 依赖

<dependency>
	<groupId>com.github.ben-manes.caffeine</groupId>
		<artifactId>caffeine</artifactId>
	<version>2.9.3</version>
</dependency>

2.使用

 Cache<String,String> cache = Caffeine.newBuilder()
                .expireAfterWrite(5, TimeUnit.SECONDS)
                .maximumSize(10_000)
                .build();
                
 //存
  cache.put("key", "value");
  
 //取
 String value=cache.getIfPresent("key");
 
 
 //如果有,直接返回缓存,没有的话,获取数据之后存入缓存再返回
 String value= cache.get("key",key->{
            return "value";
      });
                

3.缓存策略

Caffeine 提供了四种缓存策略: 手动加载,自动加载,手动异步加载,自动异步加载

3.1手动加载
Cache<String, String> cache = Caffeine.newBuilder()
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .maximumSize(10_000)
    .build();
    
// 查找一个缓存元素, 没有查找到的时候返回null
String value = cache.getIfPresent(key);

// 查找缓存,如果缓存不存在则生成缓存元素,  如果无法生成则返回null
 String value= cache.get("key",key->{
            return "value";
      });
      
// 添加或者更新一个缓存元素
cache.put("key", "value");
// 移除一个缓存元素
cache.invalidate("key");
推荐使用 cache.get(key, k -> value)

操作来在缓存中不存在该key对应的缓存元素的时候进行计算生成并直接写入至缓存内,而当该key对应的缓存元素存在的时候将会直接返回存在的缓存值。一次 cache.put(key, value)

操作将会直接写入或者更新缓存里的缓存元素,在缓存中已经存在的该key对应缓存值都会直接被覆盖。值得注意的是,当缓存的元素无法生成或者在生成的过程中抛出异常而导致生成元素失败,cache.get 也许会返回 null 。

当然,也可以使用Cache.asMap()所暴露出来的ConcurrentMap的方法对缓存进行操作。
3.2 自动加载
LoadingCache<Key, Graph> cache = Caffeine.newBuilder()
    .maximumSize(10_000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));

// 查找缓存,如果缓存不存在则生成缓存元素,  如果无法生成则返回null
Graph graph = cache.get(key);
// 批量查找缓存,如果缓存不存在则生成缓存元素
Map<Key, Graph> graphs = cache.getAll(keys);
3.3 手动异步加载
AsyncCache<Key, Graph> cache = Caffeine.newBuilder()
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .maximumSize(10_000)
    .buildAsync();

// 查找一个缓存元素, 没有查找到的时候返回null
CompletableFuture<Graph> graph = cache.getIfPresent(key);
// 查找缓存元素,如果不存在,则异步生成
graph = cache.get(key, k -> createExpensiveGraph(key));
// 添加或者更新一个缓存元素
cache.put(key, graph);
// 移除一个缓存元素
cache.synchronous().invalidate(key);
3.4自动动异步加载
AsyncLoadingCache<Key, Graph> cache = Caffeine.newBuilder()
    .maximumSize(10_000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    // 你可以选择: 去异步的封装一段同步操作来生成缓存元素
    .buildAsync(key -> createExpensiveGraph(key));
    // 你也可以选择: 构建一个异步缓存元素操作并返回一个future
    .buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));

// 查找缓存元素,如果其不存在,将会异步进行生成
CompletableFuture<Graph> graph = cache.get(key);
// 批量查找缓存元素,如果其不存在,将会异步进行生成
CompletableFuture<Map<Key, Graph>> graphs = cache.getAll(keys);

4.SpringBoot 集成

import java.util.concurrent.TimeUnit;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.fastjson.JSONObject;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

@Configuration
public class CaffeineConfig {
	
	@Bean
	public Cache<String,JSONObject> strategyCache()
	{
		
		return Caffeine.newBuilder().maximumSize(10000)
				.expireAfterWrite(60, TimeUnit.SECONDS)
				.build();
	}

}
@Autowired
private Cache<String,JSONObject> cache;
@Override
	public JSONObject queryExecuteRankList(String isContract) {
		
		return cache.get(isContract, key->{
			
			List<Map<String, Object>> executeRankList = billboardDao.queryExecuteRankList(isContract);

			JSONObject resultJson = new JSONObject();
			
			resultJson.put("executeRankList", executeRankList);
			
			return resultJson;
			
			
		});