最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot結(jié)合Redis實(shí)現(xiàn)緩存管理功能

 更新時間:2024年01月29日 11:51:45   作者:棒棒糖_  
本篇文章主要介紹spring boot緩存管理機(jī)制及相關(guān)概念,以及如何結(jié)合Redis實(shí)現(xiàn)緩存管理,文中通過代碼示例給大家介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下

一、概述

目標(biāo):

  • 熟悉Spring Cache基礎(chǔ)組件及作用
  • 熟悉Spring Cache常用注解及作用
  • 掌握SpringBoot結(jié)合Redis實(shí)現(xiàn)緩存管理

二、 Spring Cache基礎(chǔ)組件

  • keyGenerator

    keyGenerator 是用于生成緩存鍵(Cache Key)的組件。緩存鍵是用于在緩存中唯一標(biāo)識緩存數(shù)據(jù)的值。默認(rèn)情況下,Spring Cache 使用參數(shù)列表作為緩存鍵。但在某些情況下,如果需要自定義緩存鍵的生成邏輯,則可以創(chuàng)建自定義的 KeyGenerator 實(shí)現(xiàn)并配置到 Spring 中,如果沒有自定義的話Spring提供默認(rèn)的keyGenerator——SimplekeyGenerator,它會根據(jù)方法參數(shù)列表生成一個唯一的緩存 key。

  • cacheManager

    在 Spring Cache 框架中,CacheManager 是用于管理緩存實(shí)例的組件。它可以創(chuàng)建和管理多個緩存,每個緩存都有一個唯一的名稱。當(dāng)開發(fā)者在項目中配置了 Redis(或其他支持的緩存中間件),Spring 會自動使用相應(yīng)的 CacheManager 實(shí)現(xiàn),如 RedisCacheManager。 如果沒有配置任何緩存中間件,Spring 默認(rèn)會采用 SimpleCacheManager 作為緩存管理器。SimpleCacheManager 內(nèi)部使用 ConcurrentHashMap 來維護(hù)緩存數(shù)據(jù),它是一個線程安全的 HashMap 實(shí)現(xiàn)。這種情況下,并不需要額外的緩存中間件,Spring 會將緩存數(shù)據(jù)存儲在內(nèi)存中。

  • cacheResolver 和cacheManager作用一樣,使用時二選一

三、 緩存管理注解

  • @EnableCaching

    該注解用于啟用 Spring Framework 的緩存支持。通常在配置類上使用,表示開啟緩存機(jī)制。有一個可選參數(shù) proxyTargetClass,默認(rèn)值為 false,表示使用 JDK 動態(tài)代理實(shí)現(xiàn) AOP,如果設(shè)置為 true,則表示使用 CGLIB 代理進(jìn)行 AOP。

  • @CacheConfig

    @CacheConfig 注解用于配置緩存的公共屬性,如緩存名稱、緩存管理器等。可以在類級別上使用,表示該類中的所有方法都具有相同的緩存規(guī)則。 該注解可選參數(shù):

    • cacheNames:指定緩存名稱。
    • keyGenerator:指定緩存 key 生成策略。
    • cacheManager:指定緩存管理器。
  • @CacheAble

    @Cacheable 注解用于標(biāo)注方法的返回值可以被緩存,通常用于查詢操作。如果緩存中存在對應(yīng)的數(shù)據(jù),則直接從緩存中獲取數(shù)據(jù)返回,否則執(zhí)行方法并將返回值存入緩存中。該注解可選參數(shù):

    • cacheNames:指定緩存名稱。

    • key:指定緩存 key,需要使用 SpEL 表達(dá)式進(jìn)行動態(tài)計算,沒有指定的話,會使用keyGenerator

      • cacheNamekey 可以組合成最終用于在 Redis 等緩存中存儲數(shù)據(jù)的 key。通常情況下,cacheName 代表緩存的名稱,而 key 則用于標(biāo)識緩存中的具體數(shù)據(jù)。當(dāng)使用 @Cacheable(cacheNames = "myCache", key = "#user.id") 這樣的注解時,Spring 將會根據(jù)給定的 cacheNamekey 生成一個唯一的緩存 key,然后將方法返回的數(shù)據(jù)緩存到 Redis 中。
      • 例如,在 Redis 中可能會生成類似于 myCache::123 這樣的鍵來存儲緩存數(shù)據(jù),其中 myCache 是緩存名稱,123 則是根據(jù) #user.id 表達(dá)式計算得出的具體鍵值。
    • condition:指定一個 SpEL 表達(dá)式,當(dāng)條件為 true 時才會進(jìn)行緩存操作。

    • unless:指定一個 SpEL 表達(dá)式,當(dāng)條件為 false 時才會進(jìn)行緩存操作。

      • condition屬性是在方法執(zhí)行前計算的,因此無法獲取到方法返回結(jié)果。unless屬性是在方法執(zhí)行后計算的,因此可以拿到方法返回結(jié)果,即SpEL 表達(dá)式中可以使用#result獲取到方法返回值。
    • sync:指定緩存是否需要同步更新。默認(rèn)情況下,Spring Cache 不會對緩存進(jìn)行同步更新,即在多線程環(huán)境下可能會出現(xiàn)緩存不一致的問題。但是,如果我們希望在緩存更新時進(jìn)行同步操作,可以使用 sync 屬性來實(shí)現(xiàn)。

