Spring緩存抽象概述
Spring框架自身并沒有實現(xiàn)緩存解決方案,但是從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供對緩存功能的聲明,能夠與多種流行的緩存實現(xiàn)集成。
Cache接口為緩存的組件規(guī)范定義,包含緩存的各種操作集合;
Cache接口下Spring提供了各種xxxCache的實現(xiàn):如RedisCache,EhCacheCache , ConcurrentMapCache等;
CacheManager接口為緩存管理器規(guī)范,簡單來說就是用于存放cache,Spring默認也提供了一些列管理器的實現(xiàn)。
Spring緩存抽象提供了5個注解用來聲明緩存規(guī)則:
@Cacheable:能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存,多用于查詢
@CachePut: 執(zhí)行方法,并緩存結(jié)果
@CacheEvict:清空緩存
@Caching:能夠同時應(yīng)用多個緩存注解功能
@CacheConfig: 用于抽取緩存的公共配置(類級別)
以上5個注解除了@CacheConfig注解是類級別的注解,其余4個注解在類和方法上均可以使用,作用在類上表示對該類下所有方法生效,作用的方法上只對該方法生效,且只能用于public修飾的符方法,protected或者private修飾的方法不適用。
@Cacheable注解
@Cacheable注解的作用是Spring在調(diào)用該方法之前,首先在緩存中查找方法的返回值,默認的key是根據(jù)參數(shù)值生成,如果存在,直接返回緩存中的值,否則執(zhí)行該方法,并將返回值保存到緩存中
@Cacheable運行流程:
1.方法運行之前,先去查詢Cache(緩存組件),按照cacheNames指定的名字獲?。?/p>
(CacheManager先獲取相應(yīng)的緩存),第一次獲取緩存如果沒有Cache組件會自動創(chuàng)建。
2.去Cache中查找緩存的內(nèi)容,使用一個key,默認就是方法的參數(shù)值;
key是按照某種策略生成的;默認是使用keyGenerator生成的,
Spring默認加載的是SimpleCacheManage,SimpleKeyGenerator生成key的默認策略是:
如果沒有參數(shù);key=new SimpleKey()
如果有一個參數(shù):key=參數(shù)的值
如果有多個參數(shù):key=new SimpleKey(params)
3.沒有查到緩存就調(diào)用目標(biāo)方法;
4.將目標(biāo)方法返回的結(jié)果,放進緩存中
@Cacheable屬性說明:
1.acheNames/value:該屬性值必須提供,指定緩存組件的名字,將方法的返回結(jié)果放在哪個緩存中,是數(shù)組的方式,可以指定多個緩存;
如:cacheNames = "product"或者cacheNames = {"product1","product2"}
2.key:緩存數(shù)據(jù)使用的key,不指定key則默認是使用方法參數(shù)的值該屬性值支持SpEL表達式
3.cacheManager:指定緩存管理器;或者cacheResolver指定獲取解析器
4.condition:指定符合條件的情況下才緩存
5.unless:否定緩存;當(dāng)unless指定的條件為true,方法的返回值就不會被緩存;可以獲取到結(jié)果進行判斷
unless = "#result == null"
unless = "#a0==2":如果第一個參數(shù)的值是2,結(jié)果不緩存;
6.sync:是否使用異步模式
使用示例:
@Cacheable(cacheNames = "product")// 默認key為參數(shù),多個參數(shù)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") //”#+參數(shù)名”的形式,直接使用參數(shù)名//或者//@Cacheable(cacheNames ="product", key="#a0") //”#a+參數(shù)位置”的形式 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類并實現(xiàn)了KeyGenerator接口 ,使用如下:
@Configurationpublic 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()+"]"; } }; }}
該方法測試用,關(guān)于緩存key的生成方式,網(wǎng)上有很多種策略。
使用時只需要修改注解的key屬性即可:
@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")
@CachePut
@CachePut注解的作用簡單的說一句話:既調(diào)用方法,又緩存數(shù)據(jù)。@cachePut和@Cacheable兩個注解都可以用于填充緩存,但使用上略有點差異,@Cacheable注解的執(zhí)行流程是先在按key在緩存中查找,存在則返回,不存在則執(zhí)行目標(biāo)方法,并緩存目標(biāo)方法的結(jié)果。而@CachePut并不會檢查緩存,總是先執(zhí)行目標(biāo)方法,并將目標(biāo)方法的結(jié)果保存到緩存中。實際中比如執(zhí)行到更新操作時,則希望將最新的數(shù)據(jù)更新到緩存,如果該方法返回異常,將不再執(zhí)行保存緩存的邏輯。
@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("影響行數(shù):"+count); if(count>0){ return product; }else{ return null; }}
@CacheEvict注解
該注解的作用根據(jù)指定的key或者是allEntries屬性值移除緩存中特性的鍵值對。
@CacheEvict屬性說明
與@Cacheable相比@CacheEvict注解提供了另外兩個屬性:
1.allEntries:表示是否清空所有緩存內(nèi)容,默認false,如果該值為true則清空指定cacheNames緩存塊下所有內(nèi)容,如果指定了allEntries為true,那么再zhidingkey值將沒有意義
2.beforeInvocation:是否在執(zhí)行方法前請空緩存,默認值為false,如果該值為true則在調(diào)用目標(biāo)方法前執(zhí)行清空緩存,為false的情況下,如果目標(biāo)方法拋出異常,則不再執(zhí)行清空緩存邏輯
示例:
//@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注解
該注解是一個分組注解,作用是可以同時應(yīng)用多個其他注解,該注解提供了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; }
當(dāng)@Cacheing同時含有CachePut注解和Cacheable注解時,仍然會先執(zhí)行目標(biāo)方法。(并不是按@Cacheable的執(zhí)行過程,先檢查緩存,存在則返回)
@CacheConfig
是一個類級別的注解,允許共享緩存的名稱、KeyGenerator、CacheManager 和CacheResolver
示例:
@Service @CacheConfig(cacheNames = "product") public class ProductService { }
在類上使用該注解,指定cacheNames屬性值,則類中方法上的注解將默認繼承了該屬性值,如果方法上注解使用和了@CacheConfig向同的屬性,則以方法上的為準(zhǔn)。
@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,實際以方法上注解指定的為準(zhǔn)。
Spring緩存抽象的關(guān)鍵原理就是使用spring AOP,通過切面實現(xiàn)了在方法調(diào)用前、調(diào)用后獲取方法的入?yún)⒑头祷刂?,進而實現(xiàn)了緩存的邏輯。
總結(jié)
以上所述是小編給大家介紹的Spring 緩存抽象示例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對VeVb武林網(wǎng)網(wǎng)站的支持!
新聞熱點
疑難解答
圖片精選