最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1.基于注釋聲明緩存

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

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

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

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

@Caching: 把多種緩存操作應用重組到一個方法上

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

1.1@EnableCaching

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

1.2@Cacheable

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

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

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

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

更新一個name的緩存,其他所有沒有包含這個值的緩存也會被更新,即使這個緩存方法沒有實際調(diào)用.

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

}

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

Key :

上面cacheNames指定了緩存名稱,但是每個方法由于傳參不同,其return數(shù)據(jù)也會不同,所以一個方法中可能會有多個緩存。要在同一個cacheNames中區(qū)別不同的緩存,就需要使用key。通過SPEL表達式,指定 name為key。Spring 會默認以參數(shù)為key 如果沒有參數(shù)則有一個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;
}

因為Caches是一個key-value的存儲形式,每次調(diào)用緩存方法需要翻譯成對應的key來訪問緩存。緩存抽象使用簡單的 keygenerator 基于以下算法:

  • 如果沒有參數(shù),返回SimpleKey.EMPTY.
  • 如果只有一個參數(shù),就會作為實例返回.
  • 如果超過一個參數(shù),就會返回包含所有參數(shù)的 SimpleKey.

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

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

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

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

1.2.2聲明自定義key 生成

因為緩存是通用的,所以目標方法很可能有多種寫法,這些不能夠被頂層緩存結(jié)構(gòu)簡單的映射.當一個方法有多個參數(shù),但只有一些參數(shù)需要緩存時(其他key只給方法使用),這一點變得很明顯.

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

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

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

下面例子使用了多種SPEL語法:

@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的算法太過特殊或者需要共享,可以自定義keyGenerator.

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

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

1.2.3默認的cache resolution

默認的cache resolution是一個簡單的 CacheResolver ,通過配置CacheManager來檢索在操作級別定義的緩存.
通過繼承實現(xiàn)org.springframework.cache.interceptor.CacheResolver 接口來提供不同的默認resolver.
默認的cache resolution是由單個CacheManager實現(xiàn)并且沒有太復雜的resolution的需求.
默認的cache resolution是由單個CacheManager實現(xiàn)并且沒有太復雜的resolution的需求.
當一個應用同時使用多個 cacheManager 可以通過cachemanager指定

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

也可以通過cacheResolver替換resolver 類似于替換key generation.

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

這個resolution在每次緩存操作都會請求,允許我們基于實時的參數(shù)來實現(xiàn)解析緩存.

從spring 4.1之后, value的屬性不再強制要求傳,因為無論annotation的內(nèi)容傳什么,這個特定信息都會被CacheResolver提供.

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

1.2.4同步緩存

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

在這種特殊的情況下,可以使用 sync 屬性來指定緩存提供方在計算緩存實體的時候加鎖.

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

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

1.2.5 緩存的條件

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

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

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

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

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

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

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

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

上面的例子 #result一直引用Book 而不是Optional<Book>.因為有可能為空,所以使用SpEL's的Safe Navigation Operator

1.2.6可用的Spel 評估上下文

名稱

位置

描述

例子

methodName

Root object

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

#root.methodName

method

Root object

被調(diào)用的方法

#root.method.name

target

Root object

被調(diào)用的目標對象

#root.target

targetClass

Root object

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

#root.targetClass

args

Root object

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

#root.args[0]

caches

Root object

針對當前運行方法的所有緩存

#root.caches[0].name

Argument name

Evaluation context

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

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

result

Evaluation context

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

#result

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

相關(guān)文章

  • 使用springboot logback動態(tài)獲取application的配置項

    使用springboot logback動態(tài)獲取application的配置項

    這篇文章主要介紹了使用springboot logback動態(tài)獲取application的配置項,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java 實現(xiàn)KMP算法

    java 實現(xiàn)KMP算法

    這篇文章主要介紹了java 如何實現(xiàn)KMP算法,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下
    2020-12-12
  • SpringAOP+RabbitMQ+WebSocket實戰(zhàn)詳解

    SpringAOP+RabbitMQ+WebSocket實戰(zhàn)詳解

    這篇文章主要介紹了SpringAOP+RabbitMQ+WebSocket實戰(zhàn)詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • My eclipse 端口占用(9360)問題解決辦法

    My eclipse 端口占用(9360)問題解決辦法

    這篇文章主要介紹了My eclipse 工程發(fā)布時出現(xiàn)端口占用問題解決辦法的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 劍指Offer之Java算法習題精講求和篇

    劍指Offer之Java算法習題精講求和篇

    跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • java發(fā)送短信系列之同步、異步發(fā)送短信

    java發(fā)送短信系列之同步、異步發(fā)送短信

    這篇文章主要介紹了java發(fā)送短信系列之同步、異步發(fā)送短信的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 在Java和PostgreSQL枚舉之間轉(zhuǎn)換的通用方法

    在Java和PostgreSQL枚舉之間轉(zhuǎn)換的通用方法

    枚舉類型(enum)是一種方便的數(shù)據(jù)類型,允許我們指定一個常量列表,對象字段或數(shù)據(jù)庫列可以設(shè)置為該列表中的值,在本文中,我將回顧處理Java和PostgreSQL枚舉轉(zhuǎn)換的通用方法,需要的朋友可以參考下
    2023-10-10
  • Java實現(xiàn)消消樂中的消除功能

    Java實現(xiàn)消消樂中的消除功能

    這篇文章主要為大家詳細介紹了Java實現(xiàn)消消樂中的消除功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java 線程池_動力節(jié)點Java學院整理

    Java 線程池_動力節(jié)點Java學院整理

    系統(tǒng)啟動一個新線程的成本是比較高的,因為它涉及到與操作系統(tǒng)的交互。在這種情況下,使用線程池可以很好的提供性能,尤其是當程序中需要創(chuàng)建大量生存期很短暫的線程時,更應該考慮使用線程池
    2017-05-05
  • java中concat()方法的使用說明

    java中concat()方法的使用說明

    這篇文章主要介紹了java中concat()方法的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評論

昭平县| 新巴尔虎右旗| 临沧市| 宝山区| 水富县| 大化| 汉阴县| 岐山县| 云霄县| 长顺县| 隆德县| 甘谷县| 文成县| 兰州市| 壤塘县| 曲松县| 开平市| 平陆县| 曲周县| 桂阳县| 贡觉县| 通州区| 开化县| 绍兴县| 出国| 镇赉县| 南郑县| 兴仁县| 唐山市| 青冈县| 茂名市| 平原县| 开江县| 越西县| 琼结县| 葵青区| 永州市| 道孚县| 大姚县| 游戏| 崇州市|