文章目录
- 1. 简介
- 2. springboot集成jetcache
- 2.1 引入依赖
- 2.2 配置文件
- 2.3 高级API模式:通过CacheManager使用缓存,2.7 版本才可使用
- 2.4 (推荐)AOP模式:通过@Cached,@CacheUpdate,@CacheInvalidate注解
1. 简介
JetCache是一个基于Java的缓存系统封装,提供统一的API和注解来简化缓存的使用。 JetCache提供了比SpringCache更加强大的注解,可以原生的支持TTL、两级缓存、分布式自动刷新,还提供了Cache接口用于手工缓存操作。 当前有四个实现,RedisCache、TairCache(此部分未在github开源)、CaffeineCache(in memory)和一个简易的LinkedHashMapCache(in memory),要添加新的实现也是非常简单的。
JetCache需要JDK1.8、Spring Framework4.0.8以上版本。Spring Boot为可选,需要1.1.9以上版本。如果不使用注解(仅使用jetcache-core),Spring Framework也是可选的,此时使用方式与Guava/Caffeine cache类似。
全部特性:通过统一的API访问Cache系统通过注解实现声明式的方法缓存,支持TTL和两级缓存通过注解创建并配置Cache实例针对所有Cache实例和方法缓存的自动统计Key的生成策略和Value的序列化策略是可以配置的分布式缓存自动刷新,分布式锁 (2.2+)异步Cache API (2.2+,使用Redis的lettuce客户端时)Spring Boot支持
2. springboot集成jetcache
务必根据配置文件引入相关依赖,否则会有各种报错,本文以caffeine、redis.lettuce缓存为例
2.1 引入依赖
<dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-starter-redis-lettuce</artifactId><version>${jetcache.version}</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>
2.2 配置文件
jetcache:statIntervalMinutes: ${CACHE_STATS_INTERNAL:1} # 统计间隔,0表示不统计areaInCacheName: true # jetcache-anno把cacheName作为远程缓存key前缀,为了保持远程key兼容默认值为true,但是新项目的话false更合理些。enabled: ${JETCACHE_ENABLED:true}local:default:type: caffeine # 缓存类型,本地缓存类型支持linkedhashmap、caffeinekeyConvertor: jacksonremote:default:type: redis.lettuce # 缓存类型:远程缓存支持tair、rediskeyConvertor: jackson # key转换器的全局配置broadcastChannel: 'jetCache'keyPrefix: 'jetCache'valueEncoder: java # 序列化器的全局配置。仅remote类型的缓存需要指定,可选java和kryovalueDecoder: java # 序列化器的全局配置。仅remote类型的缓存需要指定,可选java和kryodefaultExpireInMillis: 60000poolConfig:minIdle: 5maxIdle: 20maxTotal: 50uri: 'redis://${JETCACHE_PASSWD:}@${JETCACHE_HOST:}:${JETCACHE_PORT:}/?database=${JETCACHE_DATABASE:4}'
2.3 高级API模式:通过CacheManager使用缓存,2.7 版本才可使用
@Configuration
public class JetCacheConfig {/*** 缓存管理器.*/@Resourceprivate CacheManager cacheManager;/*** 消息模版ID缓存.*/private Cache<String, String> msgTemplateCache;/*** 初始化缓存.*/@PostConstructpublic void init() {// 1、一级缓存:仅使用本地缓存,切永不失效
// msgTemplateCache = cacheManager.getOrCreateCache(QuickConfig.newBuilder("cache-")
// .cacheType(CacheType.LOCAL)
// .build());// 2、二级缓存: 使用本地缓存+redisDuration cacheDuration = Duration.ofSeconds(2 * 60);QuickConfig qc = QuickConfig.newBuilder("cache-").cacheType(CacheType.BOTH).syncLocal(true).localLimit(1000).localExpire(cacheDuration).expire(cacheDuration).build();msgTemplateCache = cacheManager.getOrCreateCache(qc);}@Beanpublic Cache<String, String> getMsgTemplateCache() {return msgTemplateCache;}
}@Slf4j
@Component
public class ProjectInitDataTask implements ApplicationRunner {/*** 消息模版缓存.*/@Autowiredprivate Cache<String, String> msgTemplateCache;@Overridepublic void run(ApplicationArguments args) {log.info("模拟创建缓存jetcache...");msgTemplateCache.put("msgTemplateCache1", "msgTemplateCache1");msgTemplateCache.put("msgTemplateCache2", "msgTemplateCache2");msgTemplateCache.put("msgTemplateCache3", "msgTemplateCache3");log.info("模拟创建缓存jetcache完成...");}
}
2.4 (推荐)AOP模式:通过@Cached,@CacheUpdate,@CacheInvalidate注解
@GetMapping("getRemote")@Cached(name="userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.REMOTE)public User getRemote(Long id){User user = new User();user.setId(id);user.setName("用户remote"+id);user.setAge(23);user.setSex(1);System.out.println("第一次获取数据,未走缓存:"+id);return user;}@GetMapping("getLocal")@Cached(name="userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.LOCAL)public User getLocal(Long id){// 直接新建用户,模拟从数据库获取数据User user = new User();user.setId(id);user.setName("用户local"+id);user.setAge(23);user.setSex(1);System.out.println("第一次获取数据,未走缓存:"+id);return user;}@GetMapping("getBoth")@Cached(name="userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.BOTH)public User getBoth(Long id){// 直接新建用户,模拟从数据库获取数据User user = new User();user.setId(id);user.setName("用户both"+id);user.setAge(23);user.setSex(1);System.out.println("第一次获取数据,未走缓存:"+id);return user;}@PostMapping("updateUser")@CacheUpdate(name = "userCache:", key = "#user.id", value = "#user")public Boolean updateUser(@RequestBody User user){// TODO 更新数据库return true;}@PostMapping("deleteUser")@CacheInvalidate(name = "userCache:", key = "#id")public Boolean deleteUser(Long id){// TODO 从数据库删除return true;}