| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 项目总结--3(@Cacheable的使用方法和使用技巧) -> 正文阅读 |
|
[Java知识库]项目总结--3(@Cacheable的使用方法和使用技巧) |
在项目中缓存是经常要用到的,之前用的缓存都是Redis做为缓存的,但是在实际工作中用到缓存的地方是非常多,但是又不是只有Redis这一种操作,实际中可以用到的缓存还有SpringBoot,中的@Cacheable这个注解可以充当Spring的缓存,还有Spring整合Redis做缓存的,之前一直对缓存的实际用处云里雾里的不清楚,其实在实际落地过程中最简单的应用就是在获取省市区街道这些数据的时候需要做缓存,那这些做缓存存到哪里,怎样操作最简单,毋庸置疑,使用@Cacheable操作是最简单的,操作的时候只用上注解的就可以了,但是如果数据库修改了,缓存还是以前的数据怎么办,这个时候就需要对缓存进行删除,然后再重新加载缓存就可以了,这个是我下面写的代码
就上面的整个代码非常的简单,其实主要还是针对对应的SpringBoot整合之后的@Cacheable的缓存操作,最后的@CacheEvict的操作其实是修改缓存的意思的值,这个我描述一下我的简单理解意思,可以理解为,@Cacheable作为缓存之后,中间的cacheNames="XX"这个其实是缓存的名字,后面的key可以定义为缓存的键,#cityId,这种形式,因为每次给方法中传入的形参都不一样,导致这个key都不一样,所以每次都会进入到方法中,当如果读取到同样的值的时候,他就不会在执行这个方法了,大概的意思就是第二次在加载同样的方法,并且是同样的入参的时候,就不会执行查询语句了; 总结:使用场景:比如网站首页的文章列表、电商网站首页的商品列表、微博等社交媒体热搜的文章等等,当大量的用户都去请求同样的接口,同样的数据,如果每次都去查数据库,那对数据库来说是一个不可承受的压力。通常是把高频的查询进行缓存,我们称它为“热点 使用
key的不规范使用,会造成缓存混淆,造成不可预测的后果
这里可指定key生成策略,用来覆盖spring默认的生成策略。spring默认的生成策略以方法参数值为key,会造成不同方法,如果入参参数值一样得到的缓存值不一致的情况,因此框架中拼接了key的前缀 注解使用,主要使用到@CacheConfig和@Cacheable注解@Cacheable?这个注解「一般用在查询方法上」。
@CacheEvict?这个注解会清空指定缓存。「一般用在更新或者删除的方法上」。
注解使用注意事项
使用缓存带来的问题使用缓存会带来许多问题,尤其是高并发下,包括缓存穿透、缓存击穿、缓存雪崩、双写不一致等问题。
但使用缓存通常会存在缓存中的数据和数据库中不一致的问题,尤其是调用第三方接口,你不会知道它什么时候更新了数据。但使用缓存的业务场景很多时候并不需求数据的强一致,比如首页的热点文章,我们可以让缓存一分钟失效,这样就算一分钟内,不是最新的热点排行也没关系。 补充补充一些关于Cacheable的知识的 @Cacheable 1、方法运行之前,先去查询Cache(缓仔组件),按照cacheNames指定的名字获取; 2.去Cache中查找缓存的内容,使用一个key,默认就是方法的参数; springCache删除多个Key的缓存,@CacheEvict 删除多个演示代码:
分析:要解释下面的refrsh()上面的方法注解,其实可以先看一下,对应缓存中现在存值的状况在进行实际的情况进行分析,会更加的简单明了,在执行对应的每一个方法的时候,进行拆解的过程中一直不太明白,cacheNames="cityId:info"key="#cityId"这到底是什么意思,当去Redis中看了缓存的分布一下子就明白了,在我执行了若干的查询之后,上面的查询的结果就会通过查询的返回值放到缓存中,可以看到cacheNames="cityId:info"key="#cityId",它的实际含义cacheNames其实就类似一个文件夹的层级,key:cache:cityId:info:ccc08c34d157430fb595e10bcd448786,对应的value就是我后面查询出来的值,如果不写key 上面可以清楚的看到了端倪,如果不写key值,那他这个地方默认的key就是参数的入参的key ? ? ?通过分析了这个对应的@CacheNames 之后他用:进行隔离其实还是为了更好的组合对应的key ,spring默认的生成策略以方法参数值为key,会造成不同方法,如果入参参数值一样得到的缓存值不一致的情况,因此框架中拼接了key的前缀 key:cache:cityId:info:ccc08c34d157430fb595e10bcd448786,对应的 后面的这个ccc08c34d157430fb595e10bcd448786其实就是对应的入参参数 下面对整个SpringBoot中的@Cache相关的操作做过总结1? ? ?基于注解的支持?????? Spring为我们提供了几个注解来支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素。下面我们将来详细介绍一下Spring基于注解对Cache的支持所提供的几个注解。 ? 这里其实主要学习几个注解:@CachePut、@Cacheable、@CacheEvict、@CacheConfig。 @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,这个value
这个需要主要的是在先有的框架中在进行开发的时候是@Cacheable(cacheNames="XX")这个里面的写法更加规范一些,其实用value也是可以替代里面的cachNames的 @CachePut @CachePut 的作用 主要针对方法配置,能够根据方法的返回值对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用,在其他地方写的是根据方法的请求参数对其结果进行缓存,实际是按方法返回值进行缓存的,这里我就遇到了一个坑,我开始的时候是在Mybatis的Mapper层进行缓存的,如下面的代码。但是缓存到Redis的是Null值,今天看了一博友的博客,交流了一下,才知道它缓存的是方法的返回值,如果把下面update的返回值该为int,在redis中保存的是int类型,报的错误是int无法转换成User对象。
@CachEvict ?@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheConfig ? ? ? 所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法写别的名字,那么依然以方法的名字为准。 1.1????@Cacheable?????? @Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,至于键的话,Spring又支持两种策略,默认策略和自定义策略,这个稍后会进行说明。需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的。@Cacheable可以指定三个属性,value、key和condition。 1.1.1??value属性指定Cache名称value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。
1.1.2??使用key属性自定义key?????? key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,至于默认策略会在后文单独介绍。 ???????自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例。 ?例子看下面 1.1.3??condition属性指定发生的条件???????有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。
1.2?????@CachePut???????在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
1.3?????@CacheEvict?????? @CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;condition表示清除操作发生的条件。下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。 1.3.1??allEntries属性?????? allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。
1.3.2??beforeInvocation属性???????清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
???????其实除了使用@CacheEvict清除缓存元素外,当我们使用Ehcache作为实现时,我们也可以配置Ehcache自身的驱除策略,其是通过Ehcache的配置文件来指定的。 其他知识点补充1. 基于注解的支持Spring为我们提供了几个注解来支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素。下面我们将来详细介绍一下Spring基于注解对Cache的支持所提供的几个注解。 1.1 @Cacheable@Cacheable可以标记在一个方法上,也可以标记在一个类上。
对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,至于键的话,Spring又支持两种策略,默认策略和自定义策略,这个稍后会进行说明。 1.1.1 value属性指定Cache名称alue属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。
1.1.2 使用key属性自定义keykey属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,至于默认策略会在后文单独介绍。 自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例。
除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。
当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:
1.1.3 condition属性指定发生的条件有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。
1.2 @CachePut在支持Spring Cache的环境下
1.3 @CacheEvict@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。 1.3.1 allEntries属性allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。
1.3.2 beforeInvocation属性清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
1.4 @Caching@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:00:52- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |