国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

聊聊 緩存之王 Caffeine Cache

共 16334字,需瀏覽 33分鐘

 ·

2022-05-09 23:10

前面剛說到Guava Cache,他的優(yōu)點(diǎn)是封裝了get,put操作;提供線程安全的緩存操作;提供過期策略;提供回收策略;緩存監(jiān)控。當(dāng)緩存的數(shù)據(jù)超過最大值時(shí),使用LRU算法替換。這一篇我們將要談到一個(gè)新的本地緩存框架:Caffeine Cache。它也是站在巨人的肩膀上-Guava Cache,借著他的思想優(yōu)化了算法發(fā)展而來。

本篇博文主要介紹Caffine Cache 的使用方式,以及Caffine Cache在SpringBoot中的使用。

|?Caffine Cache 在算法上的優(yōu)點(diǎn)-W-TinyLFU

說到優(yōu)化,Caffine Cache到底優(yōu)化了什么呢?我們剛提到過LRU,常見的緩存淘汰算法還有FIFO,LFU:

  1. FIFO:先進(jìn)先出,在這種淘汰算法中,先進(jìn)入緩存的會(huì)先被淘汰,會(huì)導(dǎo)致命中率很低。
  2. LRU:最近最少使用算法,每次訪問數(shù)據(jù)都會(huì)將其放在我們的隊(duì)首,如果需要淘汰數(shù)據(jù),就只需要淘汰隊(duì)尾即可。仍然有個(gè)問題,如果有個(gè)數(shù)據(jù)在 1 分鐘訪問了 1000次,再后 1 分鐘沒有訪問這個(gè)數(shù)據(jù),但是有其他的數(shù)據(jù)訪問,就導(dǎo)致了我們這個(gè)熱點(diǎn)數(shù)據(jù)被淘汰。
  3. LFU:最近最少頻率使用,利用額外的空間記錄每個(gè)數(shù)據(jù)的使用頻率,然后選出頻率最低進(jìn)行淘汰。這樣就避免了 LRU 不能處理時(shí)間段的問題。

上面三種策略各有利弊,實(shí)現(xiàn)的成本也是一個(gè)比一個(gè)高,同時(shí)命中率也是一個(gè)比一個(gè)好。Guava Cache雖然有這么多的功能,但是本質(zhì)上還是對(duì)LRU的封裝,如果有更優(yōu)良的算法,并且也能提供這么多功能,相比之下就相形見絀了。

LFU的局限性?:在 LFU 中只要數(shù)據(jù)訪問模式的概率分布隨時(shí)間保持不變時(shí),其命中率就能變得非常高。比如有部新劇出來了,我們使用 LFU 給他緩存下來,這部新劇在這幾天大概訪問了幾億次,這個(gè)訪問頻率也在我們的 LFU 中記錄了幾億次。但是新劇總會(huì)過氣的,比如一個(gè)月之后這個(gè)新劇的前幾集其實(shí)已經(jīng)過氣了,但是他的訪問量的確是太高了,其他的電視劇根本無法淘汰這個(gè)新劇,所以在這種模式下是有局限性。

LRU的優(yōu)點(diǎn)和局限性?:LRU可以很好的應(yīng)對(duì)突發(fā)流量的情況,因?yàn)樗恍枰塾?jì)數(shù)據(jù)頻率。但LRU通過歷史數(shù)據(jù)來預(yù)測(cè)未來是局限的,它會(huì)認(rèn)為最后到來的數(shù)據(jù)是最可能被再次訪問的,從而給與它最高的優(yōu)先級(jí)。

在現(xiàn)有算法的局限性下,會(huì)導(dǎo)致緩存數(shù)據(jù)的命中率或多或少的受損,而命中略又是緩存的重要指標(biāo)。HighScalability網(wǎng)站刊登了一篇文章,由前Google工程師發(fā)明的W-TinyLFU——一種現(xiàn)代的緩存 。Caffine Cache就是基于此算法而研發(fā)。Caffeine 因使用?Window TinyLfu?回收策略,提供了一個(gè)近乎最佳的命中率?。

當(dāng)數(shù)據(jù)的訪問模式不隨時(shí)間變化的時(shí)候,LFU的策略能夠帶來最佳的緩存命中率。然而LFU有兩個(gè)缺點(diǎn):

首先,它需要給每個(gè)記錄項(xiàng)維護(hù)頻率信息,每次訪問都需要更新,這是個(gè)巨大的開銷;

其次,如果數(shù)據(jù)訪問模式隨時(shí)間有變,LFU的頻率信息無法隨之變化,因此早先頻繁訪問的記錄可能會(huì)占據(jù)緩存,而后期訪問較多的記錄則無法被命中。

因此,大多數(shù)的緩存設(shè)計(jì)都是基于LRU或者其變種來進(jìn)行的。相比之下,LRU并不需要維護(hù)昂貴的緩存記錄元信息,同時(shí)也能夠反應(yīng)隨時(shí)間變化的數(shù)據(jù)訪問模式。然而,在許多負(fù)載之下,LRU依然需要更多的空間才能做到跟LFU一致的緩存命中率。因此,一個(gè)“現(xiàn)代”的緩存,應(yīng)當(dāng)能夠綜合兩者的長(zhǎng)處。

TinyLFU維護(hù)了近期訪問記錄的頻率信息,作為一個(gè)過濾器,當(dāng)新記錄來時(shí),只有滿足TinyLFU要求的記錄才可以被插入緩存。如前所述,作為現(xiàn)代的緩存,它需要解決兩個(gè)挑戰(zhàn):

一個(gè)是如何避免維護(hù)頻率信息的高開銷;

另一個(gè)是如何反應(yīng)隨時(shí)間變化的訪問模式。

首先來看前者,TinyLFU借助了數(shù)據(jù)流Sketching技術(shù),Count-Min Sketch顯然是解決這個(gè)問題的有效手段,它可以用小得多的空間存放頻率信息,而保證很低的False Positive Rate。但考慮到第二個(gè)問題,就要復(fù)雜許多了,因?yàn)槲覀冎?,任何Sketching數(shù)據(jù)結(jié)構(gòu)如果要反應(yīng)時(shí)間變化都是一件困難的事情,在Bloom Filter方面,我們可以有Timing Bloom Filter,但對(duì)于CMSketch來說,如何做到Timing CMSketch就不那么容易了。TinyLFU采用了一種基于滑動(dòng)窗口的時(shí)間衰減設(shè)計(jì)機(jī)制,借助于一種簡(jiǎn)易的reset操作:每次添加一條記錄到Sketch的時(shí)候,都會(huì)給一個(gè)計(jì)數(shù)器上加1,當(dāng)計(jì)數(shù)器達(dá)到一個(gè)尺寸W的時(shí)候,把所有記錄的Sketch數(shù)值都除以2,該reset操作可以起到衰減的作用 。

W-TinyLFU主要用來解決一些稀疏的突發(fā)訪問元素。在一些數(shù)目很少但突發(fā)訪問量很大的場(chǎng)景下,TinyLFU將無法保存這類元素,因?yàn)樗鼈儫o法在給定時(shí)間內(nèi)積累到足夠高的頻率。因此W-TinyLFU就是結(jié)合LFU和LRU,前者用來應(yīng)對(duì)大多數(shù)場(chǎng)景,而LRU用來處理突發(fā)流量。

在處理頻率記錄的方案中,你可能會(huì)想到用hashMap去存儲(chǔ),每一個(gè)key對(duì)應(yīng)一個(gè)頻率值。那如果數(shù)據(jù)量特別大的時(shí)候,是不是這個(gè)hashMap也會(huì)特別大呢。由此可以聯(lián)想到 Bloom Filter,對(duì)于每個(gè)key,用n個(gè)byte每個(gè)存儲(chǔ)一個(gè)標(biāo)志用來判斷key是否在集合中。原理就是使用k個(gè)hash函數(shù)來將key散列成一個(gè)整數(shù)。

在W-TinyLFU中使用Count-Min Sketch記錄我們的訪問頻率,而這個(gè)也是布隆過濾器的一種變種。如下圖所示:

如果需要記錄一個(gè)值,那我們需要通過多種Hash算法對(duì)其進(jìn)行處理hash,然后在對(duì)應(yīng)的hash算法的記錄中+1,為什么需要多種hash算法呢?由于這是一個(gè)壓縮算法必定會(huì)出現(xiàn)沖突,比如我們建立一個(gè)byte的數(shù)組,通過計(jì)算出每個(gè)數(shù)據(jù)的hash的位置。比如張三和李四,他們兩有可能hash值都是相同,比如都是1那byte[1]這個(gè)位置就會(huì)增加相應(yīng)的頻率,張三訪問1萬(wàn)次,李四訪問1次那byte[1]這個(gè)位置就是1萬(wàn)零1,如果取李四的訪問評(píng)率的時(shí)候就會(huì)取出是1萬(wàn)零1,但是李四命名只訪問了1次啊,為了解決這個(gè)問題,所以用了多個(gè)hash算法可以理解為long[][]二維數(shù)組的一個(gè)概念,比如在第一個(gè)算法張三和李四沖突了,但是在第二個(gè),第三個(gè)中很大的概率不沖突,比如一個(gè)算法大概有1%的概率沖突,那四個(gè)算法一起沖突的概率是1%的四次方。通過這個(gè)模式我們?nèi)±钏牡脑L問率的時(shí)候取所有算法中,李四訪問最低頻率的次數(shù)。所以他的名字叫Count-Min Sketch。

|?使用

Caffeine Cache 的github地址:

https://github.com/ben-manes/caffeine

目前的最新版本是:

<dependency>
????<groupId>com.github.ben-manes.caffeinegroupId>
????<artifactId>caffeineartifactId>
????<version>2.6.2version>
dependency>

緩存填充策略

Caffeine Cache提供了三種緩存填充策略:手動(dòng)、同步加載和異步加載。

手動(dòng)加載

在每次get key的時(shí)候指定一個(gè)同步的函數(shù),如果key不存在就調(diào)用這個(gè)函數(shù)生成一個(gè)值。

/**
?????*?手動(dòng)加載
?????*?@param?key
?????*?@return
?????*/

public?Object?manulOperator(String?key)?{
????Cache?cache?=?Caffeine.newBuilder()
????????.expireAfterWrite(1,?TimeUnit.SECONDS)
????????.expireAfterAccess(1,?TimeUnit.SECONDS)
????????.maximumSize(10)
????????.build();
????//如果一個(gè)key不存在,那么會(huì)進(jìn)入指定的函數(shù)生成value
????Object?value?=?cache.get(key,?t?->?setValue(key).apply(key));
????cache.put("hello",value);

????//判斷是否存在如果不存返回null
????Object?ifPresent?=?cache.getIfPresent(key);
????//移除一個(gè)key
????cache.invalidate(key);
????return?value;
}

public?Function?setValue(String?key){
????return?t?->?key?+?"value";
}

同步加載

構(gòu)造Cache時(shí)候,build方法傳入一個(gè)CacheLoader實(shí)現(xiàn)類。實(shí)現(xiàn)load方法,通過key加載value。

/**
?????*?同步加載
?????*?@param?key
?????*?@return
?????*/

public?Object?syncOperator(String?key){
????LoadingCache?cache?=?Caffeine.newBuilder()
????????.maximumSize(100)
????????.expireAfterWrite(1,?TimeUnit.MINUTES)
????????.build(k?->?setValue(key).apply(key));
????return?cache.get(key);
}

public?Function?setValue(String?key){
????return?t?->?key?+?"value";
}

異步加載

AsyncLoadingCache是繼承自LoadingCache類的,異步加載使用Executor去調(diào)用方法并返回一個(gè)CompletableFuture。異步加載緩存使用了響應(yīng)式編程模型。

如果要以同步方式調(diào)用時(shí),應(yīng)提供CacheLoader。要以異步表示時(shí),應(yīng)該提供一個(gè)AsyncCacheLoader,并返回一個(gè)CompletableFuture。

?/**
?????*?異步加載
?????*
?????*?@param?key
?????*?@return
?????*/

public?Object?asyncOperator(String?key){
????AsyncLoadingCache?cache?=?Caffeine.newBuilder()
????????.maximumSize(100)
????????.expireAfterWrite(1,?TimeUnit.MINUTES)
????????.buildAsync(k?->?setAsyncValue(key).get());

????return?cache.get(key);
}

public?CompletableFuture?setAsyncValue(String?key){
????return?CompletableFuture.supplyAsync(()?->?{
????????return?key?+?"value";
????});
}

回收策略

Caffeine提供了3種回收策略:基于大小回收,基于時(shí)間回收,基于引用回收。

基于大小的過期方式

基于大小的回收策略有兩種方式:一種是基于緩存大小,一種是基于權(quán)重。

//?根據(jù)緩存的計(jì)數(shù)進(jìn)行驅(qū)逐
LoadingCache?cache?=?Caffeine.newBuilder()
????.maximumSize(10000)
????.build(key?->?function(key));


//?根據(jù)緩存的權(quán)重來進(jìn)行驅(qū)逐(權(quán)重只是用于確定緩存大小,不會(huì)用于決定該緩存是否被驅(qū)逐)
LoadingCache?cache1?=?Caffeine.newBuilder()
????.maximumWeight(10000)
????.weigher(key?->?function1(key))
????.build(key?->?function(key));

maximumWeight與maximumSize不可以同時(shí)使用。

基于時(shí)間的過期方式

//?基于固定的到期策略進(jìn)行退出
LoadingCache?cache?=?Caffeine.newBuilder()
????.expireAfterAccess(5,?TimeUnit.MINUTES)
????.build(key?->?function(key));
LoadingCache?cache1?=?Caffeine.newBuilder()
????.expireAfterWrite(10,?TimeUnit.MINUTES)
????.build(key?->?function(key));

//?基于不同的到期策略進(jìn)行退出
LoadingCache?cache2?=?Caffeine.newBuilder()
????.expireAfter(new?Expiry()?{
????????@Override
????????public?long?expireAfterCreate(String?key,?Object?value,?long?currentTime)?{
????????????return?TimeUnit.SECONDS.toNanos(seconds);
????????}

????????@Override
????????public?long?expireAfterUpdate(@Nonnull?String?s,?@Nonnull?Object?o,?long?l,?long?l1)?{
????????????return?0;
????????}

????????@Override
????????public?long?expireAfterRead(@Nonnull?String?s,?@Nonnull?Object?o,?long?l,?long?l1)?{
????????????return?0;
????????}
????}).build(key?->?function(key));

Caffeine提供了三種定時(shí)驅(qū)逐策略:

expireAfterAccess(long, TimeUnit):在最后一次訪問或者寫入后開始計(jì)時(shí),在指定的時(shí)間后過期。假如一直有請(qǐng)求訪問該key,那么這個(gè)緩存將一直不會(huì)過期。expireAfterWrite(long, TimeUnit): 在最后一次寫入緩存后開始計(jì)時(shí),在指定的時(shí)間后過期。expireAfter(Expiry): 自定義策略,過期時(shí)間由Expiry實(shí)現(xiàn)獨(dú)自計(jì)算。緩存的刪除策略使用的是惰性刪除和定時(shí)刪除。這兩個(gè)刪除策略的時(shí)間復(fù)雜度都是O(1)。

基于引用的過期方式

Java中四種引用類型

引用類型被垃圾回收時(shí)間用途生存時(shí)間
強(qiáng)引用 Strong Reference從來不會(huì)對(duì)象的一般狀態(tài)JVM停止運(yùn)行時(shí)終止
軟引用 Soft Reference在內(nèi)存不足時(shí)對(duì)象緩存內(nèi)存不足時(shí)終止
弱引用 Weak Reference在垃圾回收時(shí)對(duì)象緩存gc運(yùn)行后終止
虛引用 Phantom Reference從來不會(huì)可以用虛引用來跟蹤對(duì)象被垃圾回收器回收的活動(dòng),當(dāng)一個(gè)虛引用關(guān)聯(lián)的對(duì)象被垃圾收集器回收之前會(huì)收到一條系統(tǒng)通知JVM停止運(yùn)行時(shí)終止
//?當(dāng)key和value都沒有引用時(shí)驅(qū)逐緩存
LoadingCache?cache?=?Caffeine.newBuilder()
????.weakKeys()
????.weakValues()
????.build(key?->?function(key));

//?當(dāng)垃圾收集器需要釋放內(nèi)存時(shí)驅(qū)逐
LoadingCache?cache1?=?Caffeine.newBuilder()
????.softValues()
????.build(key?->?function(key));

注意:AsyncLoadingCache不支持弱引用和軟引用。

Caffeine.weakKeys():使用弱引用存儲(chǔ)key。如果沒有其他地方對(duì)該key有強(qiáng)引用,那么該緩存就會(huì)被垃圾回收器回收。由于垃圾回收器只依賴于身份(identity)相等,因此這會(huì)導(dǎo)致整個(gè)緩存使用身份 (==) 相等來比較 key,而不是使用 equals()。

Caffeine.weakValues() :使用弱引用存儲(chǔ)value。如果沒有其他地方對(duì)該value有強(qiáng)引用,那么該緩存就會(huì)被垃圾回收器回收。由于垃圾回收器只依賴于身份(identity)相等,因此這會(huì)導(dǎo)致整個(gè)緩存使用身份 (==) 相等來比較 key,而不是使用 equals()。

Caffeine.softValues() :使用軟引用存儲(chǔ)value。當(dāng)內(nèi)存滿了過后,軟引用的對(duì)象以將使用最近最少使用(least-recently-used ) 的方式進(jìn)行垃圾回收。由于使用軟引用是需要等到內(nèi)存滿了才進(jìn)行回收,所以我們通常建議給緩存配置一個(gè)使用內(nèi)存的最大值。softValues() 將使用身份相等(identity) (==) 而不是equals() 來比較值。

Caffeine.weakValues()和Caffeine.softValues()不可以一起使用。

移除事件監(jiān)聽

Cache?cache?=?Caffeine.newBuilder()
????.removalListener((String?key,?Object?value,?RemovalCause?cause)?->
?????????????????????System.out.printf("Key?%s?was?removed?(%s)%n",?key,?cause))
????.build();

寫入外部存儲(chǔ)

CacheWriter 方法可以將緩存中所有的數(shù)據(jù)寫入到第三方。

LoadingCache?cache2?=?Caffeine.newBuilder()
????.writer(new?CacheWriter()?{
????????@Override?public?void?write(String?key,?Object?value)?{
????????????//?寫入到外部存儲(chǔ)
????????}
????????@Override?public?void?delete(String?key,?Object?value,?RemovalCause?cause)?{
????????????//?刪除外部存儲(chǔ)
????????}
????})
????.build(key?->?function(key));

如果你有多級(jí)緩存的情況下,這個(gè)方法還是很實(shí)用。

注意:CacheWriter不能與弱鍵或AsyncLoadingCache一起使用。

統(tǒng)計(jì)

與Guava Cache的統(tǒng)計(jì)一樣。

Cache?cache?=?Caffeine.newBuilder()
????.maximumSize(10_000)
????.recordStats()
????.build();

通過使用Caffeine.recordStats(), 可以轉(zhuǎn)化成一個(gè)統(tǒng)計(jì)的集合. 通過 Cache.stats() 返回一個(gè)CacheStats。CacheStats提供以下統(tǒng)計(jì)方法:

hitRate():?返回緩存命中率

evictionCount():?緩存回收數(shù)量

averageLoadPenalty():?加載新值的平均時(shí)間

|?SpringBoot 中默?認(rèn)Cache-Caffine Cache

SpringBoot 1.x版本中的默認(rèn)本地cache是Guava Cache。在2.x(Spring Boot 2.0(spring 5)?)版本中已經(jīng)用Caffine Cache取代了Guava Cache。畢竟有了更優(yōu)的緩存淘汰策略。

下面我們來說在SpringBoot2.x版本中如何使用cache。

引入依賴

<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-cacheartifactId>
dependency>
<dependency>
????<groupId>com.github.ben-manes.caffeinegroupId>
????<artifactId>caffeineartifactId>
????<version>2.6.2version>
dependency>

添加注解開啟緩存支持

添加@EnableCaching注解:

@SpringBootApplication
@EnableCaching
public?class?SingleDatabaseApplication?{

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

配置文件的方式注入相關(guān)參數(shù)

properties文件

spring.cache.cache-names=cache1
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10s

或Yaml文件

spring:
??cache:
????type:?caffeine
????cache-names:
????-?userCache
????caffeine:
??????spec:?maximumSize=1024,refreshAfterWrite=60s

如果使用refreshAfterWrite配置,必須指定一個(gè)CacheLoader.不用該配置則無需這個(gè)bean,如上所述,該CacheLoader將關(guān)聯(lián)被該緩存管理器管理的所有緩存,所以必須定義為CacheLoader,自動(dòng)配置將忽略所有泛型類型。

import?com.github.benmanes.caffeine.cache.CacheLoader;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;

/**
?*?@author:?rickiyang
?*?@date:?2019/6/15
?*?@description:
?*/

@Configuration
public?class?CacheConfig?{

????/**
?????*?相當(dāng)于在構(gòu)建LoadingCache對(duì)象的時(shí)候?build()方法中指定過期之后的加載策略方法
?????*?必須要指定這個(gè)Bean,refreshAfterWrite=60s屬性才生效
?????*?@return
?????*/

????@Bean
????public?CacheLoader?cacheLoader()?{
????????CacheLoader?cacheLoader?=?new?CacheLoader()?{
????????????@Override
????????????public?Object?load(String?key)?throws?Exception?{
????????????????return?null;
????????????}
????????????//?重寫這個(gè)方法將oldValue值返回回去,進(jìn)而刷新緩存
????????????@Override
????????????public?Object?reload(String?key,?Object?oldValue)?throws?Exception?{
????????????????return?oldValue;
????????????}
????????};
????????return?cacheLoader;
????}
}
Caffeine常用配置說明:
initialCapacity=[integer]:?初始的緩存空間大小

maximumSize=[long]:?緩存的最大條數(shù)

maximumWeight=[long]:?緩存的最大權(quán)重

expireAfterAccess=[duration]:?最后一次寫入或訪問后經(jīng)過固定時(shí)間過期

expireAfterWrite=[duration]:?最后一次寫入后經(jīng)過固定時(shí)間過期

refreshAfterWrite=[duration]:?創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過固定的時(shí)間間隔,刷新緩存

weakKeys:?打開key的弱引用

weakValues:打開value的弱引用

softValues:打開value的軟引用

recordStats:開發(fā)統(tǒng)計(jì)功能

注意:

expireAfterWrite和expireAfterAccess同時(shí)存在時(shí),以expireAfterWrite為準(zhǔn)。

maximumSize和maximumWeight不可以同時(shí)使用

weakValues和softValues不可以同時(shí)使用

需要說明的是,使用配置文件的方式來進(jìn)行緩存項(xiàng)配置,一般情況能滿足使用需求,但是靈活性不是很高,如果我們有很多緩存項(xiàng)的情況下寫起來會(huì)導(dǎo)致配置文件很長(zhǎng)。所以一般情況下你也可以選擇使用bean的方式來初始化Cache實(shí)例。

下面的演示使用bean的方式來注入:

package?com.rickiyang.learn.cache;

import?com.github.benmanes.caffeine.cache.CacheLoader;
import?com.github.benmanes.caffeine.cache.Caffeine;
import?org.apache.commons.compress.utils.Lists;
import?org.springframework.cache.CacheManager;
import?org.springframework.cache.caffeine.CaffeineCache;
import?org.springframework.cache.support.SimpleCacheManager;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
import?org.springframework.context.annotation.Primary;

import?java.util.ArrayList;
import?java.util.List;
import?java.util.concurrent.TimeUnit;

/**
?*?@author:?rickiyang
?*?@date:?2019/6/15
?*?@description:
?*/

@Configuration
public?class?CacheConfig?{


????/**
?????*?創(chuàng)建基于Caffeine的Cache?Manager
?????*?初始化一些key存入
?????*?@return
?????*/

????@Bean
????@Primary
????public?CacheManager?caffeineCacheManager()?{
????????SimpleCacheManager?cacheManager?=?new?SimpleCacheManager();
????????ArrayList?caches?=?Lists.newArrayList();
????????List?list?=?setCacheBean();
????????for(CacheBean?cacheBean?:?list){
????????????caches.add(new?CaffeineCache(cacheBean.getKey(),
????????????????????Caffeine.newBuilder().recordStats()
????????????????????????????.expireAfterWrite(cacheBean.getTtl(),?TimeUnit.SECONDS)
????????????????????????????.maximumSize(cacheBean.getMaximumSize())
????????????????????????????.build()));
????????}
????????cacheManager.setCaches(caches);
????????return?cacheManager;
????}


????/**
?????*?初始化一些緩存的?key
?????*?@return
?????*/

????private?List?setCacheBean(){
????????List?list?=?Lists.newArrayList();
????????CacheBean?userCache?=?new?CacheBean();
????????userCache.setKey("userCache");
????????userCache.setTtl(60);
????????userCache.setMaximumSize(10000);

????????CacheBean?deptCache?=?new?CacheBean();
????????deptCache.setKey("userCache");
????????deptCache.setTtl(60);
????????deptCache.setMaximumSize(10000);

????????list.add(userCache);
????????list.add(deptCache);

????????return?list;
????}

????class?CacheBean?{
????????private?String?key;
????????private?long?ttl;
????????private?long?maximumSize;

????????public?String?getKey()?{
????????????return?key;
????????}

????????public?void?setKey(String?key)?{
????????????this.key?=?key;
????????}

????????public?long?getTtl()?{
????????????return?ttl;
????????}

????????public?void?setTtl(long?ttl)?{
????????????this.ttl?=?ttl;
????????}

????????public?long?getMaximumSize()?{
????????????return?maximumSize;
????????}

????????public?void?setMaximumSize(long?maximumSize)?{
????????????this.maximumSize?=?maximumSize;
????????}
????}

}

創(chuàng)建了一個(gè)SimpleCacheManager作為Cache的管理對(duì)象,然后初始化了兩個(gè)Cache對(duì)象,分別存儲(chǔ)user,dept類型的緩存。當(dāng)然構(gòu)建Cache的參數(shù)設(shè)置我寫的比較簡(jiǎn)單,你在使用的時(shí)候酌情根據(jù)需要配置參數(shù)。

使用注解來對(duì) cache 增刪改查

我們可以使用spring提供的?@Cacheable@CachePut、@CacheEvict等注解來方便的使用caffeine緩存。

如果使用了多個(gè)cahce,比如redis、caffeine等,必須指定某一個(gè)CacheManage為@primary,在@Cacheable注解中沒指定 cacheManager 則使用標(biāo)記為primary的那個(gè)。

cache方面的注解主要有以下5個(gè):

  • @Cacheable 觸發(fā)緩存入口(這里一般放在創(chuàng)建和獲取的方法上,@Cacheable注解會(huì)先查詢是否已經(jīng)有緩存,有會(huì)使用緩存,沒有則會(huì)執(zhí)行方法并緩存)
  • @CacheEvict 觸發(fā)緩存的eviction(用于刪除的方法上)
  • @CachePut 更新緩存且不影響方法執(zhí)行(用于修改的方法上,該注解下的方法始終會(huì)被執(zhí)行)
  • @Caching 將多個(gè)緩存組合在一個(gè)方法上(該注解可以允許一個(gè)方法同時(shí)設(shè)置多個(gè)注解)
  • @CacheConfig 在類級(jí)別設(shè)置一些緩存相關(guān)的共同配置(與其它緩存配合使用)

說一下@Cacheable?和?@CachePut的區(qū)別:

@Cacheable:它的注解的方法是否被執(zhí)行取決于Cacheable中的條件,方法很多時(shí)候都可能不被執(zhí)行。

@CachePut:這個(gè)注解不會(huì)影響方法的執(zhí)行,也就是說無論它配置的條件是什么,方法都會(huì)被執(zhí)行,更多的時(shí)候是被用到修改上。

簡(jiǎn)要說一下Cacheable類中各個(gè)方法的使用:

public?@interface?Cacheable?{

????/**
?????*?要使用的cache的名字
?????*/

????@AliasFor("cacheNames")
????String[]?value()?default?{};

????/**
?????*?同value(),決定要使用那個(gè)/些緩存
?????*/

????@AliasFor("value")
????String[]?cacheNames()?default?{};

????/**
?????*?使用SpEL表達(dá)式來設(shè)定緩存的key,如果不設(shè)置默認(rèn)方法上所有參數(shù)都會(huì)作為key的一部分
?????*/

????String?key()?default?"";

????/**
?????*?用來生成key,與key()不可以共用
?????*/

????String?keyGenerator()?default?"";

????/**
?????*?設(shè)定要使用的cacheManager,必須先設(shè)置好cacheManager的bean,這是使用該bean的名字
?????*/

????String?cacheManager()?default?"";

????/**
?????*?使用cacheResolver來設(shè)定使用的緩存,用法同cacheManager,但是與cacheManager不可以同時(shí)使用
?????*/

????String?cacheResolver()?default?"";

????/**
?????*?使用SpEL表達(dá)式設(shè)定出發(fā)緩存的條件,在方法執(zhí)行前生效
?????*/

????String?condition()?default?"";

????/**
?????*?使用SpEL設(shè)置出發(fā)緩存的條件,這里是方法執(zhí)行完生效,所以條件中可以有方法執(zhí)行后的value
?????*/

????String?unless()?default?"";

????/**
?????*?用于同步的,在緩存失效(過期不存在等各種原因)的時(shí)候,如果多個(gè)線程同時(shí)訪問被標(biāo)注的方法
?????*?則只允許一個(gè)線程通過去執(zhí)行方法
?????*/

????boolean?sync()?default?false;

}
基于注解的使用方法:
package?com.rickiyang.learn.cache;

import?com.rickiyang.learn.entity.User;
import?org.springframework.cache.annotation.CacheEvict;
import?org.springframework.cache.annotation.CachePut;
import?org.springframework.cache.annotation.Cacheable;
import?org.springframework.stereotype.Service;

/**
?*?@author:?rickiyang
?*?@date:?2019/6/15
?*?@description:?本地cache
?*/

@Service
public?class?UserCacheService?{


????/**
?????*?查找
?????*?先查緩存,如果查不到,會(huì)查數(shù)據(jù)庫(kù)并存入緩存
?????*?@param?id
?????*/

????@Cacheable(value?=?"userCache",?key?=?"#id",?sync?=?true)
????public?void?getUser(long?id){
????????//查找數(shù)據(jù)庫(kù)
????}

????/**
?????*?更新/保存
?????*?@param?user
?????*/

????@CachePut(value?=?"userCache",?key?=?"#user.id")
????public?void?saveUser(User?user){
????????//todo?保存數(shù)據(jù)庫(kù)
????}


????/**
?????*?刪除
?????*?@param?user
?????*/

????@CacheEvict(value?=?"userCache",key?=?"#user.id")
????public?void?delUser(User?user){
????????//todo?保存數(shù)據(jù)庫(kù)
????}
}

如果你不想使用注解的方式去操作緩存,也可以直接使用SimpleCacheManager獲取緩存的key進(jìn)而進(jìn)行操作。

注意到上面的key使用了spEL 表達(dá)式。Spring Cache提供了一些供我們使用的SpEL上下文數(shù)據(jù),下表直接摘自Spring官方文檔:

名稱位置描述示例
methodNameroot對(duì)象當(dāng)前被調(diào)用的方法名#root.methodname
methodroot對(duì)象當(dāng)前被調(diào)用的方法#root.method.name
targetroot對(duì)象當(dāng)前被調(diào)用的目標(biāo)對(duì)象實(shí)例#root.target
targetClassroot對(duì)象當(dāng)前被調(diào)用的目標(biāo)對(duì)象的類#root.targetClass
argsroot對(duì)象當(dāng)前被調(diào)用的方法的參數(shù)列表#root.args[0]
cachesroot對(duì)象當(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對(duì)象的屬性作為key時(shí)我們也可以將“#root”省略,因?yàn)镾pring默認(rèn)使用的就是root對(duì)象的屬性。如

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

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

@Cacheable(value="userCache",?key="#id")
@Cacheable(value="userCache",?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
其他類型?.,?[…],![…],^[…],$[…]


瀏覽 98
點(diǎn)贊
評(píng)論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)
評(píng)論
圖片
表情
推薦
點(diǎn)贊
評(píng)論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 国产探花视频在线免费观看| 亚洲中文字幕码mv| 影音先锋三级片| 久久午夜无码鲁片午夜精品男男| 狠狠干影院| av在线免费观看网址| 亚洲一区二区视频在线观看| 国产乱码在线| 一级AV| 国产美女av| av在线一区二区三区| 欧洲精品在线免费观看| 操美女影院| 国产一区二区av| 中文字幕+乱码+中文字幕在线| 91艹逼| 亚洲综合中文字幕在线播放| 日韩成人在线观看视频| 中文字幕在线观看完整av| 四虎www| 欧美一级AA大片免费看视频| 亚洲AV无码乱码AV| 国产高清视频在线| 麻豆视频一区二区| 性爱视频免费| 7799精品视频天天看| 国产主播AV| h在线| 久久一级片| 国产乱视频| 久久久久亚洲AV无码麻豆| 永久免费AV| 午夜成人精品一区二区三区| 久久午夜福利视频| 久久91| 91在线网址| 91麻豆免费视频网站| 成人A片在线| 日批国产| 亚洲黄色视频网站| 日韩欧美中文在线| 亚洲欧洲成人| 欧美日韩亚洲视频| 午夜福利视频3000| 人妻中文字幕av| 无码一区二区av| 成人做爰100片免费看| 在线一区二区三区四区| 七十路の高齢熟妇无码| 凹凸熟女凹凸BBWBBW| 亚洲无码蜜桃| 青娱乐日韩| 奇米av在线| 黄色福利| 熟女资源网| 好吊看视频| 女人的天堂网| 日本欧美亚洲| 中文字幕成人网站| 丁香一区二区| 色婷婷综合视频| 精品视频久久久久久| 婷婷五月天青草| 婷婷操逼| 欧美a视频| 黄色伊人网| 91九色首页| 99精品无码视频| AV大片在线观看| 在线播放a| 欧美日韩免费在线视频| 嫩BBB槡BBBB槡BBB小号| 操BBB操BBB| 免费看一区二区三区| 大鸡巴日小逼| 久久免费国产视频| 99国产精品99久久久久久粉嫩 | 成人精品A片免费网站| 高清无码免费视频| 日韩人妻中文字幕| 日本草逼视频| 日韩激情在线| 青草视频在线播放| 亚洲aa| 女人AV天堂| 狠狠操在线观看| 日本少妇做爱| 一本色道久久综合无码人妻软件 | 国产精品国产三级国产专业不| 国产高清做爱| 青青草无码在线| 在线观看黄a| 亚洲美女在线观看| 日韩黄色电影视频| 体内射精免费视频| 丝袜足交视频在线观看| 亚洲性爱工厂| 日本老妇操屄视频| 国产中文字幕AV在线播放| 亚洲无码影视| 日韩精品在线免费观看| 四虎网站| 欲色av| 亚洲成人一区二区三区| 青娱乐亚洲视频| 亚洲成人在线免费观看| 波多野结衣AV无码| 激情黄色五月天| 久久精品熟妇丰满人妻99| 波多野无码| 天天狠狠干| 精品交换一区二区三区无码| 99香蕉视频| 欧美香蕉在线| 午夜黄色电影| 东京热视频一区| 91成人福利| 成人乱无码AV在线观看| 91爽爽| 操逼操逼操逼操逼| 51成人网| 一级黄色电影网站| 黄色亚洲| 神马午夜福利视频| 77Q视频| 在线观看a片| 亚洲AⅤ| 国产一级视频| 色人阁人妻中文字幕| 成人免费毛片视频| 三级无码AV| 乱子伦一区二区三区视频在线观看| www99国产| 国产免费激情视频| 夜夜撸天天日| 特级特黄AAAA免费看| 巨乳国产一区| 波多野结衣无码电影| 操屄在线观看| 肏少妇女情人大骚逼直播一区二区| 亚洲的天堂的αⅴ| 黄色成人网站在线免费观看| 日本免费一区二区三区| 成人伊人网| 色色一区| 成人肏逼视频在线| 91精品酒店视频| 91精品国产综合久久久蜜臀图片| 婷婷亚洲五月色综合| 国产黄片在线视频| 国产综合区| 无码精品一区二区在线| 蜜桃av无码一区二区三区| 一区二区成人电影| 中文字幕AV无码| 中文字幕在线观看免费高清完整版在线观看 | 亚洲午夜福利电影| 9I成人免费版| 中文字幕一级A片免费看| 四虎2025在线51| 高清无码不卡AV| 久久亚洲影视| Av高清无码| 99国产在线观看免费视频| 亚洲成人无码网站| 啪啪视频最新地址发布页| 黄色激情视频网站| 国产一级二级三级| 国产激情在线观看| 五月丁香激情六月| 国产在线视频第一页| 国语一区| 人人操人人干人人看| 青娱乐老视频| 骚逼综合| 成人自拍偷拍| 国产牛牛在线| 日本久久不卡| 黄色一级大片在线免费看国产| 天天操比| 日本狠狠操| 亚洲网站视频| 久久久久久久国产精品| 99热最新| 国产免费av在线观看| 日本在线免费视频| 国产精品高| 亚洲成人五月天| 波多野在线视频| 日韩人妻精品无码久久| 高清无码视频在线观看| 高清无码不卡AV| 日韩精品一区二区三区在线观看免费 | 五月丁香成人网| 91AV电影| 美女操网站| 女人BBBB| 中文字幕一区二区三区在线观看 | 日本操逼电影| 123操逼| 亚洲va在线∨a天堂va欧美va| 亚洲黄色视频在线| 一本色道久久综合无码欧美| 欧美老妇性猛交| 亚洲黄色天堂| 中文字幕无码免费| 日韩一区二区三区四区久久久精品有吗 | 尤物视频网站在线观看| 91偷拍与自偷拍精品无码| 91人妻人人澡人人爽人人精品一| 综合网在线| 韩国成人免费无码免费视频| 国产精品对白| 精品无人区无码乱码毛片国产| 欧美乱伦一区| 亚洲影视中文字幕| 国产精品96久久久| 亚洲精品成人在线| v在线| 高清无码做爱视频| 777无码| 久热在线| 逼特逼视频网站| 老熟女搡BBBB搡BBBB视频| 黄色免费在线网站| www.91在线| 久久精品人妻| 天天操天天操天天操天天| 久久久久久少妇| 911国产精品| 日本黄网站| 美妇肥臀一区二区三区-久久99精品国 | 淫色五月| 色欲AV在线| 国产毛片久久久久久国产毛片 | 欧美性爱导航| 护士小雪的yin荡高日记H视频| 性爱免费视频| 91在线观看免费视频| 不卡视频一区| 张柏芝BBw搡BBBB槡BBBBHDfree | 免费在线观看毛片| 大香蕉福利视频导航| www.黄色av| 一区二区无码精品| 亚洲日韩Av无码中文字幕美国| 日欧美美女逼| 少妇搡BBBB搡BBB搡18禁| 少妇bbb搡bbbb搡bbbb| 国产毛片基地| gogogo高清在线观看免费直播中国 | 一区二区三区福利| 国产日韩一区二区| 香蕉视频国产| 人妻熟女视频| 香蕉视频久久| 欧美夜夜爽| 亚洲在线视频| 91国啪| 自拍偷拍综合网| 亚洲AV免费在线| 11孩岁女精品A片BBB| 国产三级片91| 亚洲无码专区在线观看| 四虎永久在线精品无码| 大香蕉AV电影| 围产精品久久久久久久| 亚洲精品秘一区二区三线观看| 国产精品无码毛片| 一区二区在线免费观看| 亚洲AV毛片| 成人做爰免费网站2023| www.久久精品视频| 视频在线观看一区| 亚洲欧美在线视频| 麻豆999| 成年人视频在线免费观看| 91人人爽| 中文字幕成人在线播放| 亚洲乱码中文字幕| 日本女人操逼视频| 西西4444www大胆无吗| 国产黄片免费视频| 污视频在线免费观看| 麻豆黄片| 牛牛精品一区| 亚洲第一福利视频| 亚洲aaaaaa| 91成人在线播放| 麻豆久久久| 亚洲视频在线免费| 久久国产激情| 先锋影音资源站| 日韩成人AV电影| 黄色成人网站在线播放| 人妻精品一卡二卡| 亚洲色图五月天| 在线视频免费观看| 午夜福利高清在线观看| 免费在线观看视频a| 午夜无码影院| 欧美视频免费在线观看| 最新中文字幕视频| 欧美日韩一级毛| 久射久| 国产精品AV片| 99久久久国产| 天堂一区二区| 秋霞午夜久久| 亚洲日韩中字| 不卡一二三区| 黑人一区二区| 成人AV天堂| 一区二区三区四区在线视频| 欧美日韩国内| 狠狠干| 黄色一级视频在线观看| 无码群交| 先锋影音亚洲AV每日资源网站| 国产精品AV在线观看| 国产色情性黄片Av网站| 激情一一区二区三区| 免费自拍视频| 爽好紧别夹喷水网站| 欧美中文字| 无码视频网| 国产精品99久久免费黑人人妻| 五月在线视频| 欧美爱| JULIA超乳JULIA无码| 动图综合亚洲综合欧美男男| av超碰在线| 性爱综合网| 色猫咪av| 五月婷婷欧美| 91丝袜在线| 亚洲的天堂的αⅴ| 青娱乐一级无码| 日韩色网站| 日韩v亚洲| 一级二级三级毛片| 丁香成人五月天| av黄色网| 少妇高潮喷水| 国产成人无码区免费视频| 不卡视频一区二区三区| 精品视频在线播放| 美女裸身18禁| 日韩黄色小说| 波多野结衣在线无码视频| 91人人人| www.91爱爱,com| 中国美女一级黄片| 双飞人妻13p| 手机看片1024你懂的| 91精品丝袜久久久久久久久久粉嫩 | 天天撸免费视频| 亚洲无码观看视频| 中文字幕一区二区三区人妻在线视频| 久操成人| 肏逼视频免费看| 无码中文字幕在线播放| 超碰自拍99| 加勒比精品在线| 成人性生交大片免费看小芳| 五月天欧美性爱| 99久久久成人国产精品| 日本豆花视频| 黄色小视频在线观看| 大陆搡BBBBB搡BBBBBB| 97自拍视频| 理论毛片| 国产色播| 91女色| 波多野结衣成人在线| 欧美老女人逼| 成人肏逼视频| 伊人成人网站| 在线观看国产小视频| 成人小说视频在线社区| 天堂网AV在线| AV无码国产| 久久成人小电影| AAA一区二区三区| 在线观看禁无码精品| 国产农村乱婬片A片AAA图片| 日本无码一区二区三区| 国产成人自拍偷拍视频| 操逼视频网| 东北老女人操逼| 欧美老女人操逼群| 99成人视频| 天天日天天干天天爽| 久草新在线| 在线播放91灌醉迷J高跟美女| 视频一区中文字幕| 亚洲AV无码成人精品久久久 | 日韩91在线视频| 91免费成人| 久久天堂av| 波多野结衣亚洲无码| 午夜福利日本| 99色| 免费一级AAAAA片在线播放| 国产操屄视频| 强开小嫩苞一区二区三区网站| 天天射天天爽| 91欧美精品成人AAA片| 安徽妇女BBBWBBBwm| 国产1区2区3区中文字幕| 羞羞色院91蜜桃| 黄片在线免费播放| 91AV久久| 北条麻妃无码在线播放| 亚洲欧美国产高清vA在线播放| 欧美成人图片视频在线| 人妻天天干| 乱人伦欲国语对白| 人妻精品一区二区三区| 日本黄色视频在线免费观看| 新亚洲天堂男子Av-| 日本99热| 九九re| 国产又粗又长| 久久6精品| 亚洲一区二区网站| 成人做爰黄A片免费看| 色婷婷亚洲| 亚洲国产精品二二三三区| 亚洲国产精品久久久久婷婷老年 | 人妻懂色av粉嫩av浪潮av| 伊人五月天激情| 亚洲国产视频一区| 午夜精品视频| 天天摸天天日| 水蜜桃成人在线| 日本电影一区二区| 中文字幕乱伦性爱| 亚洲无码一区二区三区| 五月婷婷成人| 人人摸人人看| 青青青草视频在线| 好好日视频| 欧美色图15p| 日韩大香蕉在线| 97人人爽人人爽人人爽| 成人精品鲁一鲁一区二区| 再深点好爽灬轻点久久国产| 久久亚洲AV无码午夜麻豆| 夜夜欢天天干| 日韩乱伦av| 午夜无码久久| 精品国产av| 巨爆乳肉感一区二区三区| AV777777| 大鸡吧在线| 久久亚洲免费视频| 手机AV在线| 韩日一区二区三区| 久久免费成人| 国产黄色网页| 美女视频毛片| 欧美在线观看网站18| 黄色国产av| 蜜臀久久99精品久久久| 亚洲国产另类精品| 无码视频观看| 国产精品宾馆在线| 国产一级精品视频| 久草免费在线观看视频| 污污污污污www网站免费民国| 人妻少妇无码| 国产精品内射视频| 男女做爱无码| 久久精品在线观看| 免费A网站| 草逼毛片| 丁香花在线小说免费阅读| 中文字幕日韩欧美| 黄色免费在线观看| 成年人黄色视频| 午色婷婷国产无码| 亚洲无码网| 日韩91在线| 成人A片免费在线观看| 激情麻豆论坛| 婷婷五月天亚洲| 亚洲日韩三级片| 大香蕉青青| 黄色内射在线播放| 麻豆网站| 亚洲精品视频在线观看免费| 欧美黄色影院| 神马影院午夜福利| 吃奶做爱视频| 婷婷色色五月天图片| 久草中文视频| www.91com| 国产在线视频第一页| 一级片免费在线观看| 国产成人一级片| 亚洲a电影| 色色色色网| 欧美黄色A片| 色吧超碰| 蜜桃av秘一区二区三区| 午夜日逼| www.激情| va婷婷在线免费观看| 黄色成年人视频在线观看| 超碰91在线| 欧美性猛交XXXX乱大交蜜桃| 久久成人三级片| 蜜桃人妻无码AV天堂三区| 欧美aaaaaa| 免费黄色成人网站| 麻豆mdapp03.tⅴ| 青青草成人电影| 日韩精品中文字幕在线观看| 免费AV网站观看| 另类一区| 91乱子伦国产乱子伦海的味道 | 成人午夜福利高清视频| 99久免费视频| 欧美精品xxx| jizz国产精品| 懂色av懂色av粉嫩av| 麻豆videos| 国产无码电影| 农村少妇久久久久久久| 草莓av| 青草视屏| 啊啊嗯嗯视频| 国产高清在线视频| 亚洲成人免费在线观看| 色欲五月天| 曰韩精品| 国产人成视频免费观看| 欧美视频一区二区| 久久噜噜噜精品国产亚洲综合| 乱伦视频91| 亚洲精品久久久久久久蜜桃| 亚洲欧美熟妇久久久久久久久 | 成人在线精品视频| 久热青草| 久久婷婷网站| 精品人妻一区二区三区日产乱码| 操逼日爱| 永久免费黄色| 人人草人人操| 精品成人久久| 日本高清久久| 天堂久久av| 亚洲小视频| 爱爱视频免费| 人操人操人操| 久久黄色成人视频| 亚州加勒比无码| 欧美中文字幕在线| 亚洲免费性爱视频| 97精品在线视频| 国产h在线| 无码爆操| 88av在线播放| 国产无码久久久| 欧美激情DVD| 一级黄色A片| 欧美成人视频网站| 成人做爰黄AAA片免费直播岛国| 男女视频91| 91大神在线观看入口| 伊人久久五月| 在线免费观看av片| 夏目あきら被续侵犯7天| 日本伊人在线综合视频| 亚洲中文在线视频| 亚洲午夜视频在线观看| 免费视频91蜜桃| 一区二区三区免费在线| 香蕉视频成人在线| 黄色大片在线| 黄色三级A片| 国产日韩欧美成人| 亚洲国精产品| 国产偷拍精品视频| 亚洲在线视频| 日韩一页| 在线观看污视频| 婷婷丁香激情| 中文在线a√在线8| 久久99人妻无码精品一区| 69福利网| 午夜无码三级| 人妻黑人一区二区三区| 能看毛片的网站| 无码人妻丰满熟妇啪啪| 最新中文字幕在线播放| 亚洲影院中文字幕| 人人看人人摸| 欧美成人一区二区三区| 女人天堂AV| 亚州毛片| 色婷婷亚洲综合| 老熟女一区二区三区| 18久久| 日韩婬乱片A片AAA真人视频| www.a片| 亚洲无码AV在线观看| 国产无码高清在线| 人妻人操| 999福利视频| 91精品少妇| 在线观看AⅤ| 国产一区免费观看| 麻豆videos| 阿拉伯三级片| 国产91白浆四溢| 在线观看av网站中文字幕| 强开小嫩苞一区二区三区视频| 日韩无码久久| 日本三级在线| 久久久久久久国产精品| 免费看一级一级人妻片| 黄色视频视频| 亚洲免费在线视频观看| 豆花视频成人精品视频| 精品人妻二区中文字幕| 色色色777| 美女久久久| 黄片天堂| 婷婷九月| 成人精品无码免费视频| 日韩大香蕉在线| 午夜精东影业传媒在线观看| 熟妇在线| 美女操逼网站| AV无码中文| 天堂在线www| A片视频免费观看| 无套免费视频欧美| 午夜乱论| 九九久久综合| 老太色HD色老太HD| 中文字幕天天干| 国产欧美综合在线| 91久久国产综合久久91精品网站| 国产av不卡| 无码人妻在线| 在线观看成年人视频| 内射视频免费观看| 色色777| 丰满老妇高潮一级A片| 日韩无码人妻一区二区| 亚洲你懂的| 欧美成人精品欧美一级私黄| av大全在线观看| 欧美亚洲激情| 久久激情视频| 国产成人精品三级麻豆| 人妻综合网| 久久草在线观看| 足浴小少妇-88AX| 鸡巴网站| 大香蕉一区| 国产黄色电影| 青草伊人av| 一本色道88久久加勒比精品| 69午夜| 美女网站色| 色哟哟视频在线观看| 亚洲日韩精品欧美一区二区yw| 色婷婷在线视频播放| 婷婷成人在线| 日日久视频| 91涩| 中文字幕免费AV| 国产又猛又黄又爽| 精品久久一区二区| 黄色AV网| 精品乱子伦一区二区三区免费播放 | 国产欧美综合在线| 欧美一级免费观看| 国产黄A片免费网站免费| 免费成人毛片| 88av在线| 日韩在线一区二区| 东京热综合影院| 韩日A片| 成人毛片在线大全免费| 成人国产无码| 无码熟妇人妻无码AV在线天堂| 亚洲狼人综合网| 国产操逼图| 人人看人人摸人人搞| 亚欧洲精品在线视频免费观看 | 吃奶做爱视频| 亚洲色图网站| 操逼操逼视频| 麻豆亚洲AV成人无码久久精品| 伊人久久免费| 狠狠操AV| 操逼视频大全| 久久无码区| 人妻av一区二区三区| 夜夜撸夜夜| 东京热日韩无码| 特级西西444www无码视频免费看| 性爱视频小说| 天天色影院| 日韩精品成人无码免费| 国产精品99久久久久的广告情况| 欧美黄色电影网站| 日韩一级| 亚洲中文字幕日韩在线| 91一级A片在线观看| 91色在线视频| 91爱在线| ww久久| 大鸡巴视频在线观看| 欧美日韩精品在线观看| 黄片网站在线观看| 日韩精品一区二区三免费视频| 国产精品黄视频| 日韩国产免费| 熟妇槡BBBB槡BBBB图| 一级一级一级做a免费一级做a| 人妻无码在线视频| 99精品免费视频| 不迷路福利视频| 欧美激情婷婷| 国产精品香蕉国产| 日韩,变态,另类,中文,人妻| 中文在线字幕免费观| 91丨国产丨熟女熟女| 国产成人精品一区二三区熟女在线 | 在线免费观看黄色网址| 亚洲男人的天堂av| 亚洲日韩欧美在线观看| 99热这里只有精品1| 国产a√| 福利一区二区视频网| 大香蕉第一页| 五月天无码免费视频| 成人久久综合| 熟女嗷嗷叫高潮合集91| 欧美中文字幕在线视频| 日日碰狠狠| 人妻少妇91精品一区黑人| 国产精品免费一区二区三区四区视频 | 少妇AV| 麻豆亚洲AV成人无码久久精品| 日韩在线综合| 成人无码视频| 日本色情网| 午夜福利在线播放| 国产精品秘久久久久久一两个一起| 成人肏屄视频| 国产黄片在线免费观看| 亚洲性爱工厂| 色就色欧美| 国产在线播放91| 99久在线精品99re8| 免费无码一区二区三区| 日韩群交| 骚骚网站| 老熟女伦一区二区三区| 亚洲色综合久久五月| 人妻视频网| 黄色大片AV在线| 热久久视频| 天天爽夜夜爽夜夜爽精品| 亚洲精品中文字幕在线观看 | 成人免费黄色网| 久久久久久久麻豆| 影音先锋男人资源站| 激情亚洲| 日本欧美成人片AAAA| 中文字字幕在线| 高清无码做爱视频| 天天干天天干天天日| 亚卅毛片| av播播| 国产免费av片| 黄色一级片免费看| 日皮视频在线观看| 操美女的逼| 精品无码蜜桃| 人妻熟妇乱子伦精品无码专区毛片| 免费a在线观看| www,操逼| 无码人妻久久一区二区三区蜜桃 | 麻豆黄色片| 大香蕉一级片| 熊猫AⅤ| 亚洲字幕AV| 十八禁视频在线观看网站.www| 欧美亚洲天堂网| 波多野结衣网站| 国产字幕在线观看| 丰满人妻一区二区三区四区54 | 高清无码在线不卡| 影音先锋自拍| 女生操网站| 久热国产在线| 51av在线| 欧美黄片网站| 成人亚洲网| 久久精品秘一区二区三免费| 国产精品久久精品| 亚洲AV日韩AV永久无码网站| 蜜桃无码视频小说网站| 18禁污网站| 国产午夜在线观看| 亚洲日色| 色婷婷激情在线| 五月天精品| 18一20女一片毛片| 亚洲视频日韩在线观看| 狠狠色噜噜狠狠狠888| 性生活黄色视频| 爱爱91| 98无码人妻精品一区二区三区| 波多野结衣av在线观看| 日本成人三级片| 狼友在线视频| 国产一级A片免费播放| 熟女3P| 日本无码在线播放| A级片黄色片| 色吧av| 亚洲精品成人在线| 日韩综合色视频导航| 青娱乐在线精品| 一区二区三区无码高清| 欧美丰满人妻免费视频人| 91夜夜夜| 91精品国产一区二区三区| 欧美亚洲激情| 女神思瑞精品一区二区三区| 欧美国产中文| 女人18片毛片60分钟黃菲菲| 山东熟妇搡BBBB搡BBBB| 亚洲va欧美va| 狠狠插视频| 国产熟女视频| 白嫩无码| 欧美日韩国产激情| 91豆花视频| 中字av| 中文字幕精品在线视频| 久久久久免费视频| 日韩操逼视频| 久久免费看| 欧美网站在线观看| 成人黄色免费视频| 丁香六月婷婷综合| 欧美va视频| 成人精品视频在线| 夜夜国自一区| 日韩欧美黄色片| 蜜臀AV在线播放| 久久av一区二区三区| 天堂无吗| 亚洲精品中文字幕成人片| 操B无码| 蝌蚪窝视频网| 蜜桃视频免费网站| 日韩精品人妻中文字幕有| 中文字幕无码在线播放| 无码av网| 无码在线不卡| 国产成人久久| 你懂得视频在线观看| 在线成人av| 中文字幕福利电影| 91免费福利视频| 青青操逼视频| 狠狠大香蕉| 日韩一区二区不卡| 亚洲无码影音先锋| 日本人妻在线播放| 国产无遮挡又黄又爽| 麻豆一级片| 一级黄色电影免费在线观看| 蝌蚪窝视频在线| 亚洲丁香五月激情| www.亚洲视频| 国产秘久久一区二区| 丰满人妻一区二区三区精品高清| 91在线成人| 熟女导航| 精品久久大香蕉| 大香蕉精品视频| 无码人妻丰满熟妇区毛片蜜桃麻豆 | 操碧一区| A级片网站| 欧美人操逼| 丁香花免费高清视频小说完整| 国产v视频| 青娱乐三级在线免|