Spring 缓存

缓存简介

什么是缓存

缓存是存储在内存中的数据,相比硬盘读写更快。

缓存能做什么

主要就是减轻数据库压力,加快响应速度。

  • 预读取:在系统对外提供服务之前,提前将一部分热点数据从硬盘加载到内存,减少上线时服务器的压力。

  • 延迟写:数据库写入为了保证准确性所以很慢。可以将写入请求先堆积在缓存,之后一次批量写入数据库,可以缓解对数据库频繁修改的压力。只能用于对数据精度要求不高的场景,存在数据丢失的可能。

什么时候使用缓存

**1)业务流量量级以及应用规模:**对于低并发低流量的应用而言,引入缓存并不会带来性能的显著提升,反而会带来应用的复杂度以及极高的运维成本。

  1. 热点数据:每秒几十次以上的访问
  2. 静态数据:很少变化,读远大于写,如几天一变化
在哪里使用缓存

浏览器缓存 --》 CDN缓存 --》 网关(代理)缓存 --》 进程内缓存 --》 进程外缓存 --》 数据库缓存

从网关开始就是程序员自己能控制的了。常用的代理缓存有Nginx,Varnish(大量小文件),Squid(全面但成本高)。

进程内缓存:EhCache。相比于进程外缓存省去网络开销,响应时延更低。但数据存储多份(多个服务节点内)难保持一致性。

进程外缓存有:Redis(数据库结构更多),Memcached(纯kv且数据量大时会快一些,但可能丢失数据,是纯内存的)

使用缓存的弊端
  • 缓存更新
  • 缓存和数据的一致性
  • 缓存雪崩
  • 缓存穿透
  • 缓存并发

Spring 缓存

项目缓存—> Spring cache —> Spring EL表达式 —>

基于注解:
@Cacheable
  • 在方法被调用后,Spring会将返回值缓存起来,下次用同样的参数执行该方法时,直接从缓存取结果,不需要再执行方法。

  • 可以标注在方法上,表示方法支持缓存;可以标注在类上,表示类中所有方法支持缓存。

  • Spring是以键值对的方式缓存方法返回值的。

  • 有三个属性:value、key、condition

    • value:指定Cache名称,可以是多个(value={“cache1”,“cache2”})
    • key:指定返回结果时对应的key。Spring有默认生成key的策略。有提供root对象用于生成key。可以使用Spring EL表达式直接写。
    • condition:指定缓存发生的条件。使用Spring EL表达式来指定,当为true时进行缓存。
@CachePut
  • 不同于@Cacheable可能会不执行方法,@CachePut每次都会执行方法,并且把返回值放入缓存中。
  • 用法与@Cacheable一致。
@CacheEvict
  • 用来清除缓存的注解。可以标注在方法上和类上。
  • 有五个属性:value、key、condition、allEntries、beforeInvocation
    • value、key、condition用法与@Cacheable相似。
    • allEntries:表示是否需要清除缓存中的所有元素,为boolean类型。true的话将忽略指定的key,清除指定cache中的所有元素。
    • beforeInvocation:清除操作默认是在方法执行成功后执行的,如果方法抛出异常未成功返回,则不会清除缓存。此属性为true时,使得清除操作在方法执行前清除缓存中的元素。
@Caching
  • 使得可以在一个类或方法上同时指定多个Cache注解。
  • 有三个属性:cacheable、put和evict,分别对应三个注解。
基于XML配置:
  • <cache:advice 下定义多个 <cache:caching

  • <cache:caching 下定义多个 <cache:cacheable 、<cache:cache-evict 、<cache:cache-put

    <cache:advice id="cacheAdvice" cache-manager="cacheManager">
    
          <cache:caching cache="users">
    
             <cache:cacheable method="findById" key="#p0"/>
    
             <cache:cacheable method="find" key="#user.id"/>
    
             <cache:cache-evict method="deleteAll" all-entries="true"/>
    
          </cache:caching>
    
       </cache:advice>
    
  • 使用 <aop:config> 将<cache:advice 织入spring中。

配置Spring对Cache的支持
  1. 声明对Cache的支持
    1. 基于注解:<cache:annotation-driven/>
    2. 基于xml:即上面的
  2. 配置CacheManager
    1. Spring提供了两种CacheManager的实现。一种是基于Java API的ConcurrentMap,另一种是基于Ehcache。
    2. 配置<bean>即可,略。
键的生成策略
  1. 默认策略

    默认的生成策略是通过KeyGenerator生成的,默认如下:

    1. 如果方法没有参数,则使用0作为key;
    2. 如果方法有一个参数,则使用该参数为key;
    3. 如果方法有多个参数,则使用所有参数的hashCode作为key。

    也可以指定自己的KeyGenerator,配置略。

  2. 自定义策略

    我们通过Spring EL表达式来指定key。

    1. 直接使用 “#参数名” 或者 “#p参数索引”。如 key="#id",key="#p0"

    2. 使用Spring提供的root对象。

      属性名称描述示例
      methodName当前方法名#root.methodName
      method当前方法#root.method.name
      target当前被调用的对象#root.target
      targetClass当前被调用的对象的class#root.targetClass
      args当前方法参数组成的数组#root.args[0]
      caches当前被调用的方法使用的Cache#root.caches[0].name
补充:
  1. 使用@Cacheable不缓存空值。@Cacheable(value = "organCache", unless = "#result == null")
参考资料:
  1. Spring中Cache的使用
  2. Spring EL表达式
  3. 进程内缓存怎么玩
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值