springBoot集成caffeine,自定义缓存配置 CacheManager

目录

springboot集成caffeine

Maven依赖

配置信息:properties文件

config配置

使用案例

Caffeine定制化配置多个cachemanager

springboot集成redis并且定制化配置cachemanager


springboot集成caffeine

Caffeine是一种基于服务器内存的缓存库。它将数据存储在应用程序的内存中,以实现快速的数据访问和高性能。

由于Caffeine缓存在服务器内存中存储数据,因此它适用于需要快速读取和频繁访问的数据,比如一些热门数据、配置信息、常用查询的结果等。但是它不适用于大规模数据或需要持久化存储的数据,因为服务器内存有限,无法存储大量数据,并且缓存数据在应用程序重启后会丢失

Maven依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- caffeine服务器本地缓存 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- caffeine --><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.8.1</version></dependency><!--   可以对自定义配置的信息进行提示 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency>
</dependencies>

配置信息:properties文件

/*** Caffeine Cache自定义配置属性类*/
@Data   //lombok插件的  看自己需求是否引入
@Component
@ConfigurationProperties(prefix = "com.common.caffeine")  
//这个ConfigurationProperties是为了方便配置yaml文件,
//如果有需要的话可以在yaml文件中进行配置,需要与spring-boot-configuration-processor
//这个依赖搭配使用,
//然后再在resources目录下创建一个META-INF文件夹,该文件夹下存放一个配置文件提升信息(下面会贴出来的),
//这样的话在yaml文件中进行书写的时候就会有提升信息了
public class CaffeineCacheProperties {/*** 缓存初始容量  映射的话会很灵活  羊肉串写法与驼峰命名都可以和下面的属性进行映射* com.ifi.performance.common.caffeine.init-cache-capacity*/private Integer initCacheCapacity = 256;/*** 缓存最大容量,超过之后会按照recently or very often(最近最少)策略进行缓存剔除* com.ifi.performance.common.caffeine.max-cache-capacity*/private Long maxCacheCapacity = 10000L;/*** 是否允许空值null作为缓存的value* com.ifi.performance.common.caffeine.allow-null-value*/private Boolean allowNullValue = Boolean.TRUE;}

配置yaml文件提升信息:additional-spring-configuration-metadata.json

{"properties": [{"name": "com.ifi.performance.common.caffeine.init-cache-capacity","type": "java.lang.Integer","description": "Caffeine缓存的初始容量","defaultValue": 256},{"name": "com.ifi.performance.common.caffeine.max-cache-capacity","type": "java.lang.Long","description": "Caffeine缓存的最大容量","defaultValue": "10000L"},{"name": "com.ifi.performance.common.caffeine.allow-null-value","type": "java.lang.Boolean","description": "Caffeine缓存是否允许null作为value的属性","defaultValue": "true"}]
}

这样在yaml文件中输入com.common.caffeine的时候就会有提示信息了。

config配置

/*** 服务端公用缓存常量类*/
public interface CacheConstants {/*** 系统服务端公用缓存名称 默认缓存*/String CACHE_NAME = "server_cache";
}       

编写config配置文件:CaffeineCacheConfig.java

@SpringBootConfiguration
@EnableCaching  //开启注解扫描
@Slf4j
public class CaffeineCacheConfig {//刚刚编写的properties配置文件@Autowiredprivate CaffeineCacheProperties properties;/*** 默认的全局缓存管理器* @return*/@Bean("defaultCacheManager")public CaffeineCacheManager defaultCacheManager() {CaffeineCacheManager defaultCacheManager = new CaffeineCacheManager(CacheConstants.CACHE_NAME); //指定这个缓存的命名,这里我是使用了一个常量类defaultCacheManager.setAllowNullValues(properties.getAllowNullValue());Caffeine<Object, Object> caffeineBuilder = Caffeine.newBuilder().initialCapacity(properties.getInitCacheCapacity()).maximumSize(properties.getMaxCacheCapacity()) //从配置文件中获取最大容量.expireAfterWrite(7, TimeUnit.DAYS); //过期时间defaultCacheManager.setCaffeine(caffeineBuilder);log.info("the caffeine cache manager is loaded successfully!");return defaultCacheManager;}
}

使用案例

这样配置好了之后就可以在controller、service中使用配置好的缓存了。

比如说我们要在service中进行使用,案例如下:

