Spring Cache基本使用

news2024/12/24 21:04:37

Spring 从 3.1 版本开始定义缓存抽象来统一不同的缓存技术;在应用层面与后端存储之间,提供了一层抽象,这层抽象目的在于封装各种可插拔的后端存储( ehcache, redis, guava),最小化因为缓存给现有业务代码带来的侵入。

一、Spring Cache简介

Spring Cache 是 Spring 框架提供的一个缓存抽象,实现了基于注解的缓存功能,它能够轻松地集成到 Spring 应用程序中,为方法调用的结果提供缓存支持,从而提高应用程序的性能和响应速度。

Spring Cache 提供了一种声明式的缓存机制,可以在方法上使用注解来指定需要进行缓存的方法,而无需编写繁琐的缓存代码。

Spring Cache 基本介绍:

  • 声明式缓存支持:Spring Cache 提供了一种声明式的缓存机制,通过在方法上使用注解来声明需要进行缓存的方法。比如:@Cacheable、@CachePut、@CacheEvict等注解。
  • 灵活的缓存策略:Spring Cache 提供了多种灵活的缓存策略,可以根据具体需求选择合适的缓存方案。比如:基于内存缓存、基于 Redis、Ehcache 等第三方缓存框架的集成。
  • 支持缓存管理器:Spring Cache 支持多种缓存管理器,可以根据需要选择适合的缓存管理器。比如:ConcurrentMapCacheManager、EhCacheCacheManager、RedisCacheManager 等。
  • 适用于各种应用场景:Spring Cache 适用于各种应用场景,可以用于缓存方法的返回值、类级别的缓存、缓存的条件判断等。

Spring Cache核心抽象主要体现在两个接口上:

  • org.springframework.cache.cache接口:cache代表缓存组件规范定义(缓存本身),包含缓存的各种操作集合。比如:增加、删除、读取等。
  • org.springframework.cache.cachemanager接口:CacheManager 是 Spring 各种缓存的抽象接口。抽象的意义在于屏蔽实现细节的差异和提供扩展性,这一层cache的抽象解耦了缓存的使用和缓存的后端存储,这样后续可以方便的更换后端存储。

Spring提供了 Cache接口下各种 XxxCache实现。比如:RedisCache, EhCacheCache, ConcurrentMapCache, JCacheCache等。

Spring支持的常用 CacheManager 如下:

Spring Cache 默认使用 ConcurrentMapCacheManager 作为缓存管理器。

在这里插入图片描述
通过使用 Spring Cache,可以轻松地为应用程序中的方法调用提供缓存支持,从而提高应用程序的性能和响应速度,减少对数据库或其他资源的频繁访问。

每次调用需要缓存功能的方法时,Spring 会检查检查指定参数的指定的目标方法是否已经被调用过。

  • 如果有就直接从缓存中获取方法调用后的结果。
  • 如果没有就调用方法并缓 存结果后返回给用户。下次调用直接从缓存中获取。

二、Spring Cache使用

Spring Cache依赖如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

在spring boot项目中,无需添加 Spring Cache 的依赖,因为 Spring Boot 已经自动集成了 Spring Cache。

1、接入Redis使用Spring Cache

添加 Redis依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

项目配置文件(application.yml)中添加 Redis配置信息:

spring:
  ## Redis 配置信息
  redis:
    host: 127.0.0.1
    port: 6379
    password: xxxxxx
    database: 1

1.1 Redis配置类

Redis默认使用 JdkSerializationRedisSerializer序列化器。

  • RedisTemplate 中,k和v默认的序列化方案是 JdkSerializationRedisSerializer 。
  • RedisTemplate<String, Object> 中,k和v默认的序列化方案是 JdkSerializationRedisSerializer 。
  • StringRedisTemplate 中,k和v默认的序列化方案是 StringRedisSerializer 。默认情况下,前面不会有前缀。
@Configuration
public class RedisConfiguration {

    @Primary
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());

        redisTemplate.setValueSerializer(RedisSerializer.java());
        redisTemplate.setHashValueSerializer(RedisSerializer.java());
        redisTemplate.setConnectionFactory(factory);
        // 调用 afterPropertiesSet()方法执行初始化操作
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

1.2 Spring Cache配置类

@EnableCaching注解:开启缓存功能,一般放在启动类或者配置类上。

CacheManager可以不用注入,Spring框架会自动注入的。如果我们手动注入,会使用我们自己注入的(适合自定义相关配置信息)。

下面使用 RedisCacheManager作为缓存缓存管理。

@EnableCaching
@Configuration
public class CacheConfiguration {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheManager cacheManager = RedisCacheManager.create(connectionFactory);
        return cacheManager;
    }
}

2、核心注解使用

Spring Cache提供了下面几个核心注解完成缓存功能的实现。

  • @EnableCaching:开启缓存功能
  • @Cacheable:定义缓存,用于触发缓存
  • @CachePut:定义更新缓存,触发缓存更新
  • @CacheEvict:定义清除缓存,触发缓存清除
  • @Caching:组合定义多种缓存功能
  • @CacheConfig:定义公共设置,位于class之上

2.1 @Cacheable注解

@Cacheable注解:定义缓存数据或者获取缓存数据操作。
@Cacheable 注解可以应用于类或方法上。当应用于类上时,表示该类的所有方法的返回值都可以被缓存;当应用于方法上时,表示特定方法的返回值可以被缓存。

该注解标注的方法每次被调用前都会触发缓存校验,校验指定参数的缓存是否已存在(已发生过相同参数的调用),若存在,直接返回缓存结果,否则执行方法内容,最后将方法执行结果保存到缓存中。

2.1.1 主要属性

主要属性如下:

  • value:必填,指定缓存数据存放在哪块命名空间(缓存名)。用于指定要操作的缓存名称或缓存管理器的名称。可以是一个字符串,也可以是一个字符串数组,用于指定多个缓存名称。
  • cacheNames:与 value 差不多,二选一即可。
  • key:可选,指定缓存条目的键,用于唯一标识缓存中的条目。SpEL 表达式可以用于动态地生成键值。如果不指定 key,Spring Cache 将会使用默认的键生成策略来生成键值。
  • condition:条件符合则缓存。指定一个 SpEL 表达式,用于判断是否执行缓存操作。只有当表达式的值为 true 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • unless:条件符合则不缓存。指定一个 SpEL 表达式,用于判断是否不执行缓存操作。只有当表达式的值为 false 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • keyGenerator:指定一个自定义的键生成器,用于生成缓存条目的键值。默认为空,表示使用默认的键生成策略。key/keyGenerator二选一使用。
  • cacheManager:指定一个自定义的缓存管理器,用于指定缓存的实现。默认为空,表示使用默认的缓存管理器。
  • cacheResolver:指定一个自定义的缓存解析器,用于解析缓存的实现。默认为空,表示使用默认的缓存解析器。
  • sync:指定是否启用同步模式。如果设置为 true,那么缓存操作将在调用方法的同一线程中执行,否则将在后台线程中异步执行。默认为 false。
2.1.2 使用
    @Cacheable(value = "userCache_", key = "#id", unless = "#result==null")
    @Override
    public UserDTO getById(Long id) {
        if (id == null || id <= 0L) {
            return null;
        }
        UserDO userDO = userMapper.selectById(id);
        return do2DTO(userDO);
    }

unless参数里的 #result为方法的返回值。所以,判断方法返回值为 null 时,则不缓存。

在这里插入图片描述

2.2 @CachePut注解

@CachePut注解:更新缓存数据操作。
@CachePut与 @Cacheable 不同,@CachePut 不会检查缓存中是否已经存在相同键的条目,而是直接将方法的返回值更新到缓存中。

该注解用于更新缓存,无论结果是否已经缓存,都会在方法执行结束插入缓存,相当于更新缓存。一般用于更新方法之上。

2.2.1 主要属性

主要属性如下:

  • value:必填,指定缓存数据存放在哪块命名空间(缓存名)。用于指定要操作的缓存名称或缓存管理器的名称。可以是一个字符串,也可以是一个字符串数组,用于指定多个缓存名称。
  • cacheNames:与 value 差不多,二选一即可。
  • key:可选,指定缓存条目的键,用于唯一标识缓存中的条目。SpEL 表达式可以用于动态地生成键值。如果不指定 key,Spring Cache 将会使用默认的键生成策略来生成键值。
  • condition:条件符合则缓存。指定一个 SpEL 表达式,用于判断是否执行缓存操作。只有当表达式的值为 true 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • unless:条件符合则不缓存。指定一个 SpEL 表达式,用于判断是否不执行缓存操作。只有当表达式的值为 false 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • keyGenerator:指定一个自定义的键生成器,用于生成缓存条目的键值。默认为空,表示使用默认的键生成策略。key/keyGenerator二选一使用
  • cacheManager:指定一个自定义的缓存管理器,用于指定缓存的实现。默认为空,表示使用默认的缓存管理器。
  • cacheResolver:指定一个自定义的缓存解析器,用于解析缓存的实现。默认为空,表示使用默认的缓存解析器。
