SpringCache分布式緩存學習


Spring Cache

簡介

  • Cache接口為緩存的組件規范定義,包含緩存的各種操作集合
  • Cache接口下Spring提供了各種xxcache的實現;如RedisCache,EhCacheCache,ConcurrentMapCache等;
  • 每次調用需要緩存功能的方法時,Spring會檢查檢查指定參數的指定的目標方法是否已經被調用過;如果有就直接從緩存中獲取方法調用后的結果,如果沒有就調用方法並緩存結果后返回給用戶。下次調用直接從緩存中獲取。

image-20200630140504269

引入依賴

<!--引入spring cache-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>

配置

spring.cache.type=redis

開啟注解

@EnableCaching

常用注解

  • @Cacheable:觸發操作將數據保存到緩存中,參數value指cacheName
  • @CacheEvict:觸發操作將數據從緩存中刪除(運用於失效模式)
  • @CachePut:不影響方法執行更新(運用於雙寫模式)
  • @Caching:組合以上多個操作
  • @CacheConfig:再類級別上共享有關緩存的配置

默認配置

  • key自動生成:緩存名字::SimpleKey[]
  • value默認是jdk序列化
  • 默認ttl時間:-1
  • 默認查詢數據如果緩存中存在,則不再調用方法,直接將緩存中命中的數據返回

自定義配置

  • 指定key:

    • key默認為spel表達式:#root.method.name指用方法名作為key保存在緩存中

      • @Cacheable(value="category",key="#root.methodName")

      image-20200630163456360

    • key是字符串的話額外要加單引號(默認會做表達式解析)

      • @Cacheable(value=“category”,key=“‘catalogJson-cache’”)
    • 緩存key表達為:

      • 指定前綴(前提:有指定前綴並且開啟了使用前綴)+指定key名

        image-20200630154750496

      • 推薦: 默認前綴(緩存名字,前提:允許使用前綴,沒有指定前綴):: key名字 (並且保存在以指定的緩存名字namespace下,樹形結構顯示)

        image-20200630154927208

      • key名字(前提:無前綴)

        image-20200630155220833

  • 指定其他信息

    spring.cache.type=redis
    #指定ttl,單位必需(m,s,h,d)
    spring.cache.redis.time-to-live=3600000m 
    spring.cache.redis.key-prefix=CACHE_
    spring.cache.redis.use-key-prefix=true
    #默認允許緩存空值->解決緩存穿透問題,暫時性保存null給其他並發線程返回,以保護數據庫
    spring.cache.redis.cache-null-values=true 
    
  • 將value改為json格式(默認Jdk序列化器)

    Redis序列化器:

image-20200630150852638

@EnableCaching
@Configuration
public class MyCacheConfig {

    @Bean
    RedisCacheConfiguration cacheConfiguration(CacheProperties cacheProperties){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //entryTtl方法返回一個新的RedisCacheConfiguration對象覆蓋原有對象,其他屬性方法也是如此
        //cacheConfig=cacheConfig.entryTtl()
        //config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        //整合配置文件(不整合配置文件所配置的內容不生效)
        //取出配置信息
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();

        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }

        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }

        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }

        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }

        return config;
    }

}

更新緩存數據

1、@CacheEvict

用於緩存失效模式:修改后刪除該緩存信息

@CacheEvict 是用來標注在需要清除緩存元素的方法或類上的

  • 單個刪除:

    在方法上標注(一般為保存,更新方法)

    @CacheEvict(value="category",key="'getLevel1Categories'")

    表示一旦執行該方法則會從緩存中刪除對應的key

  • 批量刪除:

    1. @Caching批量操作

      @Caching(evict = {
              @CacheEvict(value="category",key="'getLevel1Categories'"),
              @CacheEvict(value="category",key="'getCatalogJson'")
      })
      
    2. 刪除整個namespace(一般統一類型的數據存放在同一個分區中)

      @CacheEvict(value="category",allEntries = true)

      • allEntries:默認為false,當其為true時表示清除緩存中的所有元素
      • beforeInvocation:默認是false,表示執行方法后刪除(當方法如果因為拋出異常而未能成功返回時也不會觸發清除操作),當指定該屬性值為true時,Spring會在調用該方法之前清除緩存中的指定元素。

2、@CachePut

用於緩存雙寫模式:修改后立即寫入緩存

@CachePut標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行方法,並將結果(方法返回值)存入指定的緩存中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM