【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis

news2024/11/24 17:00:46

目录

  • 【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis
    • 什么是缓存抽象
      • 声明式注解
      • JSR-107对应
      • SpEL上下文数据
    • 引入依赖
    • cache 支持的缓存类型
    • 缓存类型配置
      • NONE
      • SIMPLE
      • REDIS
        • 自定义配置
      • CAFFEINE
    • Hazelcast
    • ...
    • 总结

个人主页: 【⭐️个人主页】
需要您的【💖 点赞+关注】支持 💯


【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis

📖 本文核心知识点:

  • spring cache 抽象和注解
  • cache 支持的缓存类型
  • spring cache + spring data redis 配置
  • redis序列化

本章使用的spring版本
spring boot version: 3.1.5

什么是缓存抽象

  • 官网-缓存抽象
    使用翻译软件阅读
  • 主要阅读的知识点
  1. 缓存抽象的作用
  2. spring缓存的声明式注解
  3. spring缓存的生成key策略和如何自定义keyGenerator
  4. 缓存支持的后端类型

声明式注解

Spring 缓存注解说明
@Cacheable触发缓存填充。
@CacheEvict触发缓存退出。
@CachePut在不干扰方法执行的情况下更新缓存。
@Caching将多个缓存操作重新组合到一个方法上。
@CacheConfig在类级别共享一些常见的与缓存相关的设置。

JSR-107对应

Spring 缓存注解JSR-107备注
@Cacheable@CacheResult相当相似。 可以缓存特定的异常并强制 无论缓存的内容如何,都执行该方法。@CacheResult
@CachePut@CachePut当 Spring 使用方法调用的结果更新缓存时,JCache 要求将其作为注释的参数传递。 由于这种差异,JCache 允许在 实际方法调用。@CacheValue
@CacheEvict@CacheRemove相当相似。 支持有条件逐出,当 方法调用会导致异常。@CacheRemove
@CacheEvict(allEntries=true)@CacheRemoveAll看。@CacheRemove
@CacheConfig@CacheDefaults允许您以类似的方式配置相同的概念。

SpEL上下文数据

名称位置描述示例
methodNameroot对象当前被调用的方法名#root.methodname
methodroot对象当前被调用的方法#root.method.name
targetroot对象当前被调用的目标对象实例#root.target
targetClassroot对象当前被调用的目标对象的类#root.targetClass
argsroot对象当前被调用的方法的参数列表#root.args[0]
cachesroot对象当前方法调用使用的缓存列表#root.caches[0].name
Argument Name执行上下文当前被调用的方法的参数,如findArtisan(Artisan artisan),可以通过#artsian.id获得参数#artsian.id
result执行上下文方法执行后的返回值(仅当方法执行后的判断有效,如 unless cacheEvict的beforeInvocation=false)#result

引入依赖

    implementation 'org.springframework.boot:spring-boot-starter-cache'

添加启用缓存注解@EnableCaching

@SpringBootApplication(scanBasePackages = {"com.kongxiang"})
@EnableAutoConfiguration
@EnableCaching
public class StudySpring3Application {

	public static void main(String[] args) {
		SpringApplication.run(StudySpring3Application.class, args);
	}
}

cache 支持的缓存类型

spring cache支持的缓存类型
查看类org.springframework.boot.autoconfigure.cache.CacheType

public enum CacheType {

	/**
	 * Generic caching using 'Cache' beans from the context.
	 */
	GENERIC,

	/**
	 * JCache (JSR-107) backed caching.
	 */
	JCACHE,

	/**
	 * Hazelcast backed caching.
	 */
	HAZELCAST,

	/**
	 * Couchbase backed caching.
	 */
	COUCHBASE,

	/**
	 * Infinispan backed caching.
	 */
	INFINISPAN,

	/**
	 * Redis backed caching.
	 */
	REDIS,

	/**
	 * Cache2k backed caching.
	 */
	CACHE2K,

	/**
	 * Caffeine backed caching.
	 */
	CAFFEINE,

	/**
	 * Simple in-memory caching.
	 */
	SIMPLE,

	/**
	 * No caching.
	 */
	NONE

}

缓存类型配置

NONE

无缓存

spring:
  cache:
    type: NONE

SIMPLE

内存缓存

spring:
  cache:
    type: SIMPLE

在这里插入图片描述

REDIS

Redis 缓存

spring:
  cache:
    type: REDIS
  data:
    redis:
      host: '127.0.0.1'
      username:
      port: 6379
      password:
      database: 1
      lettuce:
        pool:
          enabled: true
          max-active: 8
          max-wait: 1000
          max-idle: 8
      connect-timeout: 5000

自定义配置

默认情况下会有两个模板类被注入Spring IoC供我们使用,需要个性化配置来满足实际的开发。

一个是RedisTemplate<Object, Object>,主要用于对象缓存,其默认使用JDK序列化,我们需要更改其序列化方式解决一些问题,比如Java 8日期问题JSON序列化问题。需要我们重写一下。

  1. RedisTemplate自定义配置
 @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = initJacksonSerializer();
        // 设置value的序列化规则和 key的序列化规则
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
    /**
     * 处理redis序列化问题
     * @return Jackson2JsonRedisSerializer
     */
    private Jackson2JsonRedisSerializer<Object> initJacksonSerializer() {
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //以下替代旧版本 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        //bugFix Jackson2反序列化数据处理LocalDateTime类型时出错
        om.disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
        // java8 时间支持
        om.registerModule(new JavaTimeModule());
        return new Jackson2JsonRedisSerializer<>(om,Object.class);
    }
  1. 缓存管理器自定义配置
    使用Spring Cache做缓存的时候,有针对不同的key设置不同过期时间的场景。比如Jwt Token我想设置为一周过期,而验证码我想设置为五分钟过期。这个怎么实现呢?需要我们个性化配置RedisCacheManager。首先我通过枚举来定义这些缓存及其TTL时间

我们通过向Spring IoC分别注入RedisCacheConfigurationRedisCacheManagerBuilderCustomizer来个性化配置


 /**
     * Redis cache configuration.
     *
     * @param redisTemplate the redis template
     * @return the redis cache configuration
     */
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration(RedisTemplate<Object, Object> redisTemplate, CacheProperties cacheProperties) {
        // 参见 spring.cache.redis
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                // 缓存的序列化问题
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(redisTemplate.getValueSerializer()));

        if (redisProperties.getTimeToLive() != null) {
            // 全局 TTL 时间
            redisCacheConfiguration = redisCacheConfiguration.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            // key 前缀值
            redisCacheConfiguration = redisCacheConfiguration.prefixCacheNameWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            // 默认缓存null值 可以防止缓存穿透
            redisCacheConfiguration = redisCacheConfiguration.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            // 不使用key前缀
            redisCacheConfiguration = redisCacheConfiguration.disableKeyPrefix();
        }
        return redisCacheConfiguration;
    }

    /**
     * Redis cache manager 个性化配置缓存过期时间.
     *
     * @return the redis cache manager builder customizer
     */
    @Bean
    public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(RedisCacheConfiguration redisCacheConfiguration) {
        return builder -> builder.cacheDefaults(redisCacheConfiguration);
    }

CAFFEINE

引入依赖

    implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'

修改配置

spring:
  cache:
    type: CAFFEINE

直接启动即可

Hazelcast

总结

spring cache 缓存抽象加上spring data包和spring boot autoconfig 配置包的能力,可以快速接入一个具体的缓存实现。redis是我们公司基本使用的缓存策略。所以针对redis的一些自定义配置,通过 java bean的方式实现。着重强调一下。

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

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

相关文章

打开PDF文件之后不能编辑,有哪些原因?

打开PDF文件之后发现没有办法编辑PDF文件&#xff0c;都有哪些原因呢&#xff1f; 首先我们可以考虑一下&#xff0c;PDF文件中的内容是否是图片&#xff0c;如果确认是图片文件&#xff0c;那么我们想要编辑&#xff0c;就可以先使用PDF编辑器中的OCR扫描功能&#xff0c;将图…

【Python】Pandas(学习笔记)

一、Pandas概述 1、Pandas介绍 2008年WesMcKinney开发出的库&#xff0c;专门用于数据挖掘的开源python库 以Numpy为基础&#xff0c;借力Numpy模块在计算方面性能高的优势 基于matplotib&#xff0c;能够简便的画图 独特的数据结构 import pandas as pd2、Pandas优势 便…

springcloud失物招领网站源码

开发技术&#xff1a; jdk1.8&#xff0c;mysql5.7&#xff0c;idea&#xff0c;nodejs&#xff0c;vscode springcloud springboot mybatis vue elementui 功能介绍&#xff1a; 用户端&#xff1a; 登录注册 首页显示搜索失物&#xff0c;轮播图&#xff0c;最新发布的…

传统广电媒体为何选择上云?有何优势?

随着现在互联网和科技的发展&#xff0c;现在更多的行业都搭上了科技这辆快车快速的完成了转型&#xff0c;那么在传统的广电媒资行业他们目前有哪些痛点呢&#xff1f;传统广电媒体转型发展现状是什么&#xff1f;企业如何数字化转型&#xff1f;企业上云的优势有哪些&#xf…

OpenCV快速入门:基本操作

文章目录 1. 像素操作1.1 像素统计1.2 两个图像之间的操作1.2.1 图像加法操作1.2.3 图像加权混合 1.3 二值化1.4 LUT&#xff08;查找表&#xff09;1.4.1 查找表原理1.4.2 代码演示 2 图像变换2.1 旋转操作2.1.1 旋转的基本原理2.1.2 代码实现 2.2 缩放操作2.3 平移操作2.3.1 …

【python】均值、中值和高斯滤波详解和示例

本文对均值、中值和高斯滤波进行详解&#xff0c;以帮助大家理解和使用。 这里写目录标题 均值滤波中值滤波高斯滤波核大小为&#xff08;9,9&#xff09;核大小为&#xff08;51,51&#xff09; 小结 下面是示例中使用的原图。 均值滤波 均值滤波是一种简单的平滑滤波器&…

