欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring框架cacheAnnotation緩存注釋聲明解析

 更新時(shí)間:2021年10月09日 15:49:05   作者:FantasyBaby  
這篇文章主要介紹了spring框架中cacheAnnotation注釋聲明緩存解析示例有需要的朋友可以借鑒參考下,希望能夠有所幫助

1.基于注釋聲明緩存

聲明緩存,Spring緩存抽象提供了一個(gè)java annotation集合.

@Cacheable:觸發(fā)緩存填充.

@CacheEvict: 觸發(fā)緩存刪除.

@CachePut: 不干擾方法執(zhí)行的情況下更新緩存.

@Caching: 把多種緩存操作應(yīng)用重組到一個(gè)方法上

@CacheConfig: 在類上設(shè)置,將一些共用緩存相關(guān)設(shè)置共享

1.1@EnableCaching

將該注解放在配置類上開(kāi)啟緩存,使用該注解后,允許你指定各種選項(xiàng),通過(guò)AOP的方式把這些影響添加到你的應(yīng)用程序中. 類似于 @Transactional

1.2@Cacheable

觸發(fā)數(shù)據(jù)存儲(chǔ)于緩存

顧名思義,@Cacheable用于標(biāo)示可緩存的方法 - 即將結(jié)果存儲(chǔ)到緩存中的方法,以便在后續(xù)調(diào)用(具有相同的參數(shù))時(shí),返回緩存中的值而不必實(shí)際執(zhí)行該方法.

下圖是所有的緩存的存儲(chǔ)結(jié)構(gòu)

cacheNames:指定緩存的名稱,不同緩存的數(shù)據(jù)是彼此隔離的,可以指定多個(gè)緩存名稱.(就是生成多個(gè)緩存name).如果有一個(gè)緩存命中,關(guān)聯(lián)值就會(huì)返回.

更新一個(gè)name的緩存,其他所有沒(méi)有包含這個(gè)值的緩存也會(huì)被更新,即使這個(gè)緩存方法沒(méi)有實(shí)際調(diào)用.

@Cacheable({"coffees","coffees2"})
public List<Coffee> findAllCoffee() {
return coffeeRepository.findAll();

}

1.2.1默認(rèn)key生成規(guī)則

Key :

上面cacheNames指定了緩存名稱,但是每個(gè)方法由于傳參不同,其return數(shù)據(jù)也會(huì)不同,所以一個(gè)方法中可能會(huì)有多個(gè)緩存。要在同一個(gè)cacheNames中區(qū)別不同的緩存,就需要使用key。通過(guò)SPEL表達(dá)式,指定 name為key。Spring 會(huì)默認(rèn)以參數(shù)為key 如果沒(méi)有參數(shù)則有一個(gè)org.springframework.cache.interceptor.SimpleKey.

@Cacheable(cacheNames = "coffees",key = "#name")
public Optional<Coffee> findOneCoffee(String name) {
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("name", exact().ignoreCase());
Optional<Coffee> coffee = coffeeRepository.findOne(
Example.of(Coffee.builder().name(name).build(), matcher));
log.info("Coffee Found: {}", coffee);
return coffee;
}

因?yàn)镃aches是一個(gè)key-value的存儲(chǔ)形式,每次調(diào)用緩存方法需要翻譯成對(duì)應(yīng)的key來(lái)訪問(wèn)緩存。緩存抽象使用簡(jiǎn)單的 keygenerator 基于以下算法:

  • 如果沒(méi)有參數(shù),返回SimpleKey.EMPTY.
  • 如果只有一個(gè)參數(shù),就會(huì)作為實(shí)例返回.
  • 如果超過(guò)一個(gè)參數(shù),就會(huì)返回包含所有參數(shù)的 SimpleKey.

該方法對(duì)大多數(shù)case有效,只要參數(shù)有nautral keys并且他們有效的實(shí)現(xiàn)了 hashcode()和equals()方法.如果不是這個(gè)case的需要去改變策略.

提供不同的key 生成器,需要去實(shí)現(xiàn) org.springframework.cache.interceptor.KeyGenerator 這個(gè)接口.

默認(rèn)的key生成策略在spring 4.0以后有所改變.之前的Spring版本使用用的key生成策略,對(duì)于多個(gè)key參數(shù),僅用參數(shù)的hashCode()沒(méi)有使用equeal().這可能造成key沖突(從 SPR-10237 查看背景).新的 SimpleKeyGenerator對(duì)于這種場(chǎng)景使用了組合key.

如果你想保持之前的key生成策略,你可以配置不推薦使用的org.springframework.cache.interceptor.DefaultKeyGenerator或者創(chuàng)建一個(gè)自定義的 基于hash的 key產(chǎn)生的實(shí)現(xiàn)

1.2.2聲明自定義key 生成

因?yàn)榫彺媸峭ㄓ玫?所以目標(biāo)方法很可能有多種寫法,這些不能夠被頂層緩存結(jié)構(gòu)簡(jiǎn)單的映射.當(dāng)一個(gè)方法有多個(gè)參數(shù),但只有一些參數(shù)需要緩存時(shí)(其他key只給方法使用),這一點(diǎn)變得很明顯.

@Cacheable("books")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

上面的例子: 用到了兩個(gè)布爾參數(shù),他們對(duì)緩存可能沒(méi)有用處,此外如果有一個(gè)有用另一個(gè)沒(méi)用應(yīng)該怎么辦?

上面說(shuō)過(guò)我們可以通過(guò)@Cacheable 來(lái)指定key通過(guò)哪些參數(shù)生成.可以使用SPEL 來(lái)選擇感興趣的參數(shù)(以及嵌套屬性),執(zhí)行操作,或者甚至調(diào)用任意方法都可以不需要寫任何代碼或者實(shí)現(xiàn)任何接口. 推薦的默認(rèn)的key 產(chǎn)生方式在上面已經(jīng)說(shuō)過(guò),但是默認(rèn)的策略并不能適應(yīng)所有的方法.

下面例子使用了多種SPEL語(yǔ)法:

@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

如果生成key的算法太過(guò)特殊或者需要共享,可以自定義keyGenerator.

@Cacheable(cacheNames="books", keyGenerator="myKeyGenerator")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

注: key 和 keyGenerator是互斥的,同時(shí)指定會(huì)產(chǎn)生異常

1.2.3默認(rèn)的cache resolution

默認(rèn)的cache resolution是一個(gè)簡(jiǎn)單的 CacheResolver ,通過(guò)配置CacheManager來(lái)檢索在操作級(jí)別定義的緩存.
通過(guò)繼承實(shí)現(xiàn)org.springframework.cache.interceptor.CacheResolver 接口來(lái)提供不同的默認(rèn)resolver.
默認(rèn)的cache resolution是由單個(gè)CacheManager實(shí)現(xiàn)并且沒(méi)有太復(fù)雜的resolution的需求.
默認(rèn)的cache resolution是由單個(gè)CacheManager實(shí)現(xiàn)并且沒(méi)有太復(fù)雜的resolution的需求.
當(dāng)一個(gè)應(yīng)用同時(shí)使用多個(gè) cacheManager 可以通過(guò)cachemanager指定

@Cacheable(cacheNames="books", cacheManager="anotherCacheManager")
public Book findBook(ISBN isbn) {...}

也可以通過(guò)cacheResolver替換resolver 類似于替換key generation.

@Cacheable(cacheResolver="runtimeCacheResolver")
public Book findBook(ISBN isbn) {...}

這個(gè)resolution在每次緩存操作都會(huì)請(qǐng)求,允許我們基于實(shí)時(shí)的參數(shù)來(lái)實(shí)現(xiàn)解析緩存.

從spring 4.1之后, value的屬性不再?gòu)?qiáng)制要求傳,因?yàn)闊o(wú)論annotation的內(nèi)容傳什么,這個(gè)特定信息都會(huì)被CacheResolver提供.

類似于key和keygenerator,cacheManager和cahceResolver這兩個(gè)參數(shù)都是互斥的,同時(shí)指定會(huì)返回異常,因?yàn)槎x的cacheManager會(huì)被定義的cacheResolver的實(shí)現(xiàn)給忽略.

1.2.4同步緩存

在多線程環(huán)境里,某些操作可能使用相同參數(shù)并發(fā)調(diào)用(典型的例如啟動(dòng)).默認(rèn)情況下,緩存抽象不會(huì)加鎖,如果一個(gè)同樣的值多次被計(jì)算是違背緩存的初衷的.

在這種特殊的情況下,可以使用 sync 屬性來(lái)指定緩存提供方在計(jì)算緩存實(shí)體的時(shí)候加鎖.

@Cacheable(cacheNames="foos", sync=true)
public Foo executeExpensiveOperation(String id) {...}

這個(gè)可選特性,也許提供緩存的庫(kù)并不支持.所有的 核心框架提供得CacheManager是支持的.

1.2.5 緩存的條件

有時(shí),一個(gè)方法并不能在所有時(shí)候都適用于一個(gè)緩存(比如,它可能依賴于給定參數(shù)).緩存的注解支持這些情況,通過(guò)使用 condition 參數(shù).

condition中使用 Spel 表達(dá)式可以得出 true 或者false.如果是true,方法緩存,反之,方法不會(huì)緩存(這個(gè)方法無(wú)論什么值或者使用任何參數(shù)都會(huì)被調(diào)用).

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

1.上面設(shè)置的條件是name的長(zhǎng)度 小于32

@Cacheable(cacheNames="book", condition="#name.length() < 32", unless="#result.hardback")
public Book findBook(String name)

2.使用unless, 否決掉對(duì)應(yīng)的value到緩存中.不像condition,unless表達(dá)式是在方法調(diào)用完后被調(diào)用,上面的例子就是如果我們只想緩存paperback book, 我們可以阻擋 hardback.

緩存抽象同樣支持 java.util.Optional,返回類型.如果Optional是present,則被關(guān)聯(lián)到對(duì)應(yīng)緩存,如果not present,將會(huì)存儲(chǔ)一個(gè)null. #result 總是引用業(yè)務(wù)對(duì)象并且永遠(yuǎn)不會(huì)支持包裝器,所以上面的例子可以改為

