SpringCache源碼解析Annotation案例講解
〇、常用注解
| 包地址 | 注解名 | 作用域 | 作用 |
|---|---|---|---|
| org.springframework.cache.annotation | CacheConfig | 類級(jí)別 | s設(shè)置緩存的公共配置 |
| Cacheable | 方法級(jí)別 | 緩存讀取操作 | |
| CacheEvict | 方法級(jí)別 | 緩存失效操作 | |
| CachePut | 方法級(jí)別 | 緩存更新操作 | |
| Caching | 方法級(jí)別 | h混合讀取、失效、更新操作 | |
| CacheConfig | 方法級(jí)別 | 統(tǒng)一配置緩存注解的屬性,作用于類 | |
| EnableCaching | 方法級(jí)別 | 開啟緩存功能 |
一、@Cacheable注解
| 屬性 | 默認(rèn)值 | 描述 |
|---|---|---|
| value | 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個(gè) | |
| cacheNames | 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個(gè) | |
| key | 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進(jìn)行組合 | |
| keyGenerator | ||
| cacheManager | ||
| cacheResolver | ||
| condition | 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存。不能使用返回結(jié)果 | |
| unless | 不緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 false才進(jìn)行緩存??梢允褂梅祷亟Y(jié)果 | |
| sync |
- 簡(jiǎn)介:表示該方法執(zhí)行后的結(jié)果可以被緩存;可作用于類和方法,作用于類上,則表示對(duì)該類的所有方法都有效;
- 執(zhí)行邏輯:查找對(duì)應(yīng)的緩存是否存在,若不存在,該方法會(huì)被調(diào)用,并且將返回結(jié)果放入緩存;若存在,則不調(diào)用方法,直接返回緩存的結(jié)果;
1.1 案例
注解業(yè)務(wù)案例 單一緩存名稱和鍵:
@Cacheable("books")
public Book findBookById(String id) {
// 業(yè)務(wù)邏輯
}多個(gè)緩存名稱和條件:
@Cacheable(value = {"books", "archivedBooks"}, condition = "#id.length() > 10")
public Book findBookWithComplexKey(String id) {
// 業(yè)務(wù)邏輯
}
@Service
public class MyService {
/**
* 一個(gè)使用 @Cacheable 所有屬性的案例。
*
* @param id 用戶ID
* @return 返回用戶對(duì)象
*/
@Cacheable(
value = "users", // 緩存名稱
key = "#id", // 緩存鍵,使用SpEL表達(dá)式
condition = "#id.length() > 3", // 緩存條件,只有當(dāng)ID長度大于3時(shí)才緩存
unless = "#result == null" // 除非條件,如果結(jié)果為null,則不緩存
)
public User findUserById(String id) {
// 模擬數(shù)據(jù)庫查詢操作,這里假設(shè)ID長度小于3時(shí)沒有結(jié)果
if (id == null || id.length() <= 3) {
return null;
}
return performDatabaseQuery(id);
}
private User performDatabaseQuery(String id) {
// 模擬數(shù)據(jù)庫查詢邏輯
return new User(id, "Name based on ID");
}
}1.2 核心源碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
@AliasFor("cacheNames")
String[] value() default {};
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
@AliasFor("value")
String[] cacheNames() default {};
// 緩存的KEY,支持SpEL表達(dá)式動(dòng)態(tài)計(jì)算
// 默認(rèn)為空(缺省按照方法的所有參數(shù)組合生成SimpleKey)
String key() default "";
// 緩存KEY生成器
String keyGenerator() default "";
// 緩存管理器
String cacheManager() default "";
// 緩存解析器
String cacheResolver() default "";
// 緩存的條件,使用SpEL表達(dá)式,方法調(diào)用前計(jì)算,當(dāng)結(jié)果為true時(shí)執(zhí)行動(dòng)作
// 默認(rèn)為空,表示總是緩存方法返回值
String condition() default "";
// 否決緩存的條件,使用SpEL表達(dá)式,方法調(diào)用后計(jì)算(可使用result),當(dāng)結(jié)果為true時(shí)不執(zhí)行動(dòng)作
// 默認(rèn)為空,表示永不否決;
String unless() default "";
// 使用異步模式標(biāo)識(shí)
boolean sync() default false;
}二、@CachePut
注解作用:@CachePut 注解用于在方法執(zhí)行后更新緩存。
注解屬性:與@Cacheable相同。
- 簡(jiǎn)介:表示該方法執(zhí)行后的結(jié)果需要更新到緩存;可作用于類和方法,作用于類上,則表示對(duì)該類的所有方法都有效;
- 執(zhí)行邏輯:和Cacheable不同的是,帶有CachePut注解的方法一定會(huì)被執(zhí)行,方法執(zhí)行后的結(jié)果由condition/unless判定是否存入緩存;
2.1 案例
@CachePut("books")
public Book updateBookDetails(String id, Book details) {
// 業(yè)務(wù)邏輯
}
@Service
public class MyService {
/**
* 使用 @CachePut 所有屬性的案例。
*
* @param user 用戶對(duì)象,包含ID
* @return 更新后的用戶對(duì)象
*/
@CachePut(
value = "users", // 緩存名稱
key = "#user.id", // 緩存鍵,使用SpEL表達(dá)式
condition = "#user.age > 18" // 條件,只有當(dāng)用戶年齡大于18時(shí)才更新緩存
)
public User updateUserProfile(User user) {
// 模擬更新用戶信息的業(yè)務(wù)邏輯
return performUpdate(user);
}
private User performUpdate(User user) {
// 模擬更新邏輯
user.setName("Updated Name");
return user;
}
}2.2 核心源碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
@AliasFor("cacheNames")
String[] value() default {};
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
@AliasFor("value")
String[] cacheNames() default {};
// 緩存的KEY,可以為空(缺省按照方法的所有參數(shù)組合生成SimpleKey);
// 支持SpEL表達(dá)式
String key() default "";
// KEY的生成器
String keyGenerator() default "";
// 緩存管理器
String cacheManager() default "";
// 緩存解析器
String cacheResolver() default "";
// 放置緩存的條件,使用SpEL表達(dá)式,方法調(diào)用后計(jì)算(可使用result),當(dāng)結(jié)果為true時(shí)執(zhí)行動(dòng)作
// 默認(rèn)為空,表示方法結(jié)果總是被緩存
String condition() default "";
// 否決放置緩存的條件,使用SpEL表達(dá)式,方法調(diào)用后計(jì)算(可使用result),當(dāng)結(jié)果為true時(shí)不執(zhí)行動(dòng)作
// 默認(rèn)為空,表示永不否決;
String unless() default "";
}三、@CacheEvict
注解作用:@CacheEvict 注解用于在方法執(zhí)行后清除緩存。
注解屬性介紹:
- value 或 cacheNames: 指定緩存名稱,可以是單個(gè)或多個(gè);
- allEntries: 清除所有緩存項(xiàng);
- condition: 指定清除緩存的條件SpEL表達(dá)式;
簡(jiǎn)介:表示清除該方法的緩存KEY對(duì)應(yīng)的緩存;可作用于類和方法,作用于類上,則表示對(duì)該類的所有方法都有效;
3.1 案例
清除特定緩存名稱的條目:
@CacheEvict("books")
public void deleteBook(String id) {
// 業(yè)務(wù)邏輯
}清除所有緩存名稱的所有條目:
@CacheEvict(allEntries = true)
public void clearAllCaches() {
// 業(yè)務(wù)邏輯
}3.2 核心源碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
@AliasFor("cacheNames")
String[] value() default {};
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
@AliasFor("value")
String[] cacheNames() default {};
// 緩存的KEY,可以為空(缺省按照方法的所有參數(shù)組合生成SimpleKey);
// 支持SpEL表達(dá)式
String key() default "";
// KEY的生成器
String keyGenerator() default "";
// 緩存管理器
String cacheManager() default "";
// 緩存解析器
String cacheResolver() default "";
// 清除緩存的條件,使用SpEL表達(dá)式,執(zhí)行次序由beforeInvocation()決定
// 默認(rèn)為空,表示總是清除緩存
String condition() default "";
// 刪除緩存中所有條目標(biāo)識(shí)
// 默認(rèn)為false,表示只刪除指定KEY的值
boolean allEntries() default false;
// 方法調(diào)用前執(zhí)行標(biāo)識(shí)
// 默認(rèn)為false,表示方法成功調(diào)用(未拋出異常)后執(zhí)行;為true則方法調(diào)用前執(zhí)行
boolean beforeInvocation() default false;
}四、@Caching(不常用)
注解作用:@Caching 注解用于組合多個(gè)緩存操作。
注解屬性介紹:
- value: 包含多個(gè)緩存操作的數(shù)組;
- 簡(jiǎn)介:表示多個(gè)Cache注解的組注解;可作用于類和方法,作用于類上,則表示對(duì)該類的所有方法都有效;
4.1 案例
@Caching(
cacheable = {@Cacheable("books")},
put = {@CachePut("books")},
evict = {@CacheEvict("archivedBooks")}
)
public Book processBook(String id, Book details) {
// 業(yè)務(wù)邏輯
}4.2 核心源碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
// Cacheable集合
Cacheable[] cacheable() default {};
// CachePut集合
CachePut[] put() default {};
// CacheEvict集合
CacheEvict[] evict() default {};
}五、@CacheConfig
注解作用:@CacheConfig 注解用于在類級(jí)別提供緩存相關(guān)的共享配置。
注解屬性介紹:
- cacheNames: 指定類中所有緩存操作的默認(rèn)緩存名稱;
- keyGenerator: 指定默認(rèn)的緩存鍵生成器;
- condition: 指定類中所有緩存操作的默認(rèn)條件;
- 簡(jiǎn)介:提供在類層次上共享緩存相關(guān)配置的機(jī)制;只可作用于類上;
當(dāng)作用在某個(gè)類上,會(huì)給這個(gè)類中定義的所有緩存動(dòng)作提供默認(rèn)配置,當(dāng)然,具體緩存動(dòng)作的配置可覆蓋提供的默認(rèn)配置;
5.1 案例
@CacheConfig(cacheNames = "books", keyGenerator = "customKeyGenerator")
public class BookService {
// 類中的方法可以使用緩存注解
}5.2 核心源碼
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheConfig {
// 緩存KEY所在緩存的標(biāo)識(shí)符,支持多個(gè),CSV格式
String[] cacheNames() default {};
// KEY的生成器
String keyGenerator() default "";
// 緩存管理器
String cacheManager() default "";
// 緩存解析器
String cacheResolver() default "";
}六、@EnableCaching
簡(jiǎn)介:
表示啟用Spring的注解驅(qū)動(dòng)的緩存管理能力,和@Configuration配合使用;
必須創(chuàng)建CacheManager Bean,Spring框架不會(huì)提供默認(rèn)值;@EnableCaching會(huì)根據(jù)類型搜索CacheManager Bean,因此CacheManager Bean的命名并不重要;
可以實(shí)現(xiàn)CachingConfigurer接口的cacheManager()方法來創(chuàng)建@EnableCaching指定的CacheManager Bean,這種情況下需要明確提供KeyGenerator(@EnableCaching會(huì)默認(rèn)提供SimpleKeyGenerator);如果不需要自定義,可以考慮從CachingConfigurerSupport擴(kuò)展,它為所有方法提供了默認(rèn)實(shí)現(xiàn);
6.1 核心源碼
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
// 代理模式:CGLIB or JDK Interface
// 默認(rèn)為false,表示基于JDK Interface
// 設(shè)置為true,會(huì)影響所有需要代理的Spring管理的Bean
boolean proxyTargetClass() default false;
// 緩存應(yīng)用模式:Proxy or AspectJ
// Proxy模式只允許通過代理攔截調(diào)用,不會(huì)攔截同一類中的本地調(diào)用
// AspectJ模式下,proxyTargetClass()無效,會(huì)攔截同一類中的本地調(diào)用
AdviceMode mode() default AdviceMode.PROXY;
// 特定連接點(diǎn)應(yīng)用多個(gè)建議時(shí),緩存操作的執(zhí)行順序
int order() default Ordered.LOWEST_PRECEDENCE;
}到此這篇關(guān)于SpringCache源碼解析Annotation案例講解的文章就介紹到這了,更多相關(guān)SpringCache Annotation內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java編程中實(shí)現(xiàn)歸并排序算法的實(shí)例教程
這篇文章主要介紹了Java編程中實(shí)現(xiàn)歸并排序算法的實(shí)例教程,包括自底向上的歸并排序的實(shí)現(xiàn)方法介紹,需要的朋友可以參考下2016-05-05
java如何用反射將一個(gè)對(duì)象復(fù)制給另一個(gè)對(duì)象
這篇文章主要介紹了java如何用反射將一個(gè)對(duì)象復(fù)制給另一個(gè)對(duì)象問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Maven腳手架如何基于jeecg實(shí)現(xiàn)快速開發(fā)
這篇文章主要介紹了Maven腳手架如何基于jeecg實(shí)現(xiàn)快速開發(fā),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10

