Spring Cacheable 注解

Spring Cacheable 注解

在Spring框架中,缓存是一种提高应用程序性能的重要技术手段。@Cacheable注解是Spring Cache中最常用的注解之一,它用于将方法的返回值缓存起来,以便后续调用时直接从缓存中获取,而不是再次执行方法。本文将详细介绍@Cacheable注解的使用方法及其工作原理。

什么是 @Cacheable 注解

@Cacheable注解是Spring提供的一种缓存注解,它可以应用于方法上,用于标记该方法的返回值需要缓存。每次调用该方法时,Spring会首先检查缓存中是否存在该方法的返回值,如果存在则直接返回缓存中的值,否则执行该方法并将其返回值存入缓存中。

@Cacheable 注解的基本使用

引入依赖

在使用@Cacheable之前,需要在项目中引入相关的Spring Cache依赖。对于Spring Boot项目,可以在pom.xml中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

配置缓存

接下来,需要在Spring Boot应用程序中启用缓存支持,并配置缓存管理器。例如,可以在application.properties中配置缓存:

spring.cache.type=caffeine
spring.cache.cache-names=exampleCache
spring.cache.caffeine.spec=maximumSize=100,expireAfterAccess=600s

在主应用程序类中启用缓存:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

使用 @Cacheable 注解

在需要缓存的方法上使用@Cacheable注解,例如:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class ExampleService {

    @Cacheable("exampleCache")
    public String getData(String param) {
        // 模拟耗时操作
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Data for " + param;
    }
}

当第一次调用getData方法时,会执行实际的业务逻辑并将结果缓存起来。再次调用时,将直接从缓存中获取数据,而不再执行耗时的操作。

@Cacheable 注解的高级用法

指定缓存的Key

默认情况下,@Cacheable会使用方法参数作为缓存的Key。可以通过key属性指定自定义的Key:

@Cacheable(value = "exampleCache", key = "#param")
public String getData(String param) {
    // ...
}

条件缓存

可以使用condition属性指定条件,满足条件时才进行缓存:

@Cacheable(value = "exampleCache", condition = "#param.length() > 3")
public String getData(String param) {
    // ...
}

缓存同步

在并发环境中,可以使用sync属性启用缓存同步,防止缓存击穿:

@Cacheable(value = "exampleCache", sync = true)
public String getData(String param) {
    // 模拟耗时操作
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Data for " + param;
}

当多个线程同时请求缓存中没有的数据时,只有一个线程会执行方法,其他线程等待结果。这种机制能够有效避免多个线程同时执行相同的方法,从而减少资源消耗,提高系统性能。

例如,当大量并发请求同时查询某个缓存中没有的数据时,如果没有同步机制,每个请求都会触发一次方法执行,这不仅浪费资源,还可能导致数据库或其他底层服务过载。而启用sync属性后,只有一个请求会执行方法,其他请求等待结果,执行完毕后,结果会被缓存,后续请求直接从缓存中获取数据。

自定义的Key生成器keyGenerator

keyGenerator参数用于指定一个自定义的Key生成器,覆盖默认的Key生成方式。需要实现org.springframework.cache.interceptor.KeyGenerator接口,并在配置类或服务类中进行注册。

自定义Key生成器示例:

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
        return method.getName() + "_" + Arrays.toString(params);
    }
}

在使用@Cacheable时指定自定义Key生成器:

@Cacheable(value = "exampleCache", keyGenerator = "customKeyGenerator")
public String getData(String param) {
    // ...
}

详细介绍 cacheManager

cacheManager参数用于指定一个自定义的缓存管理器。如果没有指定,使用默认的缓存管理器。缓存管理器负责管理应用程序中的所有缓存实例。

自定义缓存管理器示例:

import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CacheConfig {

    @Bean
    public CacheManager customCacheManager() {
        return new ConcurrentMapCacheManager("exampleCache");
    }
}

在使用@Cacheable时指定自定义缓存管理器:

@Cacheable(value = "exampleCache", cacheManager = "customCacheManager")
public String getData(String param) {
    // ...
}

自定义的缓存解析器cacheResolver

cacheResolver参数用于指定一个自定义的缓存解析器。需要实现org.springframework.cache.interceptor.CacheResolver接口,缓存解析器负责根据某些逻辑来解析和提供缓存实例。

自定义缓存解析器示例:

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Collections;

@Component("customCacheResolver")
public class CustomCacheResolver implements CacheResolver {

    private final CacheManager cacheManager;

    public CustomCacheResolver(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    @Override
    public Collection<? extends Cache> resolveCaches(org.springframework.cache.interceptor.CacheOperationInvocationContext<?> context) {
        // 自定义缓存解析逻辑
        return Collections.singleton(cacheManager.getCache("exampleCache"));
    }
}

在使用@Cacheable时指定自定义缓存解析器:

@Cacheable(value = "exampleCache", cacheResolver = "customCacheResolver")
public String getData(String param) {
    // ...
}

unless

unless参数是一个SpEL表达式,只有当表达式为false时才缓存方法的返回值。它的优先级高于condition,可以用于在某些条件下禁用缓存。

例如,可以在结果长度大于10时不缓存:

@Cacheable(value = "exampleCache", unless = "#result.length() > 10")
public String getData(String param) {
    // ...
}

通过unless参数,可以在不改变方法逻辑的情况下,灵活控制缓存行为,避免不必要的缓存操作,提高系统性能。

缓存一致性问题

在使用缓存时,一个常见的问题是缓存一致性问题。当数据源(如数据库)中的数据发生变化时,缓存中的数据可能不会及时更新,导致缓存中的数据与实际数据不一致。为了解决这个问题,可以使用以下几种策略:

  1. 缓存失效策略:在更新或删除数据时,同时让相关缓存失效。
  2. 缓存刷新:定期刷新缓存,确保缓存中的数据是最新的。
  3. 消息队列:使用消息队列,在数据变化时通知缓存进行更新。

例如,在数据更新时手动清除缓存:

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class ExampleService {

    @CacheEvict(value = "exampleCache", key = "#param")
    public void updateData(String param, String newData) {
        // 更新数据库中的数据
    }
}

参考链接

