当前位置:首页 > 数码 > Cache-让你的代码更香-缓存注解的最佳通常-Spring (cache文件夹可以删除吗)

Cache-让你的代码更香-缓存注解的最佳通常-Spring (cache文件夹可以删除吗)

admin6个月前 (05-06)数码22

作者最近在开发公司名目时经常使用到缓存,并在翻看先人代码时,看到了一种关于@Cacheable注解的自定义缓存有效期的处置打算,觉得比拟适用,因此作者自己拓展完善了一番后分享给各位。

缓存注解的最佳通常

Spring缓存惯例性能

SpringCache框架给咱们提供了@Cacheable注解用于缓存方法前往内容。然而@Cacheable注解不能定义缓存有效期。这样的话在一些须要自定义缓存有效期的场景就不太适用。

依照SpringCache框架给咱们提供的RedisCacheManager成功,只能在全局设置缓存有效期。这里给大家看一个惯例的CacheConfig缓存性能类,代码如下,

@EnableCaching@ConfigurationpublicclassCacheConfigextendsCachingConfigurerSupport{...privateRedisSerializer<String>keySerializer(){returnnewStringRedisSerializer();}privateRedisSerializer<Object>valueSerializer(){returnnewGenericFastJsonRedisSerializer();}publicstaticfinalStringCACHE_PREFIX="crowd:";@BeanpublicCacheManagercacheManager(RedisConnectionFactoryredisConnectionFactory){//性能序列化(处置乱码的疑问)RedisCacheConfigurationconfig=RedisCacheConfiguration.defaultCacheConfig()//设置key为String.serializeKeysWith(RedisSerializationContext.SerializationPr.fromSerializer(keySerializer()))//设置value为智能转Json的Object.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())).computePrefixWith(name->CACHE_PREFIX+name+":").entryTtl(Duration.ofSeconds(600));RedisCacheWriterredisCacheWriter=RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisConnectionFactory));returnnewRedisCacheManager(redisCacheWriter,config);}}

这外面繁难对RedisCacheConfiguration缓存性能做一下说明:

那么经常使用如上性能生成的Redis缓存key称号是什么样得嘞?这里用开源名目crowd-admin的ConfigServiceImpl类下getValueByKey(Stringkey)方法举例,

@Cacheable(value="configCache",key="#root.methodName+'_'+#root.args[0]")@OverridepublicStringgetValueByKey(Stringkey){QueryWrer<Config>wrapper=newQueryWrapper<>();wrapper.eq("configKey",key);Configconfig=getOne(wrapper);if(config==null){returnnull;}returnconfig.getConfigValue();}

口头此方法后,Redis中缓存key称号如下,

图片

TTL过时期间是287,跟咱们全局设置的300秒基本是分歧的。此时假设咱们想把getValueByKey方法的缓存有效期独自设置为600秒,那咱们该如何操作嘞?

@Cacheable注解自动是没有提供无关缓存有效期设置的。想要独自修正getValueByKey方法的缓存有效期只能修正全局的缓存有效期。那么有没有别的方法能够为getValueByKey方法独自设置缓存有效期嘞?当然是有的,大家请往下看。

自定义MyRedisCacheManager缓存

其实咱们可以经过自定义MyRedisCacheManager类承袭SpringCache提供的RedisCacheManager类后,重写createRedisCache(Stringname,RedisCacheConfigurationcacheConfig)方法,代码如下,

publicclassMyRedisCacheManagerextendsRedisCacheManager{publicMyRedisCacheManager(RedisCacheWritercacheWriter,RedisCacheConfigurationdefaultCacheConfiguration){super(cacheWriter,defaultCacheConfiguration);}@OverrideprotectedRedisCachecreateRedisCache(Stringname,RedisCacheConfigurationcacheConfig){String[]array=StringUtils.split(name,"#");name=array[0];//解析@Cacheable注解的value属性用以独自设置有效期if(array.length>1){longttl=Long.parseLong(array[1]);cacheConfig=cacheConfig.entryTtl(Duration.ofSeconds(ttl));}returnsuper.createRedisCache(name,cacheConfig);}}

MyRedisCacheManager类逻辑如下,

接着咱们修正下CacheConfig类的cacheManager方法用以经常使用MyRedisCacheManager类。代码如下,

@BeanpublicCacheManagercacheManager(RedisConnectionFactoryredisConnectionFactory){returnnewMyRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),defaultCacheConfig());}privateRedisCacheConfigurationdefaultCacheConfig(){returnRedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())).computePrefixWith(name->CACHE_PREFIX+name+":").entryTtl(Duration.ofSeconds(600));}

