项目JetCache的常见配置与使用

Hello, 大家好,今天本汪给大家带来的是JetCache在项目中的常见配置与用法讲解,接下来,随本汪一起来看看吧
请添加图片描述

一、介绍

官网地址:https://github.com/alibaba/jetcache

JetCache 是一种 Java 缓存抽象,它为不同的缓存解决方案提供了统一的用法。 它提供了比 Spring Cache 中的注释更强大的注释。JetCache 中的注解支持原生 TTL, 两级缓存,并在分散的环境中自动刷新,也可以通过代码操作实例。支持多种缓存类型:本地缓存、分布式缓存、多级缓存、缓存统计、自动刷新、异步调用、数据报表等等,能够满足不同业务场景的缓存需求。 目前,有四种实现:、(在 github 上不是开源的)、(在内存中)和简单(在内存中)。JetCache具有上手简单、性能高效、拓展性强的特点。支持缓存预热 、缓存key前缀等功能。结合spring-cache使用,可以实现十分优雅的缓存类型切换 JetCache的全部功能:CacheRedisCacheTairCacheCaffeineCacheLinkedHashMapCache

通过统一的缓存 API 操作缓存。
使用带有 TTL(Time To Live) 的注释和两级缓存支持的声明性方法缓存
使用缓存管理器创建和配置实例Cache
自动收集实例级和方法级缓存的访问统计信息Cache
密钥生成和值序列化策略可定制
支持缓存密钥转换器: //支持的值转换器:fastjson 、fastjson2、jackson、java、kryo、kryo5
分布式缓存自动刷新和分布式锁。(2.2+)
使用缓存 API 进行异步访问(2.2+,使用 redis 生菜客户端)
更新后使本地缓存失效(在所有 JVM 进程中) (2.7+)
Spring Boot 支持
要求:

JDK1.8
Spring Framework4.0.8+(可选,支持注解),jetcache 2.7需要5.2.4+
Spring Boot1.1.9+(可选),jetcache 2.7需要2.2.5+

多级缓存方案
本地缓存:(local)

​ ●LinkedHashMap (在内存中)

​ ●Caffeine (在内存中)

远程缓存:(remote)

​ ●Redis

​ ●Tair (在 github 上不是开源的)

二、配置说明

首先要引入maven依赖:

		<dependency><groupId>com.alicp.jetcache</groupId><artifactId>jetcache-starter-redis</artifactId><version>2.7.4</version></dependency>// jetcache 2.7.x 需要和 jedis 一同使用<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.0.0</version></dependency>

在启动类上加入两个注解@EnableCreateCacheAnnotation @EnableMethodCache(basePackages = “io.github.pnoker.center”) 这是jetcache启用注解缓存的开关

远程缓存:(remote) 默认的缓存方式
在yml配置文件中写入:

jetcache:remote:default:      #默认的配置type: redishost: localhostport: 6379poolConfig:    #配置必须要写,如果不写将报一个初始化错误maxTotal: 50   #最大连接数

在需要添加缓存的类中加入:

  @CreateCache(name = "jetcache" ,expire = 3600 //定义超时时间,timeUnit = TimeUnit.MINUTES //定超时时间单位)private Cache<String,String> cache;

将获取的值存入到缓存中:

   cache.put(key,value); //存入缓存 

从缓存中取值:

  String value= cache.get(key); //从缓存中取出数据

重要:

当springboot版本>=2.6版本时则会报一个循环依赖的错误,则需要在配置文件中写入即可:spring:main:allow-circular-references: true //默认为false 	

本地缓存(local):linkedhashmap
在yml文件中:

jetcache:local:default:type: linkedhashmapkeyConvertor: fastjson #类型转换

在需要添加缓存的类中加入:

在需要添加缓存的类中加入:

    @CreateCache(name = "jetScape",expire = 3600 //定义超时时间,timeUnit = TimeUnit.MINUTES //定超时时间单位,cacheType = CacheType.LOCAL //确定使用什么缓存,使用本地缓存 默认是使用远程,本地都要缓存)private Cache<String,String> cache;

将获取的值存入到缓存中:

   cache.put(key,value); //存入缓存 

从缓存中取值:

  String value= cache.get(key); //从缓存中取出数据

三、项目中实际使用

jetcache方法缓存
启用方法注解

@SpringBootApplication(scanBasePackages = {"com.alicp.jetcache.autoconfigure"})
@EnableCreateCacheAnnotation //开启注解缓存
@EnableMethodCache(basePackages = "io.github.pnoker.center") //开启方法注解缓存
@EnableDiscoveryClient
@EnableTransactionManagement
public class ManagerApplication {public static void main(String[] args) {SpringApplication.run(ManagerApplication.class, args);}
}

1、Spring 项目中常用的,使用方法注解操作缓存(这是使用实例,也是文章核心)

	// 使用注释声明方法缓存。// 表示元素将在设置后 3600 秒内过期。 JetCache 会自动生成包含所有参数的缓存密钥。@Cachedexpire = 3600@Cached(expire = 3600, cacheType = CacheType.REMOTE)User getUserById(long userId);//使用 attribute 使用 [SpEL 脚本](https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/expressions.html)//指定缓存键。key@Cached(name = "iot:device:info:deviceName:",key = "#deviceName", expire = 3600,timeUnit = TimeUnit.MINUTES
,cacheType = CacheType.REMOTE) // 缓存名 name 来获取hashMap, deviceName 为key, 查询结果DeviceInfo 作为value 存入缓存, 默认是远程缓存@CacheRefresh(refresh = 10) //经过一段时间后刷新一次缓存DeviceInfo selectDeviceInfoByDeviceName(String deviceName);// 多个参数作为key时,可以使用SpEL 脚本对参数进行拼接使用@Cached(name = "iot:device:info:device:",key = "#driverId.concat(':').concat(#deviceName)") // driverId:deviceName 作为 keyDeviceInfo selectDeviceInfoByDeviceNameAndDriveId(String deviceName, String driverId);@Cached(expire = 3600, cacheType = CacheType.REMOTE)@CacheRefresh(refresh = 1800, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS)@CachePenetrationProtect // CachePenetrationProtect 注解表示缓存将在多线程环境中同步加载。DeviceInfo selectDeviceInfoByDeviceName(String deviceName);

2、显示使用缓存实例,定义一个两级缓存(本地内存缓存和远程缓存系统),其中本地元素限制为 50(基于 LRU 的逐出)

@Autowired
private CacheManager cacheManager;
private Cache<String, UserDO> userCache;@PostConstruct
public void init() {QuickConfig qc = QuickConfig.newBuilder("userCache").expire(Duration.ofSeconds(100)).cacheType(CacheType.BOTH) // 二级缓存.localLimit(50) // 本地元素限制为 50(基于 LRU 的逐出).syncLocal(true) // 更新后使所有jvm进程中的本地缓存无效.build();userCache = cacheManager.getOrCreateCache(qc);
}

高级 API

1、异步 API:

CacheGetResult r = cache.GET(userId);
CompletionStage<ResultData> future = r.future();
future.thenRun(() -> {if(r.isSuccess()){System.out.println(r.getValue());}
});

2、分布式锁:

cache.tryLockAndRun("key", 60, TimeUnit.SECONDS, () -> heavyDatabaseOperation());

3、数据读取并自动刷新

@Autowired
private CacheManager cacheManager;
private Cache<String, Long> orderSumCache;@PostConstruct
public void init() {QuickConfig qc = QuickConfig.newBuilder("userCache").expire(Duration.ofSeconds(3600)) // 表示元素将在设置后 3600 秒内过期。.loader(this::loadOrderSumFromDatabase) // .refreshPolicy(RefreshPolicy.newPolicy(60, TimeUnit.SECONDS).stopRefreshAfterLastAccess(100, TimeUnit.SECONDS)).penetrationProtect(true) // 注解表示缓存将在多线程环境中同步加载。.build();orderSumCache = cacheManager.getOrCreateCache(qc);
}

缓存对象必须保证可序列化

public class DeviceInfo implements Serializable {

RedisCacheConfig

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;import javax.annotation.Resource;
import java.time.Duration;/*** Redis Cache** @author pnoker* @since 2022.1.0*/
@Configuration
@ConfigurationProperties(prefix = "spring.cache.redis")
public class RedisCacheConfig extends CachingConfigurerSupport {@Resourceprivate RedisConnectionFactory factory;@Setterprivate Duration timeToLive;/*** 自定义缓存 Key 生成策略** @return KeyGenerator*/@Beanpublic KeyGenerator firstKeyGenerator() {return (target, method, params) -> params[0].toString();}/*** 自定义缓存 Key 生成策略** @return KeyGenerator*/@Beanpublic KeyGenerator commonKeyGenerator() {final String dot = ".";final String hashTag = "#";return (target, method, params) -> {StringBuilder sb = new StringBuilder();sb.append(target.getClass().getName());sb.append(dot);sb.append(method.getName());sb.append(hashTag);for (Object obj : params) {sb.append(obj.toString());}return sb.toString();};}/*** 自定义 RedisCacheManager 类,主要是设置序列化,解决乱码问题** @return CacheManager*/@Bean@Overridepublic CacheManager cacheManager() {RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(factory);// Json 序列化配置Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);serializer.setObjectMapper(new ObjectMapper().setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY).activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL));// 配置 Key & Value 序列化RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer)).disableCachingNullValues().entryTtl(timeToLive);return builder.cacheDefaults(config).build();}}

yml配置

jetcache:statIntervalMinutes: 15 #查看缓存统计报告 15minremote:default:      #默认的配置type: redishost: localhostport: 6379keyConvertor: fastjsonvalueEncode: java #序列化存valueDecode: java #取得时候转换成javapoolConfig:    #配置必须要写maxTotal: 50   #最大连接数

yml 整体配置

jetcache:statIntervalMinutes: 15 #查看缓存统计报告 15minareaInCacheName: falsehiddenPackages: com.alibabalocal:default:type: linkedhashmaplimit: 100keyConvertor: fastjsonexpireAfterWriteInMillis: 100000otherArea:type: linkedhashmaplimit: 100keyConvertor: noneexpireAfterWriterInMillis: 100000remote:default:type: rediskeyConvertor: fastjson #支持的值转换器:fastjson 、fastjson2、jackson、java、kryo、kryo5valueEncoder: javavalueDecoder: javapoolConfig:minIdle: 5maxIdle: 20maxTotal: 50host: 120.27.122.182port: 6379password: Tabr_68686626database: 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/47250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python中的模块和包的定义以及如何在Python中导入和使用它们

在Python中&#xff0c;模块&#xff08;Module&#xff09;和包&#xff08;Package&#xff09;是组织代码以便重用和共享的基本单元。它们使得Python代码更加模块化&#xff0c;易于管理和维护。 模块&#xff08;Module&#xff09; 模块是一个包含Python代码的文件&…

力扣 541反转链表2

思路&#xff1a; 2k个字符中前k个翻转 如果字符正好2k个&#xff0c;那就去翻转前k个&#xff0c;如果字符不足2k个&#xff0c;那取前K个翻转 因此先写翻转函数&#xff0c;再按着要求翻转 注意边界条件&#xff0c;反转k个&#xff0c;下标是ik-1,例如0-3是前4个&#x…

秘密,一般人我不告诉他.偷偷告诉你信创产品采购的正确打开方式:python爬虫实现

创作不易 只因热爱!! 热衷分享&#xff0c;一起成长! “你的鼓励就是我努力付出的动力” 采购XX有没有找你诉说 , 某某ZFCG网上的信创产品, 品种太多太杂,无法细分查找,某某详情页面要一个个看, 真费时费力,于是乎… !!!以下内容仅供学习使用,便于快速筛选找到需求产品!!!请勿…

C#WPF DialogHost.Show 弹出对话框并返回数据

在WPF中,使用DialogHost.Show方法显示一个对话框并获取返回数据,你需要定义一个对话框,并在对话框关闭时返回数据。以下是一个简单的例子: 首先,在主窗口中添加DialogHost控件: <MaterialDesign:DialogHost x:Name="dialogHost" /> 然后,创建一个对话…

【算法/序列】等差数列子序列算术序列最长对称子串

概念&#xff1a; 等差数列&#xff1a;任意两项的差总等于同一个常数 子数组 &#xff1a;是数组中的一个连续序列。 子序列&#xff1a;是通过从原序列删除零个或多个元素并在不改变顺序的情况下排列其余元素而获得的序列 算术序列&#xff1a;是一个数字列表&#xff0c;其中…

【时时三省】(C语言基础)变量

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 变量 可以改变的量 比如 int age&#xff1d;20 &#xff08;类型 变量的名字&#xff1d;0&#xff09; 如果后面要改可以直接代入 age&#xff1d;age1 age可以是任何字母 变量的分类…

【C++】类和对象的基本概念与使用

本文通过面向对象的概念以及通俗易懂的例子介绍面向对象引出类和对象。最后通过与之有相似之处的C语言中的struct一步步引出C中的类的定义方式&#xff0c;并提出了一些注意事项&#xff0c;最后描述了类的大小的计算方法。 一、什么是面向对象&#xff1f; 1.面向对象的概念 …

【C++编程】标准模板库 STL 的基本概念

STL 从广义上分为&#xff1a;容器、算法、迭代器 容器、算法之间通过迭代器进行无缝连接 STL 六大组件&#xff1a; 容器&#xff1a;各种数据结构&#xff0c;如 vector、list、deque、set、map 等&#xff0c;用来存放数据 序列式容器&#xff1a;物理存放上有序关联式容器&…

算法训练营day72

题目&#xff1a;117. 软件构建 (kamacoder.com) #include<iostream> #include<unordered_map> #include<vector> #include<queue>using namespace std;int main() {int n, m;cin >> n >> m;vector<int> indegree(n, 0);unordered_…

约束条件和数据库的用户管理

数据库的增删改查 查 约束条件和用户管理 删 约束条件&#xff1a; 主键 主键约束 primary key 用于标识表中的主键列的值&#xff0c;而且这个值是全表当中唯一的&#xff0c;而且值不能为null。 一个表只能有一个主键。 外键&#xff1a;用来建立表与表之间的关系。…

微信小游戏 彩色试管 倒水游戏 逻辑 (四)

最近开始研究微信小游戏&#xff0c;有兴趣的 可以关注一下 公众号&#xff0c; 记录一些心路历程和源代码。 定义了一个名为 WaterFlow class&#xff0c;该类继承自 cc.Graphics&#xff0c;用于在 Cocos Creator 中创建和显示水流的动画效果。下面是对代码的详细解释&#x…

Font Awesome 图表图标

Font Awesome 图表图标 Font Awesome 是一个广泛使用的图标库&#xff0c;它提供了大量的图标&#xff0c;可以轻松地用于网页设计和开发中。在本文中&#xff0c;我们将重点介绍 Font Awesome 中的图表图标&#xff0c;探讨它们的特点、使用方法&#xff0c;并展示一些实际的…

FPGA FIR fdatool filter designer MATLAB

位数问题 fdatool 先确定输入信号的位宽&#xff0c;比如17位在fdatool中&#xff0c;选set quantization parameters 选input/output 设置input word length 为17bit(not confirmed) fir compiler implementation 注意&#xff1a; 当设置输入位宽为16位时&#xff0c;ip核…

Linux系统部署MySQL数据库

1.Linux插入光盘&#xff0c;使用df-h获取光盘信息&#xff0c;默认/dev/sr0文件为光盘文件 使用命令 mount -o ro /dev/sr0 /media进行手动挂载 mount -o ro /dev/sr0 /media 2.进入cd /etc/yum.repos.d目录 编辑配置yum库&#xff0c;编辑vim yum.repos [BaseOS] nameba…

Flutter 状态管理新境界:多Provider并行驱动UI

前言 在上一篇文章中&#xff0c;我们讨论了如何使用 Provider 在 Flutter 中进行状态管理。 本篇文章我们来讨论如何使用多个 Provider。 在 Flutter 中&#xff0c;使用 Provider 管理多个不同的状态时&#xff0c;你可以为每个状态创建一个单独的 ChangeNotifierProvider…

node+MySQL+Express实现账户登录,注册,重置之登录篇

nodeMySQLExpress实现账户登录 实现技术开发工具项目结构效果图app.js代码db.jsrouter下的account.jsdb下的account.jslogin.html数据库结构 实现技术 node.js,MySQL5.7(8.0以上版本会报错)&#xff0c;layui(前端框架)&#xff0c;Express notify(消息通知layui插件) 开发工…

如何使用在线工具将手机相册中的图片转换为JPG格式

我们经常在手机相册中保存大量的图片&#xff0c;无论是家庭聚会的照片还是旅行的瞬间&#xff0c;每一幅图像都承载着珍贵的记忆。然而&#xff0c;有时候我们会遇到图片格式不兼容的问题&#xff0c;尤其是在需要将图片分享到特定平台或编辑时。 例如&#xff0c;某些社交平台…

Java语音转文字及文字转语音教学 (离线版)

1. 语音转文字 1.1 maven导入以下包 <!-- 获取音频信息 --> <dependency><groupId>org</groupId><artifactId>jaudiotagger</artifactId><version>2.0.3</version> </dependency><!-- 语音识别 --> <dependen…

ubuntu使用vcan做本地测试

当本地没有can设备时&#xff0c;可以使用虚拟can在ubuntu本地进行模拟测试程序的正确性。 在Ubuntu上启用虚拟控制器区域网络(vCAN)&#xff0c;需要安装并配置CAN工具箱。以下是如何在Ubuntu上安装并设置vCAN的步骤 1. 安装can-utils包&#xff0c;它包含了vcan模块 sudo …

C++知识要点总结笔记

文章目录 前言一、c基础1.指针和引用指针和引用的区别函数指针 2.数据类型整型 short int long 和 long long无符号类型强制类型转换 3.关键字conststaticconst和static的区别define 和 typedef 的区别define 和 inline 的区别const和define的区别constexprvolatileextern前置与…