SpringBoot怎樣進(jìn)行緩存,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站、網(wǎng)站頁面設(shè)計(jì)、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)網(wǎng)站設(shè)計(jì)公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗(yàn),以探求精品塑造與理念升華,設(shè)計(jì)最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅(jiān)持講誠信,負(fù)責(zé)任的原則,為您進(jìn)行細(xì)心、貼心、認(rèn)真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。
緩存技術(shù)是一個讓所有開發(fā)人員又愛又恨的技術(shù),我們愛緩存是因?yàn)榫彺婺芙o我們帶來數(shù)量級的響應(yīng)和流量,但是最迷人的反而最危險(xiǎn),如果緩存用不好也是災(zāi)難級別的,特別是一些涉及到公司主要現(xiàn)金流的業(yè)務(wù),如果因?yàn)槲覀兪褂镁彺娌划?dāng),而帶給公司一定的損失,不亞于刪庫跑路的那個大兄弟,那今天我們就來看一下springboot的緩存都有那些東西,學(xué)習(xí)嘛,一點(diǎn)點(diǎn)的來,慢慢積累自己的經(jīng)驗(yàn),才能厚積薄發(fā)
為了緩存開發(fā)規(guī)范的統(tǒng)一,以及提升系統(tǒng)的擴(kuò)展性,J2EE發(fā)布了JSR107緩存規(guī)范。 主要是Java Caching定義了5個接口,分別是CachingProvider、CacheManager、Cache、Entry、Expiry。
下面我們分開詳細(xì)的展開看一下
CachingProvider:
可以創(chuàng)建、配置、獲取、管理和控制多個CacheManager,一個Application在運(yùn)行期間可以訪問多個CachingProvider。
CacheManager:
可以創(chuàng)建、配置、獲取、管理和控制多個唯一命名的Cache,這些Cache存在于CacheManager的上下文中。一個CacheManager僅被一個CachingProvider所擁有。
Cache:
是一個類似于Map的數(shù)據(jù)結(jié)構(gòu)并臨時存儲以Key為索引的值。一個Cache僅被一個CacheManager所擁有。
Entry:
是存儲在Cache中的Key-Value對。
Expiry:
每一個緩存在Cache中的條目有一個定義的有效期,一旦超過這個時間,該條目就為過期狀態(tài),一旦過期,條目將不可訪問、更新和刪除。其中緩存的有效期可以通過ExpiryPolicy設(shè)置。
如果說這樣講解讓你有點(diǎn)蒙圈的話,那沒關(guān)系,我們看下面這張圖
簡單總結(jié)一下就是:一個應(yīng)用里面可以有多個緩存提供者(CachingProvider),一個緩存提供者可以獲取到多個緩存管理器(CacheManager),一個緩存管理器管理著不同的緩存(Cache),緩存中是一個個的緩存鍵值對(Entry),每個entry都有一個有效期(Expiry)。緩存管理器和緩存之間的關(guān)系有點(diǎn)類似于數(shù)據(jù)庫中連接池和連接的關(guān)系。
在我自己看來,沒有源碼所有的理論講解,都是空談,或者說就是扯淡,所以我們來看一下,緩存的源碼級操作
Spring從3.1版本開始定義了org.springframework.cache.CacheManager和org.springframework.cache.Cache接口來統(tǒng)一不同的緩存技術(shù),并支持使用JSR-107注解簡化開發(fā)。 在IDEA中,使用Spring Initializr快速創(chuàng)建Spring Boot項(xiàng)目時,勾選中Cache后,在配置文件中配置debug=true,可以查看Spring Boot的自動配置項(xiàng)。 其中關(guān)于緩存的配置類如下:
org.springframework.boot.autoconfigure.cache.GenericCacheConfigurationorg.springframework.boot.autoconfigure.cache.JCacheCacheConfigurationorg.springframework.boot.autoconfigure.cache.EhCacheCacheConfigurationorg.springframework.boot.autoconfigure.cache.HazelcastCacheConfigurationorg.springframework.boot.autoconfigure.cache.InfinispanCacheConfigurationorg.springframework.boot.autoconfigure.cache.CouchbaseCacheConfigurationorg.springframework.boot.autoconfigure.cache.redisCacheConfigurationorg.springframework.boot.autoconfigure.cache.CaffeineCacheConfigurationorg.springframework.boot.autoconfigure.cache.GuavaCacheConfigurationorg.springframework.boot.autoconfigure.cache.SimpleCacheConfigurationorg.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
啟動項(xiàng)目后,可以在控制臺看到匹配到的只有SimpleCacheConfiguration這個自動配置類,而在SimpleCacheConfiguration類中,使用@Bean注解給容器中注冊了一個CacheManager,由此可看Spring Boot默認(rèn)的CacheManager是ConcurrentMapCacheManager。
SimpleCacheConfiguration matched: - Cache org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration automatic cache type (CacheCondition) - @ConditionalOnMissingBean (types: org.springframework.cache.CacheManager; SearchStrategy: all) did not find any beans (OnBeanCondition)
同樣的,我們通過一張圖形象的展示一下看看
進(jìn)入@Caching的源碼可以看到,在組合注解內(nèi)可以使用cacheable、put、evict
public @interface Caching { Cacheable[] cacheable() default {}; CachePut[] put() default {}; CacheEvict[] evict() default {};}
@Caching的使用
@Caching( cacheable = { @Cacheable(key = "#name") }, put = { @CachePut(key = "#result.id"), @CachePut(key = "#result.cNo") } )
key
#緩存的key,可以為空,也可以使用SpEL表達(dá)式編寫例:@Cacheable(value=“stu”,key=“userName”)
condition
#緩存的條件,可以為空,也可以使用SpEL表達(dá)式編寫,只有為true才緩存/清除緩存,#不管方法執(zhí)行前后都可以判斷例:@Cacheable(value=“stu”,condition=“userName.length()>2”)
unless
#用于否定緩存,只在方法執(zhí)行之后判斷,也可以使用SpEL表達(dá)式編寫#true不緩存,false才緩存例:@Cacheable(value=“stu”,unless=“userName == null”)
@Cacheable
標(biāo)注的方法執(zhí)行之前,先查看緩存中有沒有這個數(shù)據(jù),默認(rèn)按照參數(shù)的值作為key去緩存中查找。如果沒有就運(yùn)行這個方法并將方法的執(zhí)行結(jié)果放入緩存中,之后再調(diào)用該方法時,直接使用緩存中的數(shù)據(jù)即可。
@CachePut
標(biāo)注的方法必須要執(zhí)行,它的運(yùn)行時機(jī)是,先調(diào)用目標(biāo)方法,然后將目標(biāo)方法的結(jié)果放入緩存中,但是更新緩存中的數(shù)據(jù)時,要注意key值,否則緩存中的數(shù)據(jù)無法更新。
@CacheEvict
這個注解中allEntries = true代表要清除某個緩存中的所有數(shù)據(jù)。beforeInvocation = false代表緩存的清除在方法執(zhí)行之后執(zhí)行,如果出現(xiàn)異常等情況,則不會清除緩存中的數(shù)據(jù)。這是@CacheEvict
注解默認(rèn)的。beforeInvocation = true代表緩存的清除在方法執(zhí)行之前執(zhí)行,出現(xiàn)異常等情況,也會清除緩存中的數(shù)據(jù)。
key的生成策略
key的生成默認(rèn)使用SimpleKeyGenerator生成的,而SimpleKeyGenerator的生成策略有:如果沒有參數(shù):key=new SimpleKey();如果有一個參數(shù):key=參數(shù)的值如果有多個參數(shù):key=new SimpleKey(params);
看完上述內(nèi)容,你們掌握SpringBoot怎樣進(jìn)行緩存的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!