Spring cache缓存应用与总结

前言

现在项目中大家基本都会使用到缓存,本地缓存,Spring引入缓存,或者是直接使用三方缓存的API进行缓存的操作,基本离不开这三种,如果项目没有使用springboot的话,有些配置还需要自己手动去引入,因为没有与Spring进行自动集成,今天我们讨论的是在springboot的基础上进行缓存的使用,以redis和Spring默认缓存为例进行说明

Spring的缓存抽象

Spring Cache 只负责维护抽象层,具体的实现由自己的技术选型来决定,将缓存处理和缓存技术解除耦合。
使用Spring缓存抽象时我们需要关注以下两点:

  • 确定那些方法需要被缓存
  • 缓存策略

重要接口

org.springframework.cache.Cache
  • 缓存抽象的规范接口,缓存实现有:RedisCache、EhCache、 ConcurrentMapCache等,具体的数据存储操作都是在这里进行实现
org.springframework.cache.CacheManager
  • 缓存管理器,管理Cache的生命周期

SpringCache源码加载

在这里插入图片描述
到这一步就已经清楚了,自动按需装配;自己当时看的时候有一个疑问,echche和redis能一起使用吗,按照spring boot目前的方式是不行的,因为他们都实现了CacheManager这个接口,加载的时候,都有ConditionalOnMissingBean({CacheManager.class})这个注解,所以注定只能注入一个缓存管理器,然后加载自己对应的cache,再有个疑问,为什么Spring有默认的缓存管理,是哪一个,为什么?看下边源代码,入口方法是:
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.CacheConfigurationImportSelector
在这里插入图片描述
在这里插入图片描述
MAPPINGS这里边就是springboot实现缓存自动装配的配置类,就以redis和simple为例看下
在这里插入图片描述
在这里插入图片描述

观察SimpleCacheConfiguration这个类,上边的注解判断条件并没有额外外部类的限制,不需要额外引入外部的依赖,但是像REDIS,CAFFEINE,EHCACHE,它们都是需要额外引入依赖的,所以Spring默认缓存加载是SIMPLE;

建议配置文件加上(spring.cache.type=redis),可以更加清晰准确的加载到对应的配置信息,当然如果你配置的是spring.cache.type=simple,虽然你引入了redis,但是并不会生效,原因自己看下@Conditional({CacheCondition.class}),这个实现就知道了。

再谈一下规范
使用@Cacheable,如果是对象的话,需定义key字段,比如

@Cacheable(value="yyy",cacheManager = "redisCacheManager",key="#person.getId()")

value属于外部的索引,key属于内部的索引,不管是任何的缓存方式,整体结构都可以理解为双map形式

获取缓存的源码跟踪

org.springframework.cache.interceptor.AbstractCacheResolver#resolveCaches,这个位置打断点
在这里插入图片描述
在这里插入图片描述
org.springframework.cache.concurrent.ConcurrentMapCacheManager#getCache在这里插入图片描述
如果是redis的话,是看这个org.springframework.cache.support.AbstractCacheManager#getCache
在这里插入图片描述
最后再补充一点:
在这里插入图片描述
这个注解相当于你有多个缓存管理器的实现,但是Spring需要你有一个默认的实现,这个注解就是干这用的;若不指定CacheManager,会从spring容器中查找是否有存在CacheManager,若存在一个CacheManager会使用该CacheManager,若存在多个CacheManager则会抛出异常,即必须指定一个。

异常信息:No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary (or give it the name 'cacheManager') or declare a specific CacheManager to use, that serves as the default one.

再补充一个问题,关于@cacheable注解中(value=“cacheName”,key="#id"),value不起作用的解释,印象中应该是用于key的分组,类似于上hset的方式,其实不是,可以自己实验下,解释如下:

value属性,确实是指定了缓存的名称,但是并没有强行将value不同的缓存值加以区分(这个是有道理的,因为有些时候,需要把不同业务属性的实体存在一个缓存里,这种情况肯定是有的,所以如果强行通过value区分的话,上述需求反而实现不了了)
注:从Spring 4.1开始,value缓存注释的属性不再是强制性的,新定义的一个实行cachename是value的别名
参考链接:https://blog.csdn.net/a1035434631/article/details/100563706

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值