• Spring Cache 笔记


    @(Java ThirdParty)[Spring Cache]

    Spring Cache Abstraction

    简介

      Spring Cache提供了对底层缓存使用的抽象,通过注解的方式使用缓存,减少了对原有的侵入性,通过一个抽象层,分离了不同后端缓存的实现,在不改变代码的前提下,可以切换底层缓存的实现。
      Cache只有应用于幂等性的方法,即同样的输入,返回同样的数据(在数据没有变更时)。
      在多线程的情况下,由Cache底层实现类保存线程安全。

    Cache 两次读取数据流程(第一次miss,第二次hit):

    注解使用说明

    Cacheable

    @Cacheable注解用于指示缓存该方法的返回数据。
    该注解的属性中,需要指定一个name,用于绑定到低层的缓存(比如,底层使用的是CurrentHashMap,那这个name就是用于指示到底是哪个Map,一般来说,一个方法或者类对应一个Map)

    Key Generator

    KeyGenerator用于生成Cache Key,默认提供SimpleKeyGenerator计算方法如下:

    1. 如果没有参数,就返回SimpleKey.EMPTY
    2. 如果有一个参数,就返回该参数实例
    3. 如果有多个方法,就返回一个SimpleKey,该实例包含了所有的参数

    默认提供的Generator使用hashCode以及equals来计算,所以对于复杂的类,需要实现对应的方法。或者也可以通过自定义KeyGenerator来实现。(使用keyGenerator属性来指定)

    除了使用KeyGenerator外,还可以使用key属性来指定(两者只能使用一个,否则会抛异常)

    Key属性

    通过SpEL来生成Key,如:

    @Cacheable(cacheNames="books", key="#isbn")
    public Book findBook(ISBN isbn, boolean check);
    
    @Cacheable(cacheNames="books", key="#isbn.rawNumber")
    public Book findBook(ISBN isbn, boolean check);
    

    Cache Resolution

    CacheResolver

    Sync

      Cache缓存的时候,如果多次同时调用,当没有命中的时候,会直接调用方法计算,这会导致重复计算,以及缓存没有生效,这时就需要采用同步的方式,一个方法调用,其余的在等待。
      可以通过sync=“true”属性来指定(默认为false)

    注:这个特性取决于底层的实现(在Cache Aop读取流程中并没有加锁处理)

    条件式缓存

    当需要在特定参数情况下才缓存的时候,就可以使用。通过condition来计算,如果为true,则缓存,否则不缓存,如:

    @Cacheable(cacheNames="books", condition="#name.length < 32")
    public Book findBook(String name);
    

    SpEL Cache表达式上下文

    CachePut

    @CachePut用于更新缓存

    注:不能和@Cacheable同时使用。

    CacheEvict

    @CacheEvict注解用于淘汰缓存,其中可以通过cacheNames和key属性来淘汰指定的Entry,也可以使用cacheNames和allEntries=true来淘汰掉所有的Entries。

    beforeInvocation属性

    这个属性用于控制是在方法调用前还是调用后再淘汰缓存,如果是调用后,在抛出异常时,则不会淘汰(默认为false)。
      这里也涉及了缓存写淘汰策略。

    Caching

    @Caching用于将多个操作组合起来,如CacheEvict和CachePut组合

    CacheConfig

    类级别的注解,用于定义一些该类的通用配置,可以被方法级别的配置覆盖

    三个层级配置:

    1. 全局配置,CacheManager/KeyGenerator
    2. 类级别配置
    3. 方法级别

    开启Cache注解功能

    @EnableCaching置于@Configuration配置上,或者在XML加入配置:
    <cache:annotation-driven />

    注:如果把<cache:annotation-driven />放在WebApplicationContext中的话,那就只会扫描controllers,而不是services

    Cache存储配置

    Spring Cache提供了多个不同的存储集成,使用的时候,只需要定义对应的CacheManager即可。

    如下:

    1. JDK ConcurrentMap-based Cache.(使用ConcurrentHashMap作为底层存储)
    2. EhCache-base Cache
    3. Caffeine Cache
    4. Guava Cache
    5. GemFire-base Cache
    6. JSR-107 Cache

    Spring Cache可以配置多个Cache实现(使用CompositeCacheManager
    注:如果上述的集成都不满足,则可以自定义实现,通过实现CacheManagerCache即可。

    Cache Aop执行流程

    在下述的所有操作中,都没有同步或者锁的操作,即如果要实现相同query防止重复执行,则需要底层缓存库支持。
    这里会有并发问题,举个例子:查询个人信息。当缓存没有命中的时候,会执行实际的方法,然后将结果缓存起来。在这中间,如果作了更新的操作,并且执行完CacheEvict,然后上述查询结果再缓存起来,就会导致读取到脏数据。所以缓存的时间也需要控制好。

    参考资料

    • spring-framework-reference - ch36
    • spring cache 源码
  • 相关阅读:
    20165334 我期待的师生关系
    20165228 我期望的师生关系
    20165232 预备作业3 Linux安装及学习
    20165232 学习基础和c语言基础调查
    20165232 我期望的师生关系
    20165320 第一周学习总结
    20165320 预备作业3 :Linux安装及命令入门
    20165320 预备作业2:技能学习心得与C语言学习
    20165320 我期望的师生关系
    20165203 学习基础和C语言基础调查
  • 原文地址:https://www.cnblogs.com/jabnih/p/6501645.html
Copyright © 2020-2023  润新知