springboot使用cache緩存

本文為轉(zhuǎn)載,原文地址:http://www.cnblogs.com/yueshutong/p/9381540.html ,歡迎訪問原文。

一:Spring緩存抽象

Spring從3.1開始定義了org.springframework.cache.Cacheorg.springframework.cache.CacheManager接口來統(tǒng)一不同的緩存技術(shù);并支持使用JCache(JSR-107)注解簡化我們開發(fā);

Cache接口為緩存的組件規(guī)范定義,包含緩存的各種操作集合;

Cache接口下Spring提供了各種xxxCache的實(shí)現(xiàn);如RedisCache,EhCacheCache ,ConcurrentMapCache等;

每次調(diào)用需要緩存功能的方法時(shí),Spring會檢查檢查指定參數(shù)的指定的目標(biāo)方法是否已經(jīng)被調(diào)用過;如果有就直接從緩存中獲取方法調(diào)用后的結(jié)果,如果沒有就調(diào)用方法并緩存結(jié)果后返回給用戶。下次調(diào)用直接從緩存中獲取。

使用Spring緩存抽象時(shí)我們需要關(guān)注以下兩點(diǎn);

  1. 確定方法需要被緩存以及他們的緩存策略
  1. 從緩存中讀取之前緩存存儲的數(shù)據(jù)

二:幾個重要概念&緩存注解

名稱 解釋
Cache 緩存接口,定義緩存操作。實(shí)現(xiàn)有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 緩存管理器,管理各種緩存(cache)組件
@Cacheable 主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其進(jìn)行緩存
@CacheEvict 清空緩存
@CachePut 保證方法被調(diào)用,又希望結(jié)果被緩存。與@Cacheable區(qū)別在于是否每次都調(diào)用方法,常用于更新
@EnableCaching 開啟基于注解的緩存
keyGenerator 緩存數(shù)據(jù)時(shí)key生成策略
serialize 緩存數(shù)據(jù)時(shí)value序列化策略
@CacheConfig 統(tǒng)一配置本類的緩存注解的屬性

@Cacheable/@CachePut/@CacheEvict 主要的參數(shù)

名稱 解釋
value 緩存的名稱,在 spring配置文件中定義,必須指定至少一個。例如:@Cacheable(value=”mycache”) 或者@Cacheable(value={”cache1”,”cache2”}
key 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進(jìn)行組合。例如:@Cacheable(value=”testcache”,key=”#id”)
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存/清除緩存例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
unless 否定緩存。當(dāng)條件結(jié)果為TRUE時(shí),就不會緩存。@Cacheable(value=”testcache”,unless=”#userName.length()>2”)
allEntries(@CacheEvict ) 是否清空所有緩存內(nèi)容,缺省為 false,如果指定為true,則方法調(diào)用后將立即清空所有緩存。例如:@CachEvict(value=”testcache”,allEntries=true)beforeInvocation(@CacheEvict)是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執(zhí)行的時(shí)候就清空緩存,缺省情況下,如果方法執(zhí)行拋出異常,則不會清空緩存

例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

三:SpEL上下文數(shù)據(jù)

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

名稱 位置 描述 示例
methodName root對象 當(dāng)前被調(diào)用的方法名 #root.methodname
method root對象 當(dāng)前被調(diào)用的方法 #root.method.name
target root對象 當(dāng)前被調(diào)用的目標(biāo)對象實(shí)例 #root.target
targetClass root對象 當(dāng)前被調(diào)用的目標(biāo)對象的類 #root.targetClass
args root對象 當(dāng)前被調(diào)用的方法的參數(shù)列表 #root.args[0]
caches root對象 當(dāng)前方法調(diào)用使用的緩存列表 #root.caches[0].name
Argument Name 執(zhí)行上下文 當(dāng)前被調(diào)用的方法的參數(shù),如findArtisan(Artisan artisan),可以通過#artsian.id獲得參數(shù) #artsian.id
result 執(zhí)行上下文 法執(zhí)行后的返回值(僅當(dāng)方法執(zhí)行后的判斷有效,如 unless cacheEvict的beforeInvocation=false) #result

注意:

1、當(dāng)我們要使用root對象的屬性作為key時(shí)我們也可以將“#root”省略,因?yàn)?code>Spring默認(rèn)使用的就是root對象的屬性。 如

@Cacheable(key = "targetClass + methodName +#p0")

2、使用方法參數(shù)時(shí)我們可以直接使用“#參數(shù)名”或者“#p參數(shù)index”。 如:

@Cacheable(value="users", key="#id")

@Cacheable(value="users", key="#p0")

SpEL提供了多種運(yùn)算符

類型 運(yùn)算符
關(guān)系 <,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne
算術(shù) +,- ,* ,/,%,^
邏輯 &&,||,!,and,or,not,between,instanceof
條件 ?: (ternary),?: (elvis)
正則表達(dá)式 matches
其他類型 ?.,?[…],![…],^[…],$[…]

以上的知識點(diǎn)適合你遺忘的時(shí)候來查閱,下面正式進(jìn)入學(xué)習(xí)!

四:開始使用

環(huán)境:Spring boot 2.0.3
IDE:IDEA

  1. 開始使用前需要導(dǎo)入依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
  1. 然后在啟動類注解@EnableCaching開啟緩存
@SpringBootApplication
@EnableCaching  //開啟緩存
public class DemoApplication{

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}
  1. 緩存@Cacheable
    @Cacheable注解會先查詢是否已經(jīng)有緩存,有會使用緩存,沒有則會執(zhí)行方法并緩存。
@Cacheable(value = "emp" ,key = "targetClass + methodName +#p0")
public List<NewJob> queryAll(User uid) {
    return newJobDao.findAllByUid(uid);
}

此處的value是必需的,它指定了你的緩存存放在哪塊命名空間。

此處的key是使用的spEL表達(dá)式,參考上章。這里有一個小坑,如果你把methodName換成method運(yùn)行會報(bào)錯,觀察它們的返回類型,原因在于methodNameStringmethohMethod

此處的User實(shí)體類一定要實(shí)現(xiàn)序列化public class User implements Serializable,否則會報(bào)java.io.NotSerializableException異常。

到這里,你已經(jīng)可以運(yùn)行程序檢驗(yàn)緩存功能是否實(shí)現(xiàn)。

深入源碼,查看它的其它屬性

我們打開@Cacheable注解的源碼,可以看到該注解提供的其他屬性,如:

String[] cacheNames() default {}; //和value注解差不多,二選一
String keyGenerator() default ""; //key的生成器。key/keyGenerator二選一使用
String cacheManager() default ""; //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
String condition() default ""; //條件符合則緩存
String unless() default ""; //條件符合則不緩存
boolean sync() default false; //是否使用異步模式
  1. 配置@CacheConfig
    當(dāng)我們需要緩存的地方越來越多,你可以使用@CacheConfig(cacheNames = {"myCache"})注解來統(tǒng)一指定value的值,這時(shí)可省略value,如果你在你的方法依舊寫上了value,那么依然以方法的value值為準(zhǔn)。

使用方法如下:

@CacheConfig(cacheNames = {"myCache"})
public class BotRelationServiceImpl implements BotRelationService {
    @Override
    @Cacheable(key = "targetClass + methodName +#p0")//此處沒寫value
    public List<BotRelation> findAllLimit(int num) {
        return botRelationRepository.findAllLimit(num);
    }
    .....
}

查看它的其它屬性

String keyGenerator() default "";  //key的生成器。key/keyGenerator二選一使用
String cacheManager() default "";  //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
  1. 更新@CachePut
    @CachePut注解的作用 主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進(jìn)行緩存,和 @Cacheable 不同的是,它每次都會觸發(fā)真實(shí)方法的調(diào)用 。簡單來說就是用戶更新緩存數(shù)據(jù)。但需要注意的是該注解的valuekey 必須與要更新的緩存相同,也就是與@Cacheable 相同。示例:
@CachePut(value = "emp", key = "targetClass + #p0")
public NewJob updata(NewJob job) {
    NewJob newJob = newJobDao.findAllById(job.getId());
    newJob.updata(job);
    return job;
}

@Cacheable(value = "emp", key = "targetClass +#p0")//清空緩存
public NewJob save(NewJob job) {
    newJobDao.save(job);
    return job;
}

查看它的其它屬性

String[] cacheNames() default {}; //與value二選一
String keyGenerator() default "";  //key的生成器。key/keyGenerator二選一使用
String cacheManager() default "";  //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
String condition() default ""; //條件符合則緩存
String unless() default ""; //條件符合則不緩存
  1. 清除@CacheEvict
    @CachEvict 的作用 主要針對方法配置,能夠根據(jù)一定的條件對緩存進(jìn)行清空 。
屬性 解釋 示例
allEntries 是否清空所有緩存內(nèi)容,缺省為 false,如果指定為true,則方法調(diào)用后將立即清空所有緩存 @CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執(zhí)行的時(shí)候就清空緩存,缺省情況下,如果方法執(zhí)行拋出異常,則不會清空緩存 @CachEvict(value=”testcache”,beforeInvocation=true)

示例:

@Cacheable(value = "emp",key = "#p0.id")
public NewJob save(NewJob job) {
    newJobDao.save(job);
    return job;
}

//清除一條緩存,key為要清空的數(shù)據(jù)
@CacheEvict(value="emp",key="#id")
public void delect(int id) {
    newJobDao.deleteAllById(id);
}

//方法調(diào)用后清空所有緩存
@CacheEvict(value="accountCache",allEntries=true)
public void delectAll() {
    newJobDao.deleteAll();
}

//方法調(diào)用前清空所有緩存
@CacheEvict(value="accountCache",beforeInvocation=true)
public void delectAll() {
    newJobDao.deleteAll();
}

其他屬性

String[] cacheNames() default {}; //與value二選一
String keyGenerator() default "";  //key的生成器。key/keyGenerator二選一使用
String cacheManager() default "";  //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
String condition() default ""; //條件符合則清空
  1. 組合@Caching
    有時(shí)候我們可能組合多個Cache注解使用,此時(shí)就需要@Caching組合多個注解標(biāo)簽了。
@Caching(cacheable = {
        @Cacheable(value = "emp",key = "#p0"),
        ...
},
put = {
        @CachePut(value = "emp",key = "#p0"),
        ...
},evict = {
        @CacheEvict(value = "emp",key = "#p0"),
        ....
})
public User save(User user) {
    ....
}

源碼地址:https://gitee.com/cnovel/demo

springboot使用ehcache緩存

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容