@Cacheable(cacheNames="book", condition="#name.length() < 32", unless="#result?.hardback")
public Optional<Book> findBook(String name)

上面的例子 #result一直引用Book 而不是Optional<Book>.因?yàn)橛锌赡転榭?所以使用SpEL's的Safe Navigation Operator

1.2.6可用的Spel 評(píng)估上下文

名稱

位置

描述

例子

methodName

Root object

被調(diào)用方法的名稱

#root.methodName

method

Root object

被調(diào)用的方法

#root.method.name

target

Root object

被調(diào)用的目標(biāo)對(duì)象

#root.target

targetClass

Root object

被調(diào)用對(duì)象的類

#root.targetClass

args

Root object

調(diào)用的參數(shù)數(shù)組

#root.args[0]

caches

Root object

針對(duì)當(dāng)前運(yùn)行方法的所有緩存

#root.caches[0].name

Argument name

Evaluation context

任何方法參數(shù)的名稱.如果名稱找不到(也許是沒(méi)有debug信息),這個(gè)參數(shù)名稱可能在#a<#arg>之下找到, 這個(gè)#arg表示參數(shù)索引(從0開(kāi)始)

#iban or #a0 (you can also use #p0 or #p<#arg> notation as an alias).

result

Evaluation context

方法返回調(diào)用(值將被緩存).只有在 unless表達(dá)式中, cache put表達(dá)式(去計(jì)算一個(gè)key)或者 cache evict 表達(dá)式(當(dāng) beforeInvocation=false)可用. 為了支持wrappers(比如 Optional),#result 引用的實(shí)際的對(duì)象而非 wrapper

#result

以上就是spring框架cacheAnnotation注釋聲明緩存解析的詳細(xì)內(nèi)容,更多關(guān)于spring框架cache緩存Annotation注釋的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mybatis輸出SQL格式化方式

    mybatis輸出SQL格式化方式

    這篇文章主要介紹了mybatis輸出SQL格式化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringMVC+MyBatis 事務(wù)管理(實(shí)例)

    SpringMVC+MyBatis 事務(wù)管理(實(shí)例)

    本文先分析編程式注解事務(wù)和基于注解的聲明式事務(wù)。對(duì)SpringMVC+MyBatis 事務(wù)管理的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2017-08-08
  • Java反射機(jī)制詳解

    Java反射機(jī)制詳解

    Java的反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任何一個(gè)類,都可以知道這個(gè)類的所有屬性和方法,對(duì)于任何一個(gè)對(duì)象,都可以調(diào)用它所有的方法和屬性,修改部分類型信息。本文就來(lái)詳細(xì)講講Java反射機(jī)制的使用
    2022-07-07
  • Java實(shí)現(xiàn)雪花算法的原理和實(shí)戰(zhàn)教程

    Java實(shí)現(xiàn)雪花算法的原理和實(shí)戰(zhàn)教程

    這篇文章主要介紹了Java實(shí)現(xiàn)雪花算法的原理和實(shí)戰(zhàn)教程,本文通過(guò)語(yǔ)言表述和代碼的實(shí)現(xiàn)講解了該項(xiàng)算法,,需要的朋友可以參考下
    2021-06-06
  • java9開(kāi)始——接口中可以定義private私有方法

    java9開(kāi)始——接口中可以定義private私有方法

    這篇文章主要介紹了從java9開(kāi)始 接口中可以定義private私有方法,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-10-10
  • springboot集成opencv實(shí)現(xiàn)人臉識(shí)別功能的詳細(xì)步驟

    springboot集成opencv實(shí)現(xiàn)人臉識(shí)別功能的詳細(xì)步驟

    大家都知道OpenCV是一個(gè)基于BSD許可(開(kāi)源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)軟件庫(kù),可以運(yùn)行在Linux、Windows、Android和Mac OS操作系統(tǒng)上今天通過(guò)本文給大家分享springboot集成opencv實(shí)現(xiàn)人臉識(shí)別,感興趣的朋友一起看看吧
    2021-06-06
  • java并發(fā)中DelayQueue延遲隊(duì)列原理剖析

    java并發(fā)中DelayQueue延遲隊(duì)列原理剖析

    DelayQueue隊(duì)列是一個(gè)延遲隊(duì)列,本文將結(jié)合實(shí)例代碼,詳細(xì)的介紹DelayQueue延遲隊(duì)列的源碼分析,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 本地jvm執(zhí)行flink程序帶web ui的操作

    本地jvm執(zhí)行flink程序帶web ui的操作

    這篇文章主要介紹了本地jvm執(zhí)行flink程序帶web ui的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • JVM調(diào)優(yōu)OutOfMemoryError異常分析

    JVM調(diào)優(yōu)OutOfMemoryError異常分析

    這篇文章主要為大家介紹了JVM調(diào)優(yōu)OutOfMemoryError異常分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Java主線程捕獲子線程異常的實(shí)現(xiàn)

    Java主線程捕獲子線程異常的實(shí)現(xiàn)

    本文主要介紹了Java主線程捕獲子線程異常的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04

最新評(píng)論