2.2.2 使用
    @CachePut(cacheNames = "userCache_", key = "#updateRequest.userId", unless = "#result == null")
    @Override
    public UserDTO update2(UserUpdateRequest updateRequest) {
        Long id = updateRequest.getUserId();
        if (id == null || id <= 0) {
            return null;
        }
        // 修改用户信息
        UserDO updateDO = new UserDO();
        BeanUtils.copyProperties(updateRequest, updateDO);
        updateDO.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(updateDO);
        
        // 演示效果
        UserDO userDO = userMapper.selectById(id);
        return do2DTO(userDO);
    }

注意:这里设置的 key一定要和执行缓存保存的方法设置 key一致,否则无法准确更新。

使用方法参数作为 key的示例:

   @Cacheable(value="users", key="#id")
   public User find(Integer id) {
      return null;
   }
   @Cacheable(value="users", key="#p0")
   public User find(Integer id) {
      return null;
   }
   // 推荐使用
   @Cacheable(value="users", key="#user.id")
   public User find(User user) {
      return null;
   }
   @Cacheable(value="users", key="#p0.id")
   public User find(User user) {
      return null;
   }

除了上述使用方法参数作为 key之外,Spring还为我们提供了一个 root对象可以用来生成 key。通过该 root对象我们可以获取到以下信息。

在这里插入图片描述

2.3 @CacheEvict注解

@CacheEvict注解:删除缓存数据操作。

2.3.1 主要属性

主要属性如下:

  • value:必填,指定缓存数据存放在哪块命名空间(缓存名)。用于指定要操作的缓存名称或缓存管理器的名称。可以是一个字符串,也可以是一个字符串数组,用于指定多个缓存名称。
  • cacheNames:与 value 差不多,二选一即可。
  • key:可选,指定缓存条目的键,用于唯一标识缓存中的条目。SpEL 表达式可以用于动态地生成键值。如果不指定 key,Spring Cache 将会使用默认的键生成策略来生成键值。
  • condition:条件符合则缓存。指定一个 SpEL 表达式,用于判断是否执行缓存操作。只有当表达式的值为 true 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • eyGenerator:指定一个自定义的键生成器,用于生成缓存条目的键值。默认为空,表示使用默认的键生成策略。key/keyGenerator二选一使用。
  • cacheManager:指定一个自定义的缓存管理器,用于指定缓存的实现。默认为空,表示使用默认的缓存管理器。
  • cacheResolver:指定一个自定义的缓存解析器,用于解析缓存的实现。默认为空,表示使用默认的缓存解析器。
  • allEntries:是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存。
  • beforeInvocation:是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存。
2.3.2 使用
    @CacheEvict(value = "userCache_", key = "#id", condition = "#result.success == true")
    //@CacheEvict(value = "userCache_", allEntries = true)
    @Override
    public BaseOperateResult deleteById(Long id) {
        BaseOperateResult operateResult = new BaseOperateResult();

        if (id == null || id <= 0L) {
            operateResult.setSuccess(false);
            operateResult.setErrorCode(DemoErrorCodeEnum.ID_IS_NOT_NULL.errorCode());
            return operateResult;
        }
        UserDTO oldDTO = getById(id);
        if (oldDTO == null) {
            operateResult.setSuccess(Boolean.FALSE);
            operateResult.setErrorCode(DemoErrorCodeEnum.RECORD_NOT_FOUND.errorCode());
            return operateResult;
        }
        // 不允许删除管理员账号
        if ("admin".equals(oldDTO.getUsername())) {
            operateResult.setSuccess(Boolean.FALSE);
            operateResult.setErrorCode(DemoErrorCodeEnum.NOT_DELETE_ADMIN_USER.errorCode());
            return operateResult;
        }

        // 用户逻辑删除
        UserDO updateDO = new UserDO();
        updateDO.setUserId(id);
        updateDO.setDelFlag(CommonConstants.DELETE_FLAG_DELETED);
        userMapper.updateById(updateDO);

        operateResult.setId(id);
        operateResult.setSuccess(true);
        return operateResult;
    }

注意:

  • 这里设置的 key一定要和执行缓存保存的方法设置 key一致,否则无法准确删除。
  • condition参数里的 #result为方法的返回值。所以,判断方法返回值的 success = true 时,则执行删除缓存操作。
  • 如果配置了 allEntries属性,则会删除 value为命名空间下的所有缓存条目的键,此时配不配 key属性都不会影响 allEntries属性操作。

