日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

發布時間:2024/2/28 javascript 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

注釋介紹

@Cacheable

@Cacheable 的作用 主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存

@Cacheable 作用和配置方法

?

參數解釋example
value緩存的名稱,在 spring 配置文件中定義,必須指定至少一個例如:
@Cacheable(value=”mycache”)
@Cacheable(value={”cache1”,”cache2”}
key緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合@Cacheable(value=”testcache”,key=”#userName”)
condition緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存@Cacheable(value=”testcache”,condition=”#userName.length()>2”)

?

實例

@Cacheable(value=”accountCache”),這個注釋的意思是,當調用這個方法的時候,會從一個名叫 accountCache 的緩存中查詢,如果沒有,則執行實際的方法(即查詢數據庫),并將執行的結果存入緩存中,否則返回緩存中的對象。這里的緩存中的 key 就是參數 userName,value 就是 Account 對象?!癮ccountCache”緩存是在 spring*.xml 中定義的名稱。

?
1 2 3 4 5 6 @Cacheable(value="accountCache")// 使用了一個緩存名叫 accountCache public Account getAccountByName(String userName) { ???// 方法內部實現不考慮緩存邏輯,直接實現業務 ???System.out.println("real query account."+userName); ???return getFromDB(userName); }

@CachePut

@CachePut 的作用 主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存,和 @Cacheable 不同的是,它每次都會觸發真實方法的調用

@CachePut 作用和配置方法

?

參數解釋example
value緩存的名稱,在 spring 配置文件中定義,必須指定至少一個@CachePut(value=”my cache”)
key緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合@CachePut(value=”testcache”,key=”#userName”)
condition緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存@CachePut(value=”testcache”,condition=”#userName.length()>2”)

?

實例

@CachePut 注釋,這個注釋可以確保方法被執行,同時方法的返回值也被記錄到緩存中,實現緩存與數據庫的同步更新。

?
1 2 3 4 @CachePut(value="accountCache",key="#account.getName()")// 更新accountCache 緩存 public Account updateAccount(Account account) { ??return updateDB(account); }

@CacheEvict

@CachEvict 的作用 主要針對方法配置,能夠根據一定的條件對緩存進行清空

@CacheEvict 作用和配置方法

?

參數解釋example
value緩存的名稱,在 spring 配置文件中定義,必須指定至少一個@CacheEvict(value=”my cache”)
key緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合@CacheEvict(value=”testcache”,key=”#userName”)
condition緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存@CacheEvict(value=”testcache”,condition=”#userName.length()>2”)
allEntries是否清空所有緩存內容,缺省為 false,如果指定為 true,則方法調用后將立即清空所有緩存@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation是否在方法執行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執行的時候就清空緩存,缺省情況下,如果方法執行拋出異常,則不會清空緩存@CachEvict(value=”testcache”,beforeInvocation=true)

?

實例

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @CacheEvict(value="accountCache",key="#account.getName()")// 清空accountCache 緩存 public void updateAccount(Account account) { ???updateDB(account); } @CacheEvict(value="accountCache",allEntries=true)// 清空accountCache 緩存 public void reload() { ???reloadAll() } @Cacheable(value="accountCache",condition="#userName.length() <=4")// 緩存名叫 accountCache public Account getAccountByName(String userName) { ?// 方法內部實現不考慮緩存邏輯,直接實現業務 ?return getFromDB(userName); }

@CacheConfig

所有的@Cacheable()里面都有一個value=“xxx”的屬性,這顯然如果方法多了,寫起來也是挺累的,如果可以一次性聲明完 那就省事了, 所以,有了@CacheConfig這個配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法寫別的名字,那么依然以方法的名字為準。

?
1 2 3 4 5 6 @CacheConfig("books") public class BookRepositoryImpl implements BookRepository { ??@Cacheable ??public Book findBook(ISBN isbn) {...} }

條件緩存

下面提供一些常用的條件緩存

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //@Cacheable將在執行方法之前( #result還拿不到返回值)判斷condition,如果返回true,則查緩存; @Cacheable(value = "user", key = "#id", condition = "#id lt 10") public User conditionFindById(final Long id) //@CachePut將在執行完方法后(#result就能拿到返回值了)判斷condition,如果返回true,則放入緩存; @CachePut(value = "user", key = "#id", condition = "#result.username ne 'zhang'") public User conditionSave(final User user)? //@CachePut將在執行完方法后(#result就能拿到返回值了)判斷unless,如果返回false,則放入緩存;(即跟condition相反) @CachePut(value = "user", key = "#user.id", unless = "#result.username eq 'zhang'") public User conditionSave2(final User user)? //@CacheEvict, beforeInvocation=false表示在方法執行之后調用(#result能拿到返回值了);且判斷condition,如果返回true,則移除緩存; @CacheEvict(value = "user", key = "#user.id", beforeInvocation = false, condition = "#result.username ne 'zhang'") public User conditionDelete(final User user)?

@Caching

有時候我們可能組合多個Cache注解使用;比如用戶新增成功后,我們要添加id–>user;username—>user;email—>user的緩存;此時就需要@Caching組合多個注解標簽了。

?
1 2 3 4 5 6 @Caching(put = { @CachePut(value = "user", key = "#user.id"), @CachePut(value = "user", key = "#user.username"), @CachePut(value = "user", key = "#user.email") }) public User save(User user) {

自定義緩存注解

比如之前的那個@Caching組合,會讓方法上的注解顯得整個代碼比較亂,此時可以使用自定義注解把這些注解組合到一個注解中,如:

?
1 2 3 4 5 6 7 8 9 10 @Caching(put = { @CachePut(value = "user", key = "#user.id"), @CachePut(value = "user", key = "#user.username"), @CachePut(value = "user", key = "#user.email") }) @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface UserSaveCache { }

這樣我們在方法上使用如下代碼即可,整個代碼顯得比較干凈。

?
1 2 @UserSaveCache public User save(User user)

擴展

比如findByUsername時,不應該只放username–>user,應該連同id—>user和email—>user一起放入;這樣下次如果按照id查找直接從緩存中就命中了

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Caching( ??cacheable = { ????@Cacheable(value = "user", key = "#username") ??}, ??put = { ????@CachePut(value = "user", key = "#result.id", condition = "#result != null"), ????@CachePut(value = "user", key = "#result.email", condition = "#result != null") ??} ) public User findByUsername(final String username) { ??System.out.println("cache miss, invoke find by username, username:" + username); ??for (User user : users) { ????if (user.getUsername().equals(username)) { ??????return user; ????} ??} ??return null; }

其實對于:id—>user;username—->user;email—>user;更好的方式可能是:id—>user;username—>id;email—>id;保證user只存一份;如:

?
1 2 3 4 5 6 @CachePut(value="cacheName", key="#user.username", cacheValue="#user.username") public void save(User user)? @Cacheable(value="cacheName", key="#user.username", cacheValue="#caches[0].get(#caches[0].get(#username).get())") public User findByUsername(String username)

SpEL上下文數據

Spring Cache提供了一些供我們使用的SpEL上下文數據,下表直接摘自Spring官方文檔:

?

名稱位置描述示例
methodNameroot對象當前被調用的方法名root.methodName
methodroot對象當前被調用的方法root.method.name
targetroot對象當前被調用的目標對象root.target
targetClassroot對象當前被調用的目標對象類root.targetClass
argsroot對象當前被調用的方法的參數列表root.args[0]
cachesroot對象當前方法調用使用的緩存列表(如@Cacheable(value={“cache1”, “cache2”})),則有兩個cacheroot.caches[0].name
argument name執行上下文當前被調用的方法的參數,如findById(Long id),我們可以通過#id拿到參數user.id
result執行上下文方法執行后的返回值(僅當方法執行之后的判斷有效,如‘unless','cache evict'的beforeInvocation=false)result

?

?
1 2 @CacheEvict(value = "user", key = "#user.id", condition = "#root.target.canCache() and #root.caches[0].get(#user.id).get().username ne #user.username", beforeInvocation = true) public void conditionUpdate(User user)

微信掃一掃---打賞

?

總結

以上是生活随笔為你收集整理的详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。