91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Spring中對抽象進行緩存

發布時間:2021-04-07 16:50:37 來源:億速云 閱讀:180 作者:Leah 欄目:編程語言

怎么在Spring中對抽象進行緩存?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

Spring緩存抽象概述

Spring框架自身并沒有實現緩存解決方案,但是從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供對緩存功能的聲明,能夠與多種流行的緩存實現集成。

Cache接口為緩存的組件規范定義,包含緩存的各種操作集合;

Cache接口下Spring提供了各種xxxCache的實現:如RedisCache,EhCacheCache , ConcurrentMapCache等;

CacheManager接口為緩存管理器規范,簡單來說就是用于存放cache,Spring默認也提供了一些列管理器的實現。

Spring緩存抽象提供了5個注解用來聲明緩存規則:

@Cacheable:能夠根據方法的請求參數對其結果進行緩存,多用于查詢

@CachePut: 執行方法,并緩存結果

@CacheEvict:清空緩存

@Caching:能夠同時應用多個緩存注解功能

@CacheConfig: 用于抽取緩存的公共配置(類級別)

以上5個注解除了@CacheConfig注解是類級別的注解,其余4個注解在類和方法上均可以使用,作用在類上表示對該類下所有方法生效,作用的方法上只對該方法生效,且只能用于public修飾的符方法,protected或者private修飾的方法不適用。

@Cacheable注解

@Cacheable注解的作用是Spring在調用該方法之前,首先在緩存中查找方法的返回值,默認的key是根據參數值生成,如果存在,直接返回緩存中的值,否則執行該方法,并將返回值保存到緩存中

@Cacheable運行流程:

  1.方法運行之前,先去查詢Cache(緩存組件),按照cacheNames指定的名字獲取;

           (CacheManager先獲取相應的緩存),第一次獲取緩存如果沒有Cache組件會自動創建。

  2.去Cache中查找緩存的內容,使用一個key,默認就是方法的參數值;

           key是按照某種策略生成的;默認是使用keyGenerator生成的,              

     Spring默認加載的是SimpleCacheManage,SimpleKeyGenerator生成key的默認策略是:

                       如果沒有參數;key=new SimpleKey()

                       如果有一個參數:key=參數的值

                       如果有多個參數:key=new SimpleKey(params)

  3.沒有查到緩存就調用目標方法;

  4.將目標方法返回的結果,放進緩存中

@Cacheable屬性說明:

  1.acheNames/value:該屬性值必須提供,指定緩存組件的名字,將方法的返回結果放在哪個緩存中,是數組的方式,可以指定多個緩存;

      如:cacheNames = "product"或者cacheNames = {"product1","product2"}

  2.key:緩存數據使用的key,不指定key則默認是使用方法參數的值該屬性值支持SpEL表達式

       3.cacheManager:指定緩存管理器;或者cacheResolver指定獲取解析器

       4.condition:指定符合條件的情況下才緩存

  5.unless:否定緩存;當unless指定的條件為true,方法的返回值就不會被緩存;可以獲取到結果進行判斷

                  unless = "#result == null"

                   unless = "#a0==2":如果第一個參數的值是2,結果不緩存;

  6.sync:是否使用異步模式

使用示例:

@Cacheable(cacheNames = "product")// 默認key為參數,多個參數SimpleKey [arg1,arg2]
//@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'")
//@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")
//@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'",condition="#a0>10",unless = "#a0==11") //帶條件的緩存滿足condition=true緩存,滿足unless=true則不緩存 
public Product getProductById(Long id){
  Product product =productMapper.getProductById(id);
  System.out.println(product);
  return product;
}
//指定key屬性值
@Cacheable(cacheNames ="product", key="#id")  //”#+參數名”的形式,直接使用參數名
//或者
//@Cacheable(cacheNames ="product", key="#a0")  //”#a+參數位置”的形式
  public Product getProductById(long id) {
   xxxx
  }
@Cacheable(cacheNames ="product", key="# productcondition.productId")  
//或者
//@Cacheable(cacheNames ="product", key="#a0.productId")  
  public Product getProduct (Product productcondition) {
   xxxx
  }

自定義Key生成器

除了通過SPEL表達式之外,還可以通過自定義key生成器的方式,Spring緩存模塊提供了org.springframework.cache.interceptor.KeyGenerator接口用于緩存key的生成聲明,因此我們可以自定義一個MyKeyGenerator類并實現了KeyGenerator接口 ,使用如下:

@Configuration
public class MyCacheConfig {
  @Bean("myKeyGenerator")
  public KeyGenerator keyGenerator(){
    return new KeyGenerator(){
      @Override
      public Object generate(Object target, Method method, Object... params) {
        return method.getName()+"["+ Arrays.asList(params).toString()+"]";
      }
    };
  }
}