@Autowired
@Qualifier(value = "defaultCacheManager") //这里可以直接使用Autowired就行,Autowired默认是按照对象类型进行依赖注入,如果容器中有两个及以上的同一种类型的bean,那么就会报bean冲突的错误,后面的定制化配置会用到这个Autowired
private CaffeineCacheManager defaultCacheManager;Cache cache = defaultCacheManager.getCache(CacheConstants.CACHE_NAME); //配置类中对这个cachemanager设置的缓存名称
//下面就可以通过cache操作数据:存入缓存或者是从缓存中获取数据、删除数据了。
//存入缓存的数据是key-value形式的,key最好是一个唯一的标识,不然可能会出现缓存覆盖的情况,value可以是一个字符串也可以是自定义的对象,这里我是自定义了一个对象,比如UserCache对象,这个对象中有我需要缓存的数据,比如userid等自己需要的数据
UserCache usercache = new UserCache();
usercache.setuserId = "123456"; //实际业务场景中,比如用户登录成功,可以把用户id设置进来,方便其他业务进行获取  LOGIN_INFO 常量为自定义的一个标识符,方便在查询辨别缓存数据
cache.put(userId+CacheConstants.LOGIN_INFO,usercache);//特别注意:get缓存数据的时候,很大可能获取到的是null对象,因为比如有一些业务没有被触发从而导致没有填充你需要的数据到缓存,所以这里一定要加一个空指针判断!!!
UserCache usercache = cache.get( userId + CacheConstants.LOGIN_INFO, UserCache.class);
if(usercache == null){return null;
}//清除缓存中指定的数据  通过key来清除缓存中的数据,比如用户退出登录了可以把他的一些缓存信息给清除
cache.evict(userId + CacheConstants.LOGIN_INFO);

因为我们使用的缓存管理接口是spring-cache的,spring-cache中的操作api中并没有提供设置数据缓存的过期时间的,所以如果我们有这种业务需要(比如验证码信息需要5分钟才过期,用户登录信息30天才过期),那么就需要定制化配置cachemanager了,这样从源头上解决问题。

Caffeine定制化配置多个cachemanager

依赖与上面一致,只需要修改CaffeineCacheConfig类与使用方式就行。