最后咱们修正下@Cacheable注解经常使用形式,在原有value属性的configCache值后参与#600,独自标识缓存有效期。代码如下,

@Cacheable(value="configCache#600",key="#root.methodName+'_'+#root.args[0]")@OverridepublicStringgetValueByKey(Stringkey){...}

看下getValueByKey方法生成的Redis缓存key有效期是多久。如下,

图片

OK,看到是590秒有效期后,咱们就功败垂成了,宿愿本文能对大家有所协助


Spring本地缓存的使用方法

我们现在在用的Spring Cache,可以直接看Spring Boot提供的缓存枚举类,有如下这些:

EhCache:一个纯Java的进程内缓存框架,所以也是基于本地缓存的。(注意EhCache2.x和EhCache3.x相互不兼容)。 Redis:分布式缓存,只有Client-Server(C\S)模式,Java一般使用Jedis/Luttuce来操纵。 Hazelcast:基于内存的数据网格。虽然它基于内存,但是分布式应用程序可以使用Hazelcast进行分布式缓存、同步、集群、处理、发布/订阅消息等。 Guava:它是Google Guava工具包中的一个非常方便易用的本地化缓存实现,基于LRU(最近最少使用)算法实现,支持多种缓存过期策略。在Spring5.X以后的版本已经将他标记为过期了。 Caffeine:是使用Java8对Guava缓存的重写版本,在Spring5中将取代了Guava,支持多种缓存过期策略。 SIMPLE:使用ConcurrentMapCacheManager,因为不支持缓存过期时间,所以做本地缓存基本不考虑该方式。

关于分布式缓存,我们需要后面会专门讨论Redis的用法,这里只看本地缓存。性能从高到低,依次是Caffeine,Guava,ConcurrentMapCacheManager,其中Caffeine在读写上都快了Guava近一倍。

这里我们只讨论在Spring Boot里面怎么整合使用Caffeine和EhCache。

主要有以下几个步骤:

1)加依赖包:

2)配置缓存: 这里有两种方法,通过文件配置或者在配置类里面配置,先看一下文件配置,我们可以写一个properties文件,内容像这样:

然后还要在主类中加上@EnableCaching注解:

另外一种更灵活的方法是在配置类中配置:

应用类:

测试类:

导入依赖包,分为2.x版本和3.x版本。 其中2.x版本做如下导入:

3.x版本做如下导入:

导包完成后,我们使用JCacheManagerFactoryBean + 的方式配置:

参考资料:

spring@cacheable查询很慢

题主是想询问“spring@cacheable查询很慢的原因”,原因是:1、缓存策略不当:缓存策略的选择直接影响到缓存的效率,如果选择的策略不当,例如缓存时间过长或者缓存的数据量过大,会导致缓存效率低下,反而降低了系统性能。 建议根据具体业务需求选择合适的缓存策略。 2、缓存命中率低:命中率低即缓存中没有需要查找的数据,需要重新查询数据库,这样就会导致查询速度慢。 建议在使用@Cacheable注解时,设置合适的缓存Key,保证缓存命中率。 3、缓存数据量过大:如果缓存数据量过大,会导致缓存的查找和更新效率降低,建议对缓存进行分段管理,分别缓存不同区间的数据,减小缓存数据量。 4、缓存服务器性能问题:如果缓存服务器性能较差,也会导致查询缓存数据较慢,建议对缓存服务器进行优化或更换性能更好的服务器。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Spring