該方法測試用,關于緩存key的生成方式,網上有很多種策略。

使用時只需要修改注解的key屬性即可:

 @Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")

 @CachePut

@CachePut注解的作用簡單的說一句話:既調用方法,又緩存數據。@cachePut和@Cacheable兩個注解都可以用于填充緩存,但使用上略有點差異,@Cacheable注解的執行流程是先在按key在緩存中查找,存在則返回,不存在則執行目標方法,并緩存目標方法的結果。而@CachePut并不會檢查緩存,總是先執行目標方法,并將目標方法的結果保存到緩存中。實際中比如執行到更新操作時,則希望將最新的數據更新到緩存,如果該方法返回異常,將不再執行保存緩存的邏輯。

@CachePut屬性說明

@CachePut注解屬性與@CachePut類似,并沒有增加其他屬性

使用示例:

@CachePut(value="product",key = "#result.productId",condition = "#result!=null")
public Product updateProduct(Product product){
  int count = productMapper.updateProduct(product);
  System.out.println("影響行數:"+count);
  if(count>0){
    return product;
  }else{
    return null;
  }
}

@CacheEvict注解

該注解的作用根據指定的key或者是allEntries屬性值移除緩存中特性的鍵值對。

@CacheEvict屬性說明

與@Cacheable相比@CacheEvict注解提供了另外兩個屬性:

1.allEntries:表示是否清空所有緩存內容,默認false,如果該值為true則清空指定cacheNames緩存塊下所有內容,如果指定了allEntries為true,那么再zhidingkey值將沒有意義

2.beforeInvocation:是否在執行方法前請空緩存,默認值為false,如果該值為true則在調用目標方法前執行清空緩存,為false的情況下,如果目標方法拋出異常,則不再執行清空緩存邏輯

示例:

 //@CacheEvict(value="product",key="#id")
 //@CacheEvict(value="product",allEntries = true) //清楚所有緩存
 @CacheEvict(value="product",allEntries = true,beforeInvocation = true) //清楚所有緩存
 public boolean deleteProductById(Long id) {
   productMapper.deleteProductById(id);
   return true;
 }

@Caching注解

該注解是一個分組注解,作用是可以同時應用多個其他注解,該注解提供了3個屬性cacheable,put,evict分別用于組合@Cacheable、@CachePut、@CacheEvict三個注解

使用示例:

@Caching(
     cacheable = {@Cacheable(value="product",key="#productName")},
     put = {
         @CachePut(value="product",key="#result.productId"),
         @CachePut(value="product",key="#result.productName")
     }
 )
 public Product getProductByName(String productName){
   Product product =productMapper.getProductByName(productName);
   return product;
 }

當@Cacheing同時含有CachePut注解和Cacheable注解時,仍然會先執行目標方法。(并不是按@Cacheable的執行過程,先檢查緩存,存在則返回)

@CacheConfig

是一個類級別的注解,允許共享緩存的名稱、KeyGenerator、CacheManager 和CacheResolver

示例:

@Service
 @CacheConfig(cacheNames = "product")
 public class ProductService {
 }

在類上使用該注解,指定cacheNames屬性值,則類中方法上的注解將默認繼承了該屬性值,如果方法上注解使用和了@CacheConfig向同的屬性,則以方法上的為準。

 @Service
 @CacheConfig(cacheNames = "product")
 public class ProductService {
   @Autowired
   private ProductMapper productMapper; 
   @Cacheable(cacheNames = "product1",key = "#root.methodName+'['+#id+']'")
   public Product getProductById(Long id){
     Product product =productMapper.getProductById(id);
    System.out.println(product);
    return product;
   }
 }

上面@Cacheable和@CacheConfig都指定了屬性值cacaeNames,實際以方法上注解指定的為準。

Spring緩存抽象的關鍵原理就是使用spring AOP,通過切面實現了在方法調用前、調用后獲取方法的入參和返回值,進而實現了緩存的邏輯。

看完上述內容,你們掌握怎么在Spring中對抽象進行緩存的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

襄汾县| 广宗县| 高雄市| 乌审旗| 美姑县| 高邑县| 莱西市| 南充市| 金堂县| 天门市| 大洼县| 刚察县| 宜州市| 武川县| 茶陵县| 晋州市| 芷江| 长春市| 临桂县| 邵武市| 温宿县| 尉氏县| 兴文县| 静海县| 浦城县| 梁平县| 泸水县| 紫阳县| 榆社县| 新巴尔虎左旗| 广饶县| 凤山县| 饶平县| 璧山县| 卫辉市| 镇平县| 宝应县| 安达市| 成安县| 尼勒克县| 盐池县|