@SpringBootConfiguration
@EnableCaching  //开启注解扫描
@Slf4j
public class CaffeineCacheConfig {@Autowiredprivate CaffeineCacheProperties properties;/*** 默认的全局缓存管理器* @return*/@Primary  //必须要加这个注解,用于标识一个Bean(组件)是首选的候选者。当有多个同类型的Bean(组件)时,使用了@Primary注解的Bean将会成为默认选择,如果没有其他限定符(如@Qualifier)指定具体要使用的Bean,则会优先选择带有@Primary注解的Bean。@Bean("defaultCacheManager")public CaffeineCacheManager defaultCacheManager() {CaffeineCacheManager defaultCacheManager = new CaffeineCacheManager(CacheConstants.ACHE_NAME);defaultCacheManager.setAllowNullValues(properties.getAllowNullValue());Caffeine<Object, Object> caffeineBuilder = Caffeine.newBuilder().initialCapacity(properties.getInitCacheCapacity()).maximumSize(properties.getMaxCacheCapacity()).expireAfterWrite(7, TimeUnit.DAYS);defaultCacheManager.setCaffeine(caffeineBuilder);log.info("the caffeine cache manager is loaded successfully!");return defaultCacheManager;}/***  用于管理验证码缓存,设置过期时间为300秒*/@Bean("verificationCodeCacheManager")public CaffeineCacheManager verificationCodeCacheManager() {CaffeineCacheManager verificationCodeCacheManager = new CaffeineCacheManager(CacheConstants.CODE_CACHE_NAME);verificationCodeCacheManager.setCaffeine(Caffeine.newBuilder().initialCapacity(properties.getInitCacheCapacity()).maximumSize(properties.getMaxCacheCapacity()).expireAfterWrite(300, TimeUnit.SECONDS));log.info("the verificationCodeCacheManager cache manager is loaded successfully!");return verificationCodeCacheManager;}}

使用方式,和上面的案例一致,不过这个时候就必须使用@Qualifier来指定相关的bean。其他使用方式都是一致的。

@Autowired
@Qualifier(value = "defaultCacheManager") 
private CaffeineCacheManager defaultCacheManager;@Autowired
@Qualifier(value = "verificationCodeCacheManager")
private CaffeineCacheManager verificationCodeCacheManager;

springboot集成redis并且定制化配置cachemanager

缓存使用到的Maven依赖:

<!-- 集成redis依赖  -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 提供Redis连接池 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

yaml文件:Redis部分的配置

spring:redis:database: 0host: localhostport: 6379password: abc123456  #这个看你的Redis版本,一些老的Redis用的是auth,一些比较新的用的是password配置timeout: 10slettuce:pool:# 连接池最大连接数max-active: 200# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms# 连接池中的最大空闲连接max-idle: 10# 连接池中的最小空闲连接min-idle: 3

config配置类:

@SpringBootConfiguration
@EnableCaching
@Slf4j
public class RedisCacheConfig {/*** 定制链接和操作Redis的客户端工具   配置一些序列化器,这样通过缓存管理工具看到的缓存数据就不是乱码了* @param redisConnectionFactory* @return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);//配置序列化器Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setDefaultSerializer(genericJackson2JsonRedisSerializer);objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}/*** 默认的全局缓存管理器   配置一些序列化器,这样通过缓存管理工具看到的缓存数据就不是乱码了* @return*/@Primary  //关于这个相关的解释,上面的caffeine配置中都有说明,这里就不额外说明了@Bean("defaultCacheManager")public RedisCacheManager defaultCacheManager(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));RedisCacheManager defaultCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();log.info("the redis defaultCacheManager is loaded successfully!");return defaultCacheManager;}/***  用于管理验证码缓存,设置过期时间为300秒*/@Bean("verificationCodeCacheManager")public RedisCacheManager verificationCodeCacheManager(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));RedisCacheManager verificationCodeCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();log.info("the verificationCodeCacheManager cache manager is loaded successfully!");return verificationCodeCacheManager;}}

使用方式,和上面的一致:

@Autowired
@Qualifier(value = "defaultCacheManager")
private CaffeineCacheManager defaultCacheManager;Cache cache = defaultCacheManager.getCache(CacheConstants.CACHE_NAME); //配置类中对这个cachemanager设置的缓存名称UserCache usercache = new UserCache();
usercache.setuserId = "123456"; 
//实际业务场景中,比如用户登录成功,可以把用户id设置进来,方便其他业务进行获取  LOGIN_INFO 常量为自定义的一个标识符,方便在查询辨别缓存数据
cache.put(userId+CacheConstants.LOGIN_INFO,usercache);//特别注意:get缓存数据的时候,很大可能获取到的是null对象
UserCache usercache = cache.get( userId + CacheConstants.LOGIN_INFO, UserCache.class);
if(usercache == null){return null;
}//清除缓存中指定的数据  通过key来清除缓存中的数据
cache.evict(userId + CacheConstants.LOGIN_INFO);

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

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

相关文章

零拷贝详解

1、在没有DMA技术之前的I/O过程是这样的&#xff1a; CPU发出对应的指令给磁盘控制器&#xff0c;然后返回磁盘控制器收到指令后&#xff0c;于是就开始准备数据&#xff0c;会把数据放入到磁盘控制器的内部缓冲区&#xff0c;然后产生中断CPU收到中断信号后&#xff0c;停下手…

springBoot的日志文件

日志是程序的重要组成部分&#xff0c;主要可以用来定位和排查问题。除此之外&#xff0c;还可以用来&#xff1a; 1. 记录用户的登录日志&#xff0c;方便分析用户是正常登录还是恶意破解&#xff1b; 2. 记录系统的操作日志&#xff0c;方便数据恢复和定位操作人&#xff1b;…

过滤器,监听器与拦截器的区别

过滤器&#xff0c;监听器与拦截器的区别 ​ 过滤器和监听器不是Spring MVC中的组件&#xff0c;而是Servlet的组件&#xff0c;由Servlet容器来管理。拦截器是Spring MVC中的组件&#xff0c;由Spring容器来管理 ​ Servlet过滤器与Spring MVC 拦截器在Web应用中所处的层次如…

javaWeb项目--二级评论完整思路

先来看前端需要什么吧&#xff1a; 通过博客id&#xff0c;首先需要显示所有一级评论&#xff0c;包括评论者的头像&#xff0c;昵称&#xff0c;评论时间&#xff0c;评论内容 然后要显示每个一级评论下面的二级评论&#xff0c;包括&#xff0c;评论者的头像&#xff0c;昵称…

【Spring】-Spring中Bean对象的存取

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Framework】 主要内容&#xff1a;往spring中存储Bean对象的三大方式&#xff1a;XML方式(Bean标签)&#xff1b;五大类注解&#xff1b;方法注解。从spring中取对象的两种方式…

查看单元测试用例覆盖率新姿势:IDEA 集成 JaCoCo

1、什么是 IDEA IDEA 全称 IntelliJ IDEA&#xff0c;是 Java 编程语言开发的集成环境。IntelliJ 在业界被公认为最好的 Java 开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE 支持、各类版本工具(git、SVN 等)、JUnit、CVS 整合、代码分析、 创新的 GUI…

DNS:使用 bind9 配置主从权威DNS服务器

写在前面 分享一些 使用 bind9 配置主从权威名称服务器的笔记理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是人的逃避方式…

ML类CFAR检测器在不同环境中检测性能的分析

摘要&#xff1a;该文是楼主翻阅书籍以及一些论文总结出来的关于ML(均值)类CFAR检测器在不同环境中的性能对比&#xff0c;以及优缺点的总结&#xff0c;可以帮助大家面对不同情形如何选择CFAR问题。由于楼主见识短浅&#xff0c;文中难免出现不足之处&#xff0c;望各位指出。…

怎么做Tik Tok海外娱乐公会呢?新加坡市场怎么样?

一、为什么选择TikTok直播 1. 海外市场潜力巨大 • 自2016年始&#xff0c;多家直播平台陆续拓展至东南亚、中东、俄罗斯、日韩、欧美、拉美等地区。 • 海外市场作为直播发展新蓝海&#xff0c;2021年直播行业整申请cmxyci体规模达百亿美元&#xff0c;并维持高速增长。 &a…

geeemap学习总结(1)——Anaconda-VSCode-geemap环境安装与配置

配置conda geemap 环境 通过Anaconda配置geemap环境较为方便&#xff0c;首先需在系统中完成 Anaconda安装。创建名为geemap的环境conda create -n geemap切换到新建的环境conda activate geemap安装geemap依赖包conda install -c conda-forge geemap 安装mambaconda install …

网络编程 tcp udp http编程流程 网络基础知识

讲解 网络基础知识网络编程tcp编程流程图示理解bind和accept函数理解监视套接字和链接套接字理解linux和window下的编程实现tcp特点 udp编程流程图示理解udp特点 http编程流程图示理解编程实现-网站服务器 网络基础知识 OSI分层&#xff1a;应用层 表示层 会话层 传输层 网络层…

上传图片视频

分布式文件系统MinIo MinIO提供多个语言版本SDK的支持&#xff0c;下边找到java版本的文档&#xff1a; 地址&#xff1a;https://docs.min.io/docs/java-client-quickstart-guide.html MinIO测试&#xff08;上传、删除、下载&#xff09; public class MinioTest {MinioC…

Centos7.9编写分布式集群大数据系统_自启动脚本---Linux工作笔记058

由于为了方便,系统在启动的时候,设置成系统所有的,集群软件都自动启动,这样,可以减少,运维成本,要不然,这么多,工具,有的还不知道放到什么位置了,一个个去启动,非常麻烦. 首先编辑: 编辑这个文件: 然后编辑这个文件,写上自己,自启动脚本的位置,然后保存 :wq 然后再给这个文件…

【RabbitMQ】golang客户端教程5——使用topic交换器

topic交换器&#xff08;主题交换器&#xff09; 发送到topic交换器的消息不能具有随意的routing_key——它必须是单词列表&#xff0c;以点分隔。这些词可以是任何东西&#xff0c;但通常它们指定与消息相关的某些功能。一些有效的routing_key示例&#xff1a;“stock.usd.ny…

8月11日上课内容 nginx的多实例和动静分离

多实例部署 在一台服务器上有多个tomcat的服务。 配置多实例之前&#xff0c;看单个实例是否访问正常。 1.安装好 jdk 2.安装 tomcat cd /opt tar zxvf apache-tomcat-9.0.16.tar.gz mkdir /usr/local/tomcat mv apache-tomcat-9.0.16 /usr/local/tomcat/tomcat1 cp -a /usr…

利用三维内容编辑器制作VR交互课件,简单好用易上手

随着虚拟现实技术的不断发展&#xff0c;越来越多的教育机构开始尝试将其应用于教育教学中。然而&#xff0c;要实现这一目标并不容易&#xff0c;需要专业的技术支持和开发团队。 为了解决这一问题&#xff0c;广州华锐互动研发了三维内容编辑器&#xff0c;它是一种基于虚拟现…

“掌握类与对象,点亮编程之路“(下)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:《C语言入门知识》&#x1f649; &#x1f649; 内容推荐:“掌握类与对象&#xff0c;点亮编程之路“(上)&#x1f649; &#x1f439;今日诗词:春风得意马蹄疾&#xff0c;一日看尽长安花&#x1f439; 目录 &…

fork创建多个子进程

fork创建多个子进程 示例代码 fork1.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h>int main(int argc,char **argv) {int i, j;pid_t pid;for (i 0; i < 3; i){pid fork();if (pid < 0){perror(&q…

Python 11道字典练习题

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 有字典 dic {“k1”: “v1”, “k2”: “v2”, “k3”: “v3”}&#xff0c;实现以下功能&#xff1a; 1、遍历字典 dic 中所有的key 参考答案&#xff1a; dic {k1: v1,k2:v2,k3:v3}for k in dic.keys():print(k)2、遍历…

Apollo让自动驾驶如此简单

前言&#xff1a; 最近被新能源的电价闹的不行&#xff0c;买了电车的直呼上当了、不香了。但电车吸引人不只是公里油耗低&#xff0c;还有良好的驾车使用感。比如辅助驾驶、甚至是自动驾驶。今天来介绍一个头部自动驾驶平台Apollo&#xff0c;Apollo是一个开源的、自动驾驶的软…