3、全局配置Cache参数信息(了解)

参考文章:spring-boot+redis实现缓存功能:https://www.jianshu.com/p/be2c09cd27d8

项目配置文件(application.yml)中可以添加 cache配置信息。

注意:

  • 如果使用 Spring框架自动注入 CacheManager的方式,下面配置会生效。
  • 如果使用我们手动注入的自定义了 CacheManager方式,下面配置不会生效,而是使用我们自定义的相关配置。
spring:
  ## Redis 配置信息
  redis:
    host: 127.0.0.1
    port: 6379
    password: xxxxxx
    database: 1
  ## Spring cache配置信息
  cache:
    # 缓存的类型,redis
    type: redis
    redis:
      # 缓存数据key是否使用前缀,默认是true
      use-key-prefix: true
      #缓存数据key的前缀,在上面的配置为true时有效,
      key-prefix: 'demo:'
      # redis中缓存超时的时间,默认60000ms
      time-to-live: 120000

参考文章:

  • SpEL表达式详解:https://blog.csdn.net/weixin_43888891/article/details/127520555

– 求知若饥,虚心若愚。

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

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

相关文章

DRKCT复现

Osint 羡慕群友每一天 MISC 签到 扫码关注公众号&#xff0c;回复一下行 &#xff08;眼神要好&#xff0c; 我做题时没看见有个二维码&#xff09; 神秘的文字 把代码js运行一下 (用js的原因是前面给的动物代表的字符类似jsfuck代码) &#x13142;![]; &#x13080;!…

Daisy Chain

菊花链是双向和半双工的&#xff0c;因此在 COMH 和 COML 接口上有一个发送器 (TX) 和一个接收器 (RX)。TX 和 RX 功能由硬件根据器件的基底/堆栈检测自动控制。当接收到 WAKE ping/音调时&#xff0c;通信方向由 CONTROL1[DIR_SEL] 和 COMM_CTRL[TOP_STACK] 配置进行设置。 对…

如何处理网安发出的网络安全监督检查限期整改通知

近期&#xff0c;很多客户都收到了网安发出的限期整改通知。大家都比较关心的问题是&#xff0c;如何应对处理这些限期整改通知。后续是否有其他的影响&#xff0c;需要如何做进一步的优化整改和调整。今天就这些问题给大家做一些分享。 一. 为什么会有网安的网络安全检查 主…

系统管理、磁盘分区

系统管理 业务层面&#xff1a;为了满足一定的需求所做的特定操作。 硬盘是什么&#xff0c;硬盘的作用&#xff1a; **硬盘&#xff1a;**计算机的存储设备&#xff0c;机械硬盘是由一个或者多个磁性的盘组成&#xff0c;可以在盘片上进行数据的读写。 连接方式&#xff1a…

谈谈BlueStore的BitmapAllocator

背景 BlueStore在ceph里面承担了数据在底层磁盘上的读写任务&#xff0c;那它的功能里自然就有一块是管理磁盘空间使用的。说白了&#xff0c;就是记录&管理磁盘里哪些空间已经使用了&#xff0c;哪些空间还没有被使用。 目前官方的ceph里使用BitmapAllocator来管理磁盘空…

冯喜运:5.27黄金短线看震荡,今日黄金原油走势分析

【黄金消息面分析】&#xff1a;黄金作为传统的避险资产&#xff0c;在经济不确定性中扮演着至关重要的角色。近期&#xff0c;国际黄金价格经历了显著的波动。从5月9日的低点2325.19美元/盎司反弹至2340美元/盎司以上&#xff0c;尽管金价曾一度触及2449.89美元/盎司的历史高点…

C++ 数据结构算法 学习笔记(33) -查找算法及企业级应用

C 数据结构算法 学习笔记(33) -查找算法及企业级应用 数组和索引 日常生活中&#xff0c;我们经常会在电话号码簿中查阅“某人”的电话号码&#xff0c;按姓查询或者按字母排 序查询&#xff1b;在字典中查阅“某个词”的读音和含义等等。在这里&#xff0c;“电话号码簿”和…

高弹性架构的微服务设计模式

长期以来&#xff0c;开发人员一直使用单片架构&#xff0c;而且长期以来&#xff0c;这种架构一直有效。不幸的是&#xff0c;这些架构使用的部件较少&#xff0c;但体积较大&#xff0c;这意味着如果一个部件发生故障&#xff0c;它们更有可能整体失效。通常&#xff0c;这些…

《书生·浦语大模型实战营》第1课 学习笔记:书生·浦语大模型全链路开源体系