简单的用Python实现一下,采集某牙视频,多个视频翻页下载

前言 表弟自从学会了Python&#xff0c;每天一回家就搁那爬视频&#xff0c;不知道的以为是在学习&#xff0c;结果我昨天好奇看了一眼&#xff0c;好家伙&#xff0c;在那爬某牙舞蹈区&#xff0c;太过分了&#xff01; 为了防止表弟做坏事&#xff0c;我连忙找了个凳子坐下&…

k8s-部署Redis-cluster(TLS)

helm pull bitnami/redis-cluster v8.3.8拉取源码生成证书 git clone https://github.com/redis/redis.git #文档 https://redis.io/docs/management/security/encryption/#getting-started生成你的TLS证书用官网的工具生成 1 Run ./utils/gen-test-certs.sh 生成根CA和服务…

【libGDX】ApplicationAdapter生命周期

1 前言 libGDX 中&#xff0c;用户自定义的渲染窗口需要继承 ApplicationAdapter 类&#xff0c;ApplicationAdapter 实现了 ApplicationListener 接口&#xff0c;但实现的方法都是空方法&#xff0c;方法释义如下。 public interface ApplicationListener {// 应用首次创建时…

【Rust】快速教程——冻结表达式

前言 以前谁是魔我杀谁&#xff0c;现在我杀谁谁就是魔。——《拔魔》 \;\\\;\\\; 目录 前言Rust基本知识结构体元组结构体局部作用域冻结字面量Vec元素的类型由第一个push进的类型确定type别名from和intoTryFrom和TryInto 表达式 Rust基本知识 结构体 #[derive(Debug)] str…

C语言之深入指针及qsort函数(五)(详解介绍)

C语言之深入指针 在这篇博客看不懂的可以看看这篇C语言之深入指针&#xff08;四&#xff09;在上篇博客中介绍了&#xff1a; 函数指针变量函数指针数组简易计算器的实现\ 文章目录 C语言之深入指针1 回调函数2 qsort函数的使用2.1 使用冒泡排序排序整型数组2.2 使用qsort函数…

国内crm解决方案的主要提供商有哪些?对比7家

目前国内CRM服务商1410家&#xff0c;今年1-7月CRM服务商新注册19家。如何从众多服务商中挑选出合适的一家&#xff0c;无疑是一项耗时耗力的大工程。为此&#xff0c;本文将为根据国内外知名机构、媒体、网站发布、百度指数、行业知名度等维度考量&#xff0c;选择出7大CRM系统…

【DevOps】Git 图文详解(一):简介及基础概念

Git 图文详解&#xff08;一&#xff09;&#xff1a;简介及基础概念 1.简介&#xff1a;认识 Git2.基础概念&#xff1a;Git 是干什么的&#xff1f;2.1 概念汇总2.2 工作区 / 暂存区 / 仓库2.3 Git 基本流程2.4 Git 状态 1.简介&#xff1a;认识 Git Git 是当前最先进、最主…

系列一、JVM概述

一、概述 1.1、Java发展中的重大事件 1.2、虚拟机 vs Java虚拟机 1.2.1、虚拟机 1.2.2、Java虚拟机 1.2.3、Java虚拟机的作用 Java虚拟机是二进制字节码的运行环境&#xff0c;负责装载字节码到其内部&#xff0c;解释/编译为对应平台上的机器指令指令。每一条Java指令&#…

力扣-路径总和问题

路径总和 --简单 112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 f…

MATLAB 状态空间设计 —— LQG/LQR 和极点配置算法

系列文章目录 文章目录 系列文章目录前言一、相关函数 —— LQG/LQR 和极点配置算法1.1 LQR —— lqr 函数1.1.1 函数用法1.1.2 举例1.1.2.1 倒摆模型的 LQR 控制 1.2 LQG —— lqg() 函数1.2.1 函数用法1.2.2 举例 1.3 极点配置 —— place() 函数1.3.1 函数用法1.3.2 示例1.3…

【算法】复习搜索与图论

&#x1f34e; 博客主页&#xff1a;&#x1f319;披星戴月的贾维斯 &#x1f34e; 欢迎关注&#xff1a;&#x1f44d;点赞&#x1f343;收藏&#x1f525;留言 &#x1f347;系列专栏&#xff1a;&#x1f319; 蓝桥杯 &#x1f319;请不要相信胜利就像山坡上的蒲公英一样唾手…

Spring Task使用介绍

文章目录 Spring Task介绍cron表达式入门案例Spring Task使用步骤全注解的方式代码开发测试结果 代码仓库 Spring Task 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 定位定时任务框架 作用定时自动执行某段Java…

36、Flink 的 Formats 之Parquet 和 Orc Format

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

NewStarCTF2023 Reverse方向Week3 ez_chal WP

分析 题目&#xff1a;ez_chal 一个XTEA加密&#xff0c; V6是key&#xff0c;v5是输入&#xff0c;然后v7就是密文。 看了v6&#xff0c;要用动调。 ELF文件用ida的远程调试。 然后在kali上输入长度为32的flag 全部转换成dd 再提取密文。 EXP #include <stdio.h>…