[笔记] Java Cache
依赖
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>jcache</artifactId>
</dependency>
里面包含了
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
如果只指定 cache-api 这个依赖,编译不会报错,但运行报错,因为这个只定义接口没有实现
也可以使用其他实现
定义要缓存的类,必须是可序列化的
package com.example.demo.entity;
import com.example.demo.utils.Logger;
import java.io.Serializable;
public class MyObject implements Serializable {
private final String name;
private final String id;
public MyObject(String name, String id) {
this.name = name;
this.id = id;
}
public void display() {
Logger.message("This is " + name + " id is " + id);
}
}
定义 Factory,通过 @Bean 注解创建一个 Cache,这个 Cache 的 key 是 String,对应 value 是 MyObject
setExpiryPolicyFactory 决定了缓存失效时间
setCacheLoaderFactory 决定了如果 key 在缓存里不存在或失效的话,要怎么去获取
package com.example.demo.factory;
import com.example.demo.entity.MyObject;
import com.example.demo.utils.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.cache.Cache;
import javax.cache.Caching;
import javax.cache.configuration.Configuration;
import javax.cache.configuration.FactoryBuilder;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;
import java.util.concurrent.TimeUnit;
import static org.springframework.web.context.WebApplicationContext.SCOPE_APPLICATION;
@Component
public class MyCacheFactory {
CachingProvider cachingProvider = Caching.getCachingProvider();
@Bean
@Scope(SCOPE_APPLICATION)
public Cache<String, MyObject> produce() {
Logger.message("MyCacheFactory produce conn");
Configuration<String, MyObject> config =
new MutableConfiguration<String, MyObject>()
.setTypes(String.class, MyObject.class)
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.HOURS, 1)))
.setReadThrough(true)
.setCacheLoaderFactory(FactoryBuilder.factoryOf(MyObjectLoader.class));
return cachingProvider.getCacheManager().createCache("MyObject", config);
}
}
定义 MyObjectLoader 决定如果缓存不存在或过期,如何获取
package com.example.demo.factory;
import com.example.demo.entity.MyObject;
import com.example.demo.utils.Logger;
import javax.cache.integration.CacheLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MyObjectLoader implements CacheLoader<String, MyObject> {
@Override
public MyObject load(String key) {
Logger.message("load " + key);
return this.get(key);
}
@Override
public Map<String, MyObject> loadAll(Iterable<? extends String> keys) {
Logger.message("loadAll " + keys);
Map<String, MyObject> mapper = new HashMap<>();
for (String key : keys) {
mapper.put(key, get(key));
}
return mapper;
}
private MyObject get(String key) {
return new MyObject(key, UUID.randomUUID().toString());
}
}
应用,@Autowired 自动找到了 @Bean 注解的返回类型为 Cache<String, MyObject> 的函数所创建的实例
@Autowired
private Cache<String, MyObject> cache;
@PostConstruct
public void init() {
this.verifyCache(); // 第一次,缓存里找不到,会调用 load 和 loadAll
Logger.message("\nbetween 2 verify cache");
this.verifyCache(); // 第二次,缓存里找得到,直接返回缓存
}
public void verifyCache() {
Logger.message("\n================\nverifyCache\n================\n");
cache.get("a").display();
cache.get("b").display();
Set<String> set = new HashSet<>();
set.add("c");
set.add("d");
Map<String, MyObject> mapper = cache.getAll(set);
for (Map.Entry<String, MyObject> entry : mapper.entrySet()) {
entry.getValue().display();
}
}
结果
================
verifyCache
================
load a
This is a id is 0cde6a55-04e9-498d-bcc6-7ff01c18ffe8
load b
This is b id is 89e86e9b-dbe0-4140-a0a8-449344fbba5d
loadAll [c, d]
This is c id is 42c101a8-40d6-4998-8905-758febf2841f
This is d id is 970e537e-9e5d-4c01-9226-e0261e1d0747
between 2 verify cache
================
verifyCache
================
This is a id is 0cde6a55-04e9-498d-bcc6-7ff01c18ffe8
This is b id is 89e86e9b-dbe0-4140-a0a8-449344fbba5d
This is c id is 42c101a8-40d6-4998-8905-758febf2841f
This is d id is 970e537e-9e5d-4c01-9226-e0261e1d0747
分类:
Java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界