Spring?@Cacheable讀取配置常量方式
Spring @Cacheable讀取配置常量
屬性①:value
String REDIS_DATABASE="database";
cacheable的name。默認(rèn)會(huì)在后面加上雙冒號,手動(dòng)調(diào)用加上::
屬性②:key
String REDIS_KEY_PREFIX="'wtf_'";
需要使用單引號',防止被表達(dá)式解析
簡單使用
@Cacheable(value = RedisConstant.REDIS_DATABASE, key = (RedisConstant.REDIS_KEY_PREFIX + "+#wtf"))
Spring緩存管理(Cacheable)
Spring的緩存管理可謂是相當(dāng)?shù)姆奖?。與其他功能的風(fēng)格一致,同樣的在需要管理的地方添加一個(gè)注解,可以是方法,也可以是類。
使用Spring Cache需要我們做兩方面的事:
- 聲明某些方法使用緩存
- 配置Spring對Cache的支持
和Spring對事務(wù)管理的支持一樣,Spring對Cache的支持也有基于注解和基于XML配置兩種方式。下面我們先來看看基于注解的方式。
基于注解的支持
Spring為我們提供了幾個(gè)注解來支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable標(biāo)記的方法在執(zhí)行后Spring Cache將緩存其返回結(jié)果,而使用@CacheEvict標(biāo)記的方法會(huì)在方法執(zhí)行前或者執(zhí)行后移除Spring Cache中的某些元素。下面我們將來詳細(xì)介紹一下Spring基于注解對Cache的支持所提供的幾個(gè)注解。
@Cacheable
@Cacheable可以標(biāo)記在一個(gè)方法上,也可以標(biāo)記在一個(gè)類上。當(dāng)標(biāo)記在一個(gè)方法上時(shí)表示該方法是支持緩存的,當(dāng)標(biāo)記在一個(gè)類上時(shí)則表示該類所有的方法都是支持緩存的。對于一個(gè)支持緩存的方法,Spring會(huì)在其被調(diào)用后將其返回值緩存起來,以保證下次利用同樣的參數(shù)來執(zhí)行該方法時(shí)可以直接從緩存中獲取結(jié)果,而不需要再次執(zhí)行該方法。Spring在緩存方法的返回值時(shí)是以鍵值對進(jìn)行緩存的,值就是方法的返回結(jié)果,至于鍵的話,Spring又支持兩種策略,默認(rèn)策略和自定義策略,這個(gè)稍后會(huì)進(jìn)行說明。需要注意的是當(dāng)一個(gè)支持緩存的方法在對象內(nèi)部被調(diào)用時(shí)是不會(huì)觸發(fā)緩存功能的。
@Cacheable可以指定三個(gè)屬性,value、key和condition。
value屬性指定Cache名稱
value屬性是必須指定的,其表示當(dāng)前方法的返回值是會(huì)被緩存在哪個(gè)Cache上的,對應(yīng)Cache的名稱。其可以是一個(gè)Cache也可以是多個(gè)Cache,當(dāng)需要指定多個(gè)Cache時(shí)其是一個(gè)數(shù)組。
@Cacheable("cache1")//Cache是發(fā)生在cache1上的 public User find(Integer id) { return null; } @Cacheable({"cache1", "cache2"})//Cache是發(fā)生在cache1和cache2上的 public User find(Integer id) { return null; }
使用key屬性自定義key
key屬性是用來指定Spring緩存方法的返回結(jié)果時(shí)對應(yīng)的key的。該屬性支持SpringEL表達(dá)式。當(dāng)我們沒有指定該屬性時(shí),Spring將使用默認(rèn)策略生成key。我們這里先來看看自定義策略,至于默認(rèn)策略會(huì)在后文單獨(dú)介紹。
自定義策略是指我們可以通過Spring的EL表達(dá)式來指定我們的key。這里的EL表達(dá)式可以使用方法參數(shù)及它們對應(yīng)的屬性。使用方法參數(shù)時(shí)我們可以直接使用“#參數(shù)名”或者“#p參數(shù)index”。下面是幾個(gè)使用參數(shù)作為key的示例。
@Cacheable(value="users", key="#id") public User find(Integer id) { return null; } @Cacheable(value="users", key="#p0") public User find(Integer id) { return null; } @Cacheable(value="users", key="#user.id") public User find(User user) { return null; } @Cacheable(value="users", key="#p0.id") public User find(User user) { return null; }
除了上述使用方法參數(shù)作為key之外,Spring還為我們提供了一個(gè)root對象可以用來生成key。通過該root對象我們可以獲取到以下信息。
屬性名稱 | 描述 | 示例 |
---|---|---|
methodName | 當(dāng)前方法名 | #root.methodName |
method | 當(dāng)前方法 | #root.method.name |
target | 當(dāng)前被調(diào)用的對象 | #root.target |
targetClass | 當(dāng)前被調(diào)用的對象的class | #root.targetClass |
args | 當(dāng)前方法參數(shù)組成的數(shù)組 | #root.args[0] |
caches | 當(dāng)前被調(diào)用的方法使用的Cache | #root.caches[0].name |
當(dāng)我們要使用root對象的屬性作為key時(shí)我們也可以將“#root”省略,因?yàn)镾pring默認(rèn)使用的就是root對象的屬性。如:
@Cacheable(value={"users", "xxx"}, key="caches[1].name") public User find(User user) { return null; }
condition屬性指定發(fā)生的條件
有的時(shí)候我們可能并不希望緩存一個(gè)方法所有的返回結(jié)果。通過condition屬性可以實(shí)現(xiàn)這一功能。condition屬性默認(rèn)為空,表示將緩存所有的調(diào)用情形。其值是通過SpringEL表達(dá)式來指定的,當(dāng)為true時(shí)表示進(jìn)行緩存處理;當(dāng)為false時(shí)表示不進(jìn)行緩存處理,即每次調(diào)用該方法時(shí)該方法都會(huì)執(zhí)行一次。如下示例表示只有當(dāng)user的id為偶數(shù)時(shí)才會(huì)進(jìn)行緩存。
@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0") public User find(User user) { System.out.println("find user by user " + user); return user; }
@CachePut
在支持Spring Cache的環(huán)境下,對于使用@Cacheable標(biāo)注的方法,Spring在每次執(zhí)行前都會(huì)檢查Cache中是否存在相同key的緩存元素,如果存在就不再執(zhí)行該方法,而是直接從緩存中獲取結(jié)果進(jìn)行返回,否則才會(huì)執(zhí)行并將返回結(jié)果存入指定的緩存中。@CachePut也可以聲明一個(gè)方法支持緩存功能。與@Cacheable不同的是使用@CachePut標(biāo)注的方法在執(zhí)行前不會(huì)去檢查緩存中是否存在之前執(zhí)行過的結(jié)果,而是每次都會(huì)執(zhí)行該方法,并將執(zhí)行結(jié)果以鍵值對的形式存入指定的緩存中。
@CachePut也可以標(biāo)注在類上和方法上。使用@CachePut時(shí)我們可以指定的屬性跟@Cacheable是一樣的。
@CachePut(“users”)//每次都會(huì)執(zhí)行方法,并將結(jié)果存入指定的緩存中 public User find(Integer id) { return null; }
@CacheEvict
@CacheEvict是用來標(biāo)注在需要清除緩存元素的方法或類上的。當(dāng)標(biāo)記在一個(gè)類上時(shí)表示其中所有的方法的執(zhí)行都會(huì)觸發(fā)緩存的清除操作。@CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。
其中value、key和condition的語義與@Cacheable對應(yīng)的屬性類似。即value表示清除操作是發(fā)生在哪些Cache上的(對應(yīng)Cache的名稱);
key表示需要清除的是哪個(gè)key,如未指定則會(huì)使用默認(rèn)策略生成的key;
condition表示清除操作發(fā)生的條件。
下面我們來介紹一下新出現(xiàn)的兩個(gè)屬性allEntries和beforeInvocation。
allEntries屬性
allEntries是boolean類型,表示是否需要清除緩存中的所有元素。默認(rèn)為false,表示不需要。當(dāng)指定了allEntries為true時(shí),Spring Cache將忽略指定的key。有的時(shí)候我們需要Cache一下清除所有的元素,這比一個(gè)一個(gè)清除元素更有效率。
@CacheEvict(value="users", allEntries=true) public void delete(Integer id) { System.out.println("delete user by id: " + id); }
beforeInvocation屬性
清除操作默認(rèn)是在對應(yīng)方法成功執(zhí)行之后觸發(fā)的,即方法如果因?yàn)閽伋霎惓6茨艹晒Ψ祷貢r(shí)也不會(huì)觸發(fā)清除操作。使用beforeInvocation可以改變觸發(fā)清除操作的時(shí)間,當(dāng)我們指定該屬性值為true時(shí),Spring會(huì)在調(diào)用該方法之前清除緩存中的指定元素。
@CacheEvict(value="users", beforeInvocation=true) public void delete(Integer id) { System.out.println("delete user by id: " + id); }
其實(shí)除了使用@CacheEvict清除緩存元素外,當(dāng)我們使用Ehcache作為實(shí)現(xiàn)時(shí),我們也可以配置Ehcache自身的驅(qū)除策略,其是通過Ehcache的配置文件來指定的。由于Ehcache不是本文描述的重點(diǎn),這里就不多贅述了。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring?Boot?Actuator管理日志的實(shí)現(xiàn)
本文主要介紹了Spring?Boot?Actuator管理日志的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07java通過模擬post方式提交表單實(shí)現(xiàn)圖片上傳功能實(shí)例
這篇文章主要介紹了java通過模擬post方式提交表單實(shí)現(xiàn)圖片上傳功能實(shí)例,涉及Java針對表單的提交操作響應(yīng)及文件傳輸?shù)南嚓P(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11BeanPostProcessor在顯示調(diào)用初始化方法前修改bean詳解
這篇文章主要介紹了BeanPostProcessor在顯示調(diào)用初始化方法前修改bean詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Java中的日期和時(shí)間類以及Calendar類用法詳解
這篇文章主要介紹了Java中的日期和時(shí)間類以及Calendar類用法詳解,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09Mybatis order by 動(dòng)態(tài)傳參出現(xiàn)的問題及解決方法
今天,我正在愉快地CRUD,突然發(fā)現(xiàn)出現(xiàn)一個(gè)Bug,我們來看看是怎么回事吧!接下來通過本文給大家介紹Mybatis order by 動(dòng)態(tài)傳參出現(xiàn)的一個(gè)小bug,需要的朋友可以參考下2021-07-07Java 實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能簡單實(shí)例
這篇文章主要介紹了Java 實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-04-04