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

使用Spring?Cache本地緩存示例代碼

 更新時間:2025年08月19日 09:07:12   作者:會飛的架狗師  
緩存是提高應用程序性能的重要手段,通過將頻繁訪問的數(shù)據(jù)存儲在內存中,可以減少數(shù)據(jù)庫訪問次數(shù),從而加速數(shù)據(jù)讀取,這篇文章主要介紹了使用Spring?Cache本地緩存的相關資料,需要的朋友可以參考下

一、Spring Cache簡介

Spring Cache 是 Spring 框架提供的一套聲明式緩存抽象層,通過注解方式簡化緩存操作,它通過在方法上添加注解(如 @Cacheable、@CacheEvict)來地管理緩存操作,無需手動編寫緩存邏輯。

它支持多種緩存實現(xiàn)(如 Caffeine、Redis、EhCache),并統(tǒng)一了緩存訪問的 API。

這里需要注意兩點:

  1. Spring Cache 只是一個聲明式的抽象緩存層,意思是它只提供了接口,不提供實現(xiàn)
  2. 具體的實現(xiàn)可以有很多,比如 Caffeine,Redis,EhCache 這些,只要實現(xiàn)了這些接口,就可以被 Spring Cache 使用。

核心特點:

  • 基于注解的聲明式緩存
  • 支持 SpEL 表達式
  • 自動與 Spring 生態(tài)集成
  • 支持條件緩存

二、基礎配置

1. 添加依賴

<!-- Spring Boot Cache Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!-- 如果使用Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 如果使用caffeine -->
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

2. 啟用緩存

在啟動類添加@EnableCaching注解:

@SpringBootApplication
@EnableCaching
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

3. 緩存配置方案

方案1:通過 yml 配置文件

spring:
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=500,expireAfterWrite=60s
    # 或者分開配置
    cache-names: users,products
    caffeine.spec: # 全局默認配置
      maximumSize=1000,
      expireAfterAccess=30m

方案2:自定義 Bean

@Configuration  // 標記這是一個Spring配置類
public class CacheConfig {

    /**
     * 創(chuàng)建并配置Caffeine緩存管理器
     *
     * @return CacheManager 實例,用于管理應用中所有緩存
     *
     * 主要配置參數(shù)說明:
     * - initialCapacity: 初始緩存空間大?。ㄌ嵘跏夹阅埽?
     * - maximumSize: 緩存最大容量(基于條目數(shù))
     * - expireAfterWrite: 寫入后過期時間(數(shù)據(jù)一致性優(yōu)先場景)
     * - recordStats: 開啟統(tǒng)計功能(用于監(jiān)控和調優(yōu))
     */
    @Bean
    public CacheManager cacheManager() {
        // 創(chuàng)建Caffeine緩存管理器實例
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();

        // 配置Caffeine緩存參數(shù)
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .initialCapacity(100)      // 初始容量100個條目
                .maximumSize(1000)          // 最大緩存1000個條目,超過后按LRU淘汰
                .expireAfterWrite(10, TimeUnit.MINUTES)  // 寫入10分鐘后過期
                .recordStats());           // 啟用緩存統(tǒng)計(命中率等)

        return cacheManager;
    }

    /**
     * 創(chuàng)建短期緩存實例(獨立于主緩存管理器)
     *
     * @return Cache 實例,適用于高頻訪問的臨時數(shù)據(jù)
     *
     * 典型使用場景:
     * - 高頻訪問的臨時數(shù)據(jù)
     * - 需要快速失效的驗證碼等
     * - 與其他緩存不同生命周期的數(shù)據(jù)
     */
    @Bean(name = "shortTermCache")  // 指定Bean名稱便于按名稱注入
    public Cache shortTermCache() {
        return Caffeine.newBuilder()
                .expireAfterWrite(1, TimeUnit.MINUTES)  // 1分鐘過期(短期存儲)
                .maximumSize(100)                       // 最大100個條目
                .build();                               // 構建Cache實例
    }
}

三、 緩存注解使用示例

  • @Cacheable:用于標記方法,表示該方法將結果緩存起來,下次調用時直接從緩存中獲取結果,而不需要重新執(zhí)行方法。
  • @CacheEvict:用于標記方法,表示該方法將清除緩存,通常用于刪除緩存。
  • @CachePut:用于標記方法,表示該方法將更新緩存,通常用于更新緩存。
  • @Caching:用于組合多個緩存注解,可以同時使用多個緩存注解。
  • @CacheConfig:用于標記類,表示該類中的所有方法將使用指定的緩存配置。

1.@Cacheable - 數(shù)據(jù)查詢緩存

/**
 * 根據(jù)ID獲取用戶信息(帶緩存)
 * @param id 用戶ID
 * @return 用戶對象,如果不存在返回null
 * 
 * @Cacheable 參數(shù)說明:
 * - value/cacheNames: 指定緩存名稱(對應Caffeine配置)
 * - key: 緩存鍵,使用SpEL表達式(#參數(shù)名引用方法參數(shù))
 * - unless: 條件表達式,當結果滿足條件時不緩存
 */