文章大纲 1. 简介与背景智能聊天机器人与大语言模型目前的开源智能聊天机器人与云上运行模式 2. InternLM2 大模型 简介3. 视频笔记&#xff1a;书生浦语大模型全链路开源体系内容要点从模型到应用典型流程全链路开源体系 4. 论文笔记:InternLM2 Technical Report简介软硬件基础…

HR招聘面试测评,哪些工作岗位需要测评创新能力?

什么是创新能力&#xff1f; 创新能力指在现有的物质基础上&#xff0c;通过某些特定的条件&#xff0c;促成满足未来社会发展的新事物。无论是个人还是国家都需要巨大的创新能力&#xff0c;因为创新是一切发展的根基&#xff0c;离开了创新&#xff0c;所有的发展都是原地踏…

Windows安全基础——Windows WMI详解

Windows安全基础——WMI篇 1. WMI简介 WMI&#xff08;Windows Management Instrumentation, Windows管理规范&#xff09;是Windows 2000/XP管理系统的核心&#xff0c;属于管理数据和操作的基础模块。设计WMI的初衷是达到一种通用性&#xff0c;通过WMI操作系统、应用程序等…

设计模式16——策略模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 策略模式&#xff08;Strategy…

计算机的存储体系

计算机的存储分为内存和硬盘两大类。其中内存属于非持久化的存储设备&#xff0c;用于临时存储数据&#xff0c;设备掉电后数据会丢失&#xff1b;硬盘属于持久化的存储设备&#xff0c;设备掉电后数据不会丢失。 实际上在计算机领域存储的种类是非常多的&#xff0c;业界有时…

linux网卡MAC地址

1、ifconfig命令查看网卡MAC地址 1.1 通过HWaddr或ether字段过滤mac地址 ifconfig | grep HWaddr ifconfig | grep ether [rootlocalhost ~]# /sbin/ifconfig | grep ether 注&#xff1a;有些Linux发行版本的MAC地址字段为HWaddr&#xff0c;有些Linux发行版本的MAC地址字段…

SkyWalking 介绍及部署

1、SkyWalking简介2、SkyWalking的搭建 2.1 部署Elasticsearch2.2 部署SkyWalking-Server2.3 部署SkyWalking-UI3、应用接入 3.1 jar包部署方式3.2 dockerfile方式3.3 DockerFile示例4、SkyWalking UI 界面说明 4.1 仪表盘 4.1.1 APM &#xff08;1&#xff09;全局维度&#x…

clickhouse——ck目录介绍

一、ck目录 1、/etc/clickhouse-server: 服务端的配置文件目录&#xff0c;包括全局配置config.xml和用户配置users.xml等。 2、/var/lib/clickhouse 默认的数据存储目录&#xff08;通常会修改默认路径配置&#xff0c;将数据保存到大容量磁盘挂载的路径&#xff09; 3、/var…

电脑不能远程桌面连接不上,电脑无法建立远程桌面连接如何解决?

电脑无法建立远程桌面连接的问题&#xff0c;通常涉及到多个层面的因素&#xff0c;包括但不限于网络设置、系统配置、防火墙设置以及服务状态等。以下是一些专业性的解决方案&#xff0c;以帮助您解决这一问题。 首先&#xff0c;我们需要检查网络连接。远程桌面连接需要稳定的…

【数据库】通过一个实例来认识数据流图DFD

导读&#xff1a;通过一个实例&#xff08;数据中台&#xff09;说明数据流图DFD的作用、介绍了常见的数据流图元素及其标准符号以及如何画数据流图。数据流图主要被分析师、系统设计师、流程优化专家、系统管理员以及与系统开发和维护相关的人员查看和使用。对于刚考完2024年5…

怎样在网上赚点零花钱?推荐十个正规的赚钱兼职平台

今天要和大家探讨一个激动人心的话题——网络赚钱。在这个互联网日新月异的时代&#xff0c;网络赚钱已经变成了触手可及的现实。如果你正打算在网上赚取一些额外收入&#xff0c;那么这篇文章绝对值得一读&#xff01; 在这个信息泛滥的时代&#xff0c;网络赚钱的机遇随处可…

redis数据操作相关命令

1.list操作 1.1 rpush rpush&#xff1a;新的元素添加到list最右边 #从右边依次往List添加1,2,3 RPUSH name 1 RPUSH name 2 RPUSH name 3#查看列表&#xff1a;返回 1,2,3 LRANGE name 0 -1结果如下&#xff1a; 1.2 lpush lpush&#xff1a;新加的元素在list最左边 #从…