//當(dāng)方法被多個線程并發(fā)調(diào)用時,只有一個線程能夠執(zhí)行方法并更新緩存,其他線程會被阻塞,直到更新完成后才能繼續(xù)執(zhí)行。
@Cacheable(cacheNames = "myCache", key = "#id", sync = true)
public User getUserById(Long id) {
    //....
}
//注意:使用 `sync` 屬性會增加緩存訪問的時間和資源消耗,因此建議只在必要的情況下使用。另外,對于高并發(fā)場景,使用 `sync` 屬性可能會導(dǎo)致性能問題,因此需要謹(jǐn)慎使用。
  • 以下是常用的 SpEL 表達(dá)式及其說明:

    表達(dá)式說明
    #root代表被調(diào)用方法的參數(shù)列表
    #root.target代表被調(diào)用方法的目標(biāo)對象
    #root.caches代表方法調(diào)用對應(yīng)的緩存
    #root.methodName代表被調(diào)用方法的名稱
    #root.targetClass代表被調(diào)用方法所在的類
    #result代表方法調(diào)用的返回結(jié)果(僅在 @Cacheable 和 @CachePut 注解中有效)
    #argument代表方法的參數(shù),例如 #a0 代表第一個參數(shù),#p0 也代表第一個參數(shù)
    T(...)調(diào)用靜態(tài)方法,比如 T(java.lang.Math).PI
    方法調(diào)用直接調(diào)用方法,比如 hasPermission('read')
    集合訪問訪問數(shù)組、列表、集合等元素,比如 list[0]
    屬性訪問訪問對象的屬性,比如 [user.name]
  • @CachePut

    @CachePut 注解用于緩存標(biāo)注方法的返回值,不管緩存中是否存在相同的鍵值,通常用于增加或更新操作。在方法執(zhí)行后,將執(zhí)行結(jié)果緩存到指定的緩存中。

    該注解可選參數(shù):

    • cacheNames:同@Cacheable。
    • key:同@Cacheable。
    • condition: 同@Cacheable。
    • unless:同@Cacheable。
  • @CacheEvict

    @CacheEvict 注解用于標(biāo)注方法執(zhí)行后刪除緩存中的數(shù)據(jù),通常用于刪除操作。

    該注解可選參數(shù):

    • cacheNames:同@Cacheable
    • key:同@Cacheable。
    • condition:同@Cacheable。
    • allEntries:配合cacheNames一起使用,當(dāng) allEntries 屬性設(shè)置為 true 時,表示清除緩存中緩存名稱為cacheNames的所有條目。allEntries 默認(rèn)值為false,表示只刪除與該方法對應(yīng)的緩存條目。
      • 例如:@CacheEvict(cacheNames = "k1",allEntries = true),會刪除緩存中所有緩存名稱為k1的鍵值對。
    • beforeInvocation:當(dāng) beforeInvocation 屬性設(shè)置為 true 時,表示在方法執(zhí)行之前清除緩存;即使方法執(zhí)行出現(xiàn)異常,緩存仍然會被清除。當(dāng) beforeInvocation 屬性設(shè)置為 false (默認(rèn)值)時,表示在方法執(zhí)行之后清除緩存;如果方法執(zhí)行出現(xiàn)異常,緩存不會被清除。

四、 代碼示例

添加pom依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

數(shù)據(jù)緩存

@Service
@CacheConfig(cacheNames = "user")
public class CacheService {

    @CachePut(key = "'userId:' + #p0.userId")
    public User addUser(User user){
        System.out.println("添加成功:user = " + user);
        return user;
    }

    @Cacheable(key = "'userId:' + #p0")
    public User getUser(Integer userId){
        User userFromDB = getUserFromDB(userId);
        System.out.println("查詢成功: userId = " + userId);
        return userFromDB;
    }

    @CachePut(key = "'userId:' + #p0")
    public User update(Integer userId,User user){
        updateUserInDB(userId,user);
        System.out.println("更新成功:userId = " + userId);
        return user;
    }

    private void updateUserInDB(Integer userId,User user) {
        user.setUsername("DB_user");
    }

    private User getUserFromDB(Integer userId) {
        User user = new User();
        user.setUserId(userId);
        user.setUsername("DB_user");
        return user;
    }

    @CacheEvict(cacheNames = "k1",allEntries = true)
    public void del(int id){
    }
}

單元測試

@SpringBootTest
public class CacheServiceTest {
    @Resource
    private CacheService cacheService;
    private User user;