“Cache-让你的代码更香-缓存注解的最佳通常-Spring (cache文件夹可以删除吗)” 的相关文章

比如每日有大量用户访问和数据替换-服务器的带宽需求与网站的访问量密切相关-那么就须要更大的带宽来满足需求-访问量-假设你的网站流量大 (比如每日有大事的句子)

比如每日有大量用户访问和数据替换-服务器的带宽需求与网站的访问量密切相关-那么就须要更大的带宽来满足需求-访问量-假设你的网站流量大 (比如每日有大事的句子)

SpringBeanDefinition元信息定义形式 BeanDefinition是一个蕴含Bean元数据的对象。它形容了如何创立Bean实例、Bean属性的值以及Bean之间的依赖相关。...

b-b-核心原理拆解与源码分析-2.0-Spring-Boot-深度实践 (核心b类期刊有哪些)

b-b-核心原理拆解与源码分析-2.0-Spring-Boot-深度实践 (核心b类期刊有哪些)

SpringBoot是一个基于Spring的轻量级框架,它简化了Spring应用程序的创建过程,使得开发者能够快速搭建一个可运行的应用程序。随着SpringBoot2.0版本的发布,其功能和性能得...

Security权限控制框架入门指南-Spring (security)

Security权限控制框架入门指南-Spring (security)

在罕用的后盾治理系统中,通常都会有访问权限控制的需求,用于限度不同人员关于接口的访问才干,假设用户不具有指定的权限,则不能访问某些接口。 本文将用waynboot-mall名目举例,给大家引...

6-Spring-提供的四种弱小工具-远程接口调用神器 (6sp日常使用还能用多久)

6-Spring-提供的四种弱小工具-远程接口调用神器 (6sp日常使用还能用多久)

1.引见 Spring6是一个十分弱小的框架,它提供了许多工具和接口来简化远程接口调用。其中,WebClient、RestTemplate、HTTPInterface和RestClient是...

Spring-Webflux-Boot-虚构线程性能逊色于-深化比较 (springboot)

Spring-Webflux-Boot-虚构线程性能逊色于-深化比较 (springboot)

早上看到一篇关于SpringBoot虚构线程和Webflux性能对比的文章,感觉还不错。内容较长,抓重点给大家引见一下这篇文章的外围内容,繁难大家极速浏览。 测试场景 作者驳回了一个尽...

揭秘-的暗藏技艺-AOP-从概念到实用场景-Spring (神秘丂丂是什么意思)

揭秘-的暗藏技艺-AOP-从概念到实用场景-Spring (神秘丂丂是什么意思)

环境:Spring5.3.23 1.引见 当天看Spring文档看到这么一个常识点《ControlFlowPointcuts》都不好翻译 官网原文: Springcontr...

Spring-Boot-Starter原理详解-b-b (springernature)

Spring-Boot-Starter原理详解-b-b (springernature)

SpringBoot Starter 是一种包含了一组特定功能和依赖关系的依赖项,旨在为特定的应用程序场景提供快速集成和开箱即用的功能。主要用于将常用的功能模块打包成一个可重用的依赖项,开发者只需...

容器启动有效的交互-Spring-如何利用-框架提供的才干-让-Bean-深化了解并与-Spring (容器启动过程)

容器启动有效的交互-Spring-如何利用-框架提供的才干-让-Bean-深化了解并与-Spring (容器启动过程)

Spring有一个特点,就是创立进去的Bean对容器是无感的,一个Bean是怎样样被容器从一个Class整成一个Bean的,关于Bean自身来说是不知道的,当然也不须要知道,也就是Bean对容器的...