@Cacheable(value = "users", key = "#id", unless = "#result == null")
public User getUserById(Long id) {
    log.info("執(zhí)行數(shù)據(jù)庫查詢,用戶ID: {}", id);
    return userRepository.findById(id).orElse(null);
}

2.@CachePut - 更新數(shù)據(jù)并緩存

/**
 * 更新用戶信息(同時更新緩存)
 * @param user 用戶對象
 * @return 更新后的用戶對象
 * 
 * @CachePut 特點:
 * - 總是執(zhí)行方法體
 * - 用返回值更新緩存
 * - 適用于"先寫后讀"場景
 */
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
    log.info("更新用戶數(shù)據(jù): {}", user.getId());
    return userRepository.save(user);
}

3.@CacheEvict - 刪除緩存

/**
 * 刪除用戶(同時移除緩存)
 * @param id 用戶ID
 * 
 * @CacheEvict 參數(shù)說明:
 * - beforeInvocation: 是否在方法執(zhí)行前清除緩存(默認false)
 * - allEntries: 是否清空整個緩存區(qū)域(慎用)
 */
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
    log.info("刪除用戶: {}", id);
    userRepository.deleteById(id);
}

4. @Caching - 組合操作

組合操作允許在單個方法上同時使用多個緩存注解,以實現(xiàn)更復雜的緩存策略。

/**
* 更新用戶狀態(tài)(復雜緩存操作)
* @param userId 用戶ID
* @param status 新狀態(tài)
*
* 典型場景:
* - 更新用戶緩存
* - 同時失效用戶列表緩存
    */
    @Caching(
    put = @CachePut(value = "users", key = "#userId"),
    evict = @CacheEvict(value = "userList", allEntries = true)
    )
    public void updateUserStatus(Long userId, UserStatus status) {
    log.info("更新用戶{}狀態(tài)為{}", userId, status);
    userRepository.updateStatus(userId, status);
    }

5. 條件緩存 (condition/unless)

條件緩存允許在緩存注解中添加 SpEL 條件表達式,以控制緩存的觸發(fā)時機。

/**
 * 獲取用戶詳情(帶條件緩存)
 * @param id 用戶ID
 * 
 * 緩存條件說明:
 * - condition: 只有id>1000時才走緩存
 * - unless: 結果中status=DELETED時不緩存
 */
@Cacheable(value = "users", 
           key = "#id",
           condition = "#id > 1000",
           unless = "#result != null && #result.status == T(com.example.UserStatus).DELETED")
public User getUserDetail(Long id) {
    log.info("查詢用戶詳情: {}", id);
    return userRepository.findDetailById(id);
}

6. 異步緩存加載

/**
 * 獲取用戶訂單列表(異步緩存)
 * @param userId 用戶ID
 * 
 * @sync = true 表示:
 * - 多線程并發(fā)時,只有一個線程會執(zhí)行加載
 * - 其他線程等待結果
 */
@Cacheable(value = "orders", key = "#userId", sync = true)
public List<Order> getUserOrders(Long userId) {
    log.info("加載用戶{}訂單數(shù)據(jù)...", userId);
    return orderService.getOrdersByUser(userId);
}

四、特殊場景處理

1. 緩存空值防御

/**
 * 查詢用戶(防穿透處理)
 * @param name 用戶名
 * 
 * 特殊處理:
 * - 對null結果也進行緩存(特殊標記對象)
 * - 設置較短過期時間(配置文件中定義)
 */
@Cacheable(value = "usersByName", 
           key = "#name",
           unless = "#result == null || #result == T(com.example.CacheConstants).NULL_OBJECT")
public User getUserByName(String name) {
    User user = userRepository.findByName(name);
    return user != null ? user : CacheConstants.NULL_OBJECT;
}

2. 復合緩存鍵

/**
 * 獲取用戶在某系統(tǒng)的權限列表
 * @param userId 用戶ID 
 * @param systemCode 系統(tǒng)編碼(如:"OA", "CRM"等)
 * @return 權限字符串集合
 * 
 * 緩存Key設計說明:
 * 1. 使用復合Key結構:`用戶ID_系統(tǒng)編碼`(如:123_OA)
 * 2. 優(yōu)點:
 *    - 避免不同系統(tǒng)權限緩存沖突
 *    - 支持按用戶+系統(tǒng)維度獨立管理緩存
 * 3. 緩存條件:僅當結果非空時緩存
 */
@Cacheable(value = "userPermissions", 
           key = "#userId + '_' + #systemCode",
           unless = "#result == null || #result.isEmpty()")
public Set<String> getUserSystemPermissions(Long userId, String systemCode) {
    log.debug("查詢用戶[{}]在系統(tǒng)[{}]的權限", userId, systemCode);
    return permissionService.findPermissions(userId, systemCode);
}

/**
 * 獲取用戶角色列表(帶枚舉參數(shù)的Key示例)
 * @param userId 用戶ID
 * @param roleType 角色類型枚舉
 * 
 * 枚舉類型處理技巧:
 * 1. 調用枚舉的name()方法轉換為字符串
 * 2. 最終Key格式:`userId:roleType`(如:123:ADMIN)
 */
@Cacheable(value = "userRoles", 
           key = "#userId + ':' + #roleType.name()")
public List<Role> getUserRoles(Long userId, RoleType roleType) {
    return roleService.findByUserAndType(userId, roleType);
}

五、經(jīng)驗之談

  • 推薦為每個 @Cacheable 方法添加 unless 條件防御 null
  • 業(yè)務更新方法建議同時使用 @CachePut@CacheEvict
  • 高頻訪問數(shù)據(jù)考慮設置 sync=true

總結 

到此這篇關于使用Spring Cache本地緩存的文章就介紹到這了,更多相關Spring Cache本地緩存內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 實體類使用@Builder,導致@ConfigurationProperties注入屬性失敗問題

    實體類使用@Builder,導致@ConfigurationProperties注入屬性失敗問題

    這篇文章主要介紹了實體類使用@Builder,導致@ConfigurationProperties注入屬性失敗問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Intellij IDEA 查找接口實現(xiàn)類的快捷鍵

    Intellij IDEA 查找接口實現(xiàn)類的快捷鍵

    本文主要介紹了Intellij IDEA 查找接口實現(xiàn)類的快捷鍵,文中通過圖文示例介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-06-06
  • java實現(xiàn)簡單發(fā)送郵件功能

    java實現(xiàn)簡單發(fā)送郵件功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單發(fā)送郵件功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Spring AI集成DeepSeek的詳細步驟

    Spring AI集成DeepSeek的詳細步驟

    DeepSeek 作為一款卓越的國產(chǎn) AI 模型,越來越多的公司考慮在自己的應用中集成,對于 Java 應用來說,我們可以借助 Spring AI 集成 DeepSeek,非常簡單方便,本文給大家介紹了Spring AI集成DeepSeek的詳細步驟,需要的朋友可以參考下
    2025-02-02
  • Maven依賴管理的用法介紹

    Maven依賴管理的用法介紹

    依賴管理是項目管理中非常重要的一環(huán)。幾乎任何項目開發(fā)的時候需要都需要使用到庫。而這些庫很可能又依賴別的庫,這樣整個項目的依賴形成了一個樹狀結構,而隨著這個依賴的樹的延伸和擴大,一系列問題就會隨之產(chǎn)生
    2022-08-08
  • IDEA報錯java.lang.OutOfMemoryError:Java?heap?space的解決辦法

    IDEA報錯java.lang.OutOfMemoryError:Java?heap?space的解決辦法

    這篇文章主要給大家介紹了關于IDEA報錯java.lang.OutOfMemoryError:Java?heap?space的解決辦法,出現(xiàn)這個問題的主要原因是項目運行時的堆內存不足引起的報錯,需要的朋友可以參考下
    2024-02-02
  • Swing常用組件之多行文本區(qū)JTextArea

    Swing常用組件之多行文本區(qū)JTextArea

    這篇文章主要為大家詳細介紹了Swing常用組件之多行文本區(qū)JTextArea,感興趣的朋友可以參考一下
    2016-05-05
  • SpringBoot基于Swagger2構建API文檔過程解析

    SpringBoot基于Swagger2構建API文檔過程解析

    這篇文章主要介紹了SpringBoot基于Swagger2構建API文檔過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Java反射的定義和用法詳解

    Java反射的定義和用法詳解

    Java中的反射是指在程序運行時動態(tài)地獲取和操作類、方法、屬性等元素的能力。它使得我們可以在程序運行時獲取一個類的信息,并對其進行操作,需要的朋友可以參考下
    2023-05-05
  • JAVA讀取PDF、WORD文檔實例代碼

    JAVA讀取PDF、WORD文檔實例代碼

    本篇文章主要通過實例代碼介紹了JAVA讀取PDF、WORD文檔,需要的朋友可以參考下
    2017-04-04

最新評論

宣威市| 织金县| 社旗县| 武义县| 金寨县| 南涧| 长白| 香港 | 通许县| 桃园县| 会昌县| 北安市| 济南市| 淳化县| 宕昌县| 封丘县| 甘孜| 贞丰县| 古交市| 开原市| 徐州市| 台安县| 苍南县| 唐河县| 行唐县| 卓尼县| 营山县| 册亨县| 怀宁县| 多伦县| 琼结县| 淅川县| 昌图县| 阿巴嘎旗| 哈尔滨市| 团风县| 翁源县| 新蔡县| 信丰县| 攀枝花市| 邹平县|