    @BeforeEach
    void initUser(){
        user = new User();
        user.setUserId(1);
        user.setUsername("zhang san");
        user.setNickname("xiao san");
        user.setPhone("18788888888");
    }

    @Test
    void addCacheTest(){
        cacheService.addUser(user);
    }
    @Test
    void getCacheTest(){
        User user = cacheService.getUser(1);
        System.out.println("user = " + user);
    }

    @Test
    void updateCacheTest(){
        cacheService.update(1,user);
    }

    @Test
    void delCacheTest(){
        cacheService.del(2);
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void key() {
        // 這里將緩存key都撈出來
        Set<String> keys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            Set<byte[]> sets = connection.keys("k*".getBytes());
            Set<String> ans = new HashSet<>();
            assert sets != null;
            for (byte[] b : sets) {
                ans.add(new String(b));
            }
            return ans;
        });
        System.out.println("keys = " + keys);
    }
}

總結(jié)

以上就是SpringBoot結(jié)合Redis實(shí)現(xiàn)緩存管理功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Redis緩存管理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring?cloud?eureka注冊原理-注冊失敗填坑筆記

    spring?cloud?eureka注冊原理-注冊失敗填坑筆記

    這篇文章主要介紹了spring?cloud?eureka注冊原理-注冊失敗填坑筆記,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會話項目實(shí)戰(zhàn)

    SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會話項目實(shí)戰(zhàn)

    本文主要介紹了SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會話項目實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java繼承關(guān)系中構(gòu)造器的使用詳解

    Java繼承關(guān)系中構(gòu)造器的使用詳解

    本文介紹了繼承關(guān)系中構(gòu)造器的使用要點(diǎn),創(chuàng)建子類對象時,必須先調(diào)用父類構(gòu)造器實(shí)現(xiàn)初始化,若父類無參構(gòu)造器被覆蓋,子類需用super顯式調(diào)用父類構(gòu)造器,且super須寫在構(gòu)造器首行,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • SpringBoot實(shí)現(xiàn)滑塊驗(yàn)證碼驗(yàn)證登陸校驗(yàn)功能詳解

    SpringBoot實(shí)現(xiàn)滑塊驗(yàn)證碼驗(yàn)證登陸校驗(yàn)功能詳解

    驗(yàn)證碼作為一種自然人的機(jī)器人的判別工具,被廣泛的用于各種防止程序做自動化的場景中。傳統(tǒng)的字符型驗(yàn)證安全性已經(jīng)名存實(shí)亡的情況下,各種新型的驗(yàn)證碼如雨后春筍般涌現(xiàn),今天給大家分享一篇SpringBoot實(shí)現(xiàn)滑塊驗(yàn)證碼
    2022-09-09
  • Java中的ReadWriteLock高效處理并發(fā)讀寫操作實(shí)例探究

    Java中的ReadWriteLock高效處理并發(fā)讀寫操作實(shí)例探究

    這篇文章主要為大家介紹了Java中的ReadWriteLock高效處理并發(fā)讀寫操作實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Java實(shí)現(xiàn)簡單的彈球游戲

    Java實(shí)現(xiàn)簡單的彈球游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡單的彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 解決Mybatis的serverTimezone時區(qū)出現(xiàn)問題

    解決Mybatis的serverTimezone時區(qū)出現(xiàn)問題

    這篇文章主要介紹了解決Mybatis的serverTimezone時區(qū)出現(xiàn)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 使用eclipse 實(shí)現(xiàn)將springboot項目打成jar包

    使用eclipse 實(shí)現(xiàn)將springboot項目打成jar包

    這篇文章主要介紹了使用eclipse 實(shí)現(xiàn)將springboot項目打成jar包的流程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • shardingsphere-jdbc5.5.1分庫分表實(shí)戰(zhàn)

    shardingsphere-jdbc5.5.1分庫分表實(shí)戰(zhàn)

    本文主要介紹了shardingsphere-jdbc5.5.1分庫分表實(shí)戰(zhàn),解決了分表和讀寫分離的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-01-01
  • SpringBoot項目部署的四種方式詳解

    SpringBoot項目部署的四種方式詳解

    本文詳細(xì)介紹了SpringBoot項目的四種部署方式,包括原始命令部署、寶塔Linux可視化部署、Docker容器化部署和Docker容器平臺托管,每種方式都有其特點(diǎn)和適用場景,需要的朋友可以參考下
    2026-04-04

最新評論

调兵山市| 高邑县| 韶关市| 和顺县| 遵化市| 车险| 德庆县| 秀山| 江陵县| 南投市| 镇赉县| 东阳市| 开封市| 仲巴县| 秦安县| 横山县| 鄂尔多斯市| 江阴市| 东阳市| 夏河县| 元江| 乐亭县| 连州市| 龙门县| 镇赉县| 丹寨县| 古丈县| 南昌县| 池州市| 揭西县| 保定市| 留坝县| 桂阳县| 海阳市| 顺平县| 宁德市| 密云县| 连州市| 柞水县| 永康市| 峡江县|