漫畫:什么是 volatile 關(guān)鍵字?
827
2025-04-01
前言
前面有介紹過spring整合redis和redis的一些注意點(diǎn),在實(shí)際開發(fā)中,spring cache方便簡(jiǎn)化的緩存操作的大部分內(nèi)容。通過注解的方式實(shí)現(xiàn)緩存。
閱讀前推薦先閱讀:redis緩存介紹。和springboot整合redis
緩存抽象的核心是將緩存應(yīng)用于Java方法,從而根據(jù)緩存中可用的信息減少執(zhí)行次數(shù)。也就是說,每次調(diào)用目標(biāo)方法時(shí),抽象都會(huì)應(yīng)用一種緩存行為,該行為檢查該方法是否已針對(duì)給定參數(shù)執(zhí)行。
如果已執(zhí)行,則返回緩存的結(jié)果,而不必執(zhí)行實(shí)際方法。
如果該方法尚未執(zhí)行,則執(zhí)行該方法,并將結(jié)果緩存并返回給用戶,以便下次調(diào)用該方法時(shí),返回緩存的結(jié)果。
這樣,對(duì)于給定的一組參數(shù),昂貴的方法(無論是CPU還是IO)只能執(zhí)行一次,并且重用結(jié)果而不必再次實(shí)際執(zhí)行該方法。
在緩存框架出現(xiàn)之前,要么公司自己寫緩存框架造輪子,要么在每個(gè)service中手動(dòng)修改調(diào)用redis進(jìn)行存儲(chǔ)或者更新(刪除).一旦業(yè)務(wù)邏輯代碼有變,將造成不小的維護(hù)負(fù)擔(dān)。并且代碼量也很大,使得項(xiàng)目看起來很臃腫!
而spring cache的出現(xiàn)用于簡(jiǎn)化對(duì)緩存的操作,你只需要配置緩存的cacheManager,然后按照一些簡(jiǎn)單的序列化配置,在service層即可使用注解的形式對(duì)項(xiàng)目邏輯無侵入的調(diào)用緩存。
方法介紹
觸發(fā) 緩存填充。即:如果有緩存從緩存中直接拿數(shù)據(jù)(就不走service了),如果沒緩存那么就執(zhí)行service。將service中的值傳到緩存中(執(zhí)行service)。
多個(gè)名稱:緩存可能有一個(gè)名字或者多個(gè)名字,那么你可以@Cacheable("books")或者@Cacheable({"books", "isbns"})表示。
自定義key:大家對(duì)同一個(gè)接口進(jìn)行查詢,可能有多個(gè)參數(shù),那么你可以自定義key。類似@Cacheable(value = "getuser",key = "#username")這樣寫法,這個(gè)規(guī)則和mybatis注解很像,但也有點(diǎn)區(qū)別也可以自行拼湊。
條件緩存:有些數(shù)據(jù)你若不想所有都想走緩存,當(dāng)然也可以設(shè)置條件緩存,比如你若想讓兩個(gè)字的姓名緩存,那么你可以@Cacheable(value = "getuser",key = "#username",condition="#username.length() < 3")這樣寫法
上鎖:@Cacheable(value = "getuser",key = "#username",sync = true)對(duì)有些數(shù)據(jù),你可能不想讓他并發(fā)執(zhí)行,那么可以假設(shè)sync關(guān)鍵字。當(dāng)然,如果是分布式或者多臺(tái)服務(wù)器需要考慮分布式鎖實(shí)現(xiàn)。
@Cacheable(value = "getalluser") public List
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
觸發(fā) 緩存逐出。即刪除緩存。執(zhí)行之后將刪除緩存。
用法和前面相似@CacheEvict(value = "getuser",key = "#username")
但是若想刪除getuser下所有緩存目錄,那么加個(gè)參數(shù)@CacheEvict(value = "getuser",key = "#username",allEntries = true)其中allEntries就是刪除所有的意思。當(dāng)需要清除整個(gè)緩存區(qū)域時(shí),此選項(xiàng)會(huì)派上用場(chǎng)。而不是逐出每個(gè)條目。
更新緩存而不會(huì)干擾方法執(zhí)行。即:不管有沒有緩存。每次都執(zhí)行方法,將方法得到的數(shù)據(jù)更新到緩存之中。起到update的功能。
需要注意的是,在更新過程中可能有并發(fā)的存在。你可以設(shè)置鎖.參考Cacheable用法
重新組合要應(yīng)用于方法的多個(gè)緩存操作。
有時(shí),需要指定相同類型(例如@CacheEvict或 @CachePut)的多個(gè)注釋- 例如,因?yàn)椴煌?a target="_blank" href="http://m.bai1xia.com/news/tags-5931.html"style="font-weight:bold;">高速緩存之間的條件或鍵表達(dá)式不同。@Caching允許多個(gè)嵌套 @Cacheable,@CachePut和@CacheEvict注解相同的方法來使用。以下示例使用兩個(gè)@CacheEvict注釋:
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
此操作可能是一個(gè)方法操作更新、刪除不同的緩存。具體使用需要考慮情景。
在類級(jí)別共享一些常見的緩存相關(guān)設(shè)置。
此方法針對(duì)同一個(gè)類中一些共同操作,簡(jiǎn)便操作和代碼量。
到目前為止,我們已經(jīng)看到緩存操作提供了許多自定義選項(xiàng),您可以為每個(gè)操作設(shè)置這些選項(xiàng)。但是,如果某些自定義選項(xiàng)適用于該類的所有操作,則它們可能會(huì)很繁瑣。例如,指定用于類的每個(gè)高速緩存操作的高速緩存的名稱可以由單個(gè)類級(jí)定義替換。這是@CacheConfig 發(fā)揮作用的地方。以下示例用于@CacheConfig設(shè)置緩存的名稱:
@CacheConfig("books") public class BookRepositoryImpl implements BookRepository { @Cacheable public Book findBook(ISBN isbn) {...} }
1
2
3
4
5
6
具體整合
step1:創(chuàng)建springboot工程,省略部分截圖
step2:添加maven依賴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
step3: 配置application.properties
spring.redis.host=127.0.0.1 spring.redis.password= spring.redis.port= 6379 spring.redis.timeout=10000 spring.cache.type=redis logging.level.com.redisCache=debug spring.redis.database=3 spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
step4: config目錄下建立配置文件(緩存注入對(duì)象配置,以及序列化相關(guān)配置,和前文redis差不多)
這里面需要注意的是里面有關(guān)于redis的一些配置。在項(xiàng)目中防止多個(gè)項(xiàng)目公用一個(gè)redis可以在redis前面加個(gè)前綴(通常是項(xiàng)目名)。
過期時(shí)間一定要設(shè)置,并且過期策略還需要根據(jù)項(xiàng)目需求具體踩坑設(shè)置。
package com.redisCache.config; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.io.Serializable; import java.time.Duration; import java.util.*; @Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisConfiguration { @Bean public RedisTemplate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
step5:創(chuàng)建pojo對(duì)象和controller
pojo:
package com.redisCache.pojo; import java.io.Serializable; public class user implements Serializable { private String name; private String password; private String sex; public user(String name,String password,String sex) { this.name=name; this.password=password; this.sex=sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
service:
package com.redisCache.service; import com.redisCache.pojo.user; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class redisService { Logger logger= LoggerFactory.getLogger(redisService.class); @Cacheable(value = "getalluser") public List
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
controller:
package com.redisCache.controller; import com.redisCache.pojo.user; import com.redisCache.service.redisService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class redisController { private final static Logger log= LoggerFactory.getLogger(redisController.class); @Autowired(required = false) redisService redisService; @GetMapping("getalluser") public List
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
step6:在啟動(dòng)類加上允許緩存注解
測(cè)試與總結(jié)
getalluser:
getuser:
update:更新上一條
delete:整個(gè)移除(前面講到allentries參數(shù)作用,不妨自己測(cè)試)
可以看得到緩存的一些操作正常完成了
上文只是一個(gè)簡(jiǎn)單的整合過程,具體使用還需要自己踩坑才行。而緩存的深度遠(yuǎn)遠(yuǎn)不是這么簡(jiǎn)單,還需要自己挖掘。
項(xiàng)目完整github地址。不吝嗇star的大哥求個(gè)star。
最后,歡迎關(guān)注個(gè)人公眾號(hào):bigsai 關(guān)注后回復(fù) java 有精選資料一份!
Redis Spring Spring Boot
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。