  1. Spring Cache 官方文档
  2. Spring Boot Cache 官方文档
  3. Caffeine 缓存库
  4. SpEL 表达式官方文档

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

独立开发者系列(16)——数据表的设计

绝大部分项目&#xff0c;都需要用到数据库&#xff0c;而数据库需要设计数据表。而设计数据表&#xff0c;需要理解一些关于MYSQL的属性背景。要不然设计的时候&#xff0c;不符合规范或者性能非常差。 建立数据库。 主要是需要掌握字符集概念&#xff0c;在以前gbk网页编码比…

git 还原被删除的分支

在多人项目开发中&#xff0c;有一次碰到忘记合并到master分支了&#xff0c;直接就把开发分支给删除了&#xff0c;现在记录下怎么还原被删除的分支 必须保证删除的分支之前已经被推送到了远程仓库 # 找出被删除分支的最后一个提交的哈希值 git reflog show# 找到提交哈希值…

选项卡功能 样式

先上效果图 用的flex布局&#xff0c;flex1 自动平均分为几块 选中样式就是tab-active&#xff0c;有个背景色和下划线 <template><div><div class"tab-box"><!-- <div class"tab-li" :class"[activeIndex0?tab-active:]&…

赛氪网:企业竞赛组织平台新选择,一键操作助力赛事成功举办

在数字化时代&#xff0c;传统的赛事报名方式已经逐渐难以满足组织者和参赛者的需求。企业如何寻找一种既方便又高效的赛事报名工具&#xff1f;赛氪网平台凭借其便捷的操作流程、完善的管理功能和技术保障&#xff0c;成为众多企业和高校举办竞赛时的首选。 赛氪网作为一款先…

内容营销专家刘鑫炜:越是赚不到钱,越要加大推广力度

这两天&#xff0c;一位跟我们有长期合作关系的小微企业主老苏问我。 “现在钱这么不好赚&#xff0c;品牌推广应该怎么做&#xff1f;” 我说&#xff1a;“这是好机会&#xff0c;加大投放力度&#xff01;” 老苏很是不解&#xff0c;这时候不开源节流&#xff0c;还要加…

换热器管接头内孔焊

GB/T 151-2014的6.6.4给出了换热管与管板连接内孔焊的四种型式。有文献将前两种称为全部对接&#xff0c;后两种称为准对接。 与强度焊、强度胀、强度焊贴胀相比&#xff0c;内孔焊主要有以下优点&#xff1a;不存在胀管产生的残余应力的问题&#xff1b;换热管与管板管孔之间…

录屏软件哪个好用?分享5款(2024最新)

随着网络时代的发展&#xff0c;电脑的使用频率也越来越高&#xff0c;还有近些年出现的网课、直播等&#xff0c;这让电脑的录屏功能显得更重要。随之而来的录屏软件也越来越多样化&#xff0c;选择一款好的软件是录屏至关重要的环节。 在数字浪潮汹涌的时代&#xff0c;录屏…

[C++][设计模式][迭代器模式]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受 1.动机 在软件构建过程中&#xff0c;集合对象内部结构常常变化各异。但对于这些集合对象&#xff0c;我们希望不暴露其内部结构的同时&#xff0c;可以让外部客户代码透明地访问其中包含的元素&#xff1b; 同时这种”透明遍历“也…

【web APIs】快速上手Day03

目录 Web APIs - 第3天全选文本框案例事件流事件捕获事件冒泡阻止冒泡解绑事件on事件方式解绑addEventListener方式解绑 注意事项-鼠标经过事件的区别两种注册事件的区别 事件委托综合案例-tab栏切换改造 其他事件页面加载事件元素滚动事件页面滚动事件-获取位置页面滚动事件-滚…

五种肉苁蓉属植物叶绿体基因组-文献精读25

Structural mutations of small single copy (SSC) region in the plastid genomes of five Cistanche species and inter-species identification 五种肉苁蓉属植物叶绿体基因组中小单拷贝 (SSC) 区域的结构突变及物种间鉴定 摘要 背景 肉苁蓉属是列当科的重要属类&#xf…

Windows PowerShell 添加新配置文件(打开对应的目录,并执行命令)

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe ./redis-server.exe %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe yarn dev 人工智能学习网站 https://chat.xutongbao.top

谷粒商城篇章10 -- P262-P291/P295-P310 -- 订单服务(支付)【分布式高级篇七】

目录 1 页面环境搭建 1.1 静态资源上传到nginx 1.2 SwitchHosts增加配置 1.3 网关配置 1.4 订单模块基础配置 1.4.1 引入 thymeleaf 依赖 1.4.2 application.yml配置 1.4.3 bootstrap.properties配置 1.4.4 开启nacos注册发现和远程调用 1.5 修改各个页面的静态资源路…

全国WMS厂商大盘点,哪家未来能杀出重围?

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 一、引言 随着物流行业的快速发展&#xff0c;仓储管理作为其重要的一环&#xff0c;正逐步受到越来越多企业的重视。当前&#xff0c;市…

pytorch-ResNet18简单复现

目录 1. ResNet block2. ResNet18网络结构3. 完整代码3.1 网络代码3.2 训练代码 1. ResNet block ResNet block有两个convolution和一个short cut层&#xff0c;如下图&#xff1a; 代码&#xff1a; class ResBlk(nn.Module):def __init__(self, ch_in, ch_out, stride):su…

基于C语言+控制台的学生信息管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、Php、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

绘唐3一键追爆款文刻创作聚星文社

聚星文社是一个中国的文学社交平台&#xff0c;提供了一个让作家和读者相互交流和分享作品的平台。 在聚星文社&#xff0c;作家可以在平台上发布自己的作品&#xff0c;获得读者的阅读和评论&#xff0c;同时也可以与其他作家进行交流与学习。 点击下载即可 读者可以在平台上…

第五届计算机、大数据与人工智能国际会议(ICCBD+AI 2024)

随着科技的飞速发展&#xff0c;计算机、大数据和人工智能等前沿技术已成为推动社会进步的重要力量。为了加强这一领域的学术交流与合作&#xff0c;促进技术创新与发展&#xff0c;第五届计算机、大数据与人工智能国际会议&#xff08;ICCBDAI 2024&#xff09;将于2024年11月…

Linux基础IO操作详解

C文件IO相关接口 fopen函数 pathname: 要打开的文件名字符串mode: 访问文件的模式 模式描述含义“r”读文件不存在失败返回null“r”读写文件不存在打开失败返回null&#xff0c;文件存在则从头开始覆盖现有的数据&#xff08;不会清空数据&#xff09;“w”写文件不存在创建…

蜜雪冰城小程序逆向

app和小程序算法一样 小程序是wasm

并发编程工具集——Lock和Condition(下)(十四)

如何利用两个条件变量快速实现阻塞队列呢&#xff1f; 入队与出队需要同步&#xff0c;用一个锁。一个阻塞队列&#xff0c;需要两个条件变量&#xff0c;一个是队列不空&#xff08;空队列不允许出队&#xff09;&#xff0c;另一个是队列不满&#xff08;队列已满不允许入队&…