欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、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)集成
  • 支持條件緩存

二、基礎(chǔ)配置

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  // 標(biāo)記這是一個Spring配置類
public class CacheConfig {

    /**
     * 創(chuàng)建并配置Caffeine緩存管理器
     *
     * @return CacheManager 實例,用于管理應(yīng)用中所有緩存
     *
     * 主要配置參數(shù)說明:
     * - initialCapacity: 初始緩存空間大小(提升初始性能)
     * - maximumSize: 緩存最大容量(基于條目數(shù))
     * - expireAfterWrite: 寫入后過期時間(數(shù)據(jù)一致性優(yōu)先場景)
     * - recordStats: 開啟統(tǒng)計功能(用于監(jiān)控和調(diào)優(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();                               // 構(gòu)建Cache實例
    }
}

三、 緩存注解使用示例

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

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

/**
 * 根據(jù)ID獲取用戶信息(帶緩存)
 * @param id 用戶ID
 * @return 用戶對象,如果不存在返回null
 * 
 * @Cacheable 參數(shù)說明:
 * - value/cacheNames: 指定緩存名稱(對應(yīng)Caffeine配置)
 * - key: 緩存鍵,使用SpEL表達式(#參數(shù)名引用方法參數(shù))
 * - unless: 條件表達式,當(dāng)結(jié)果滿足條件時不緩存
 */
@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)更復(fù)雜的緩存策略。

/**
* 更新用戶狀態(tài)(復(fù)雜緩存操作)
* @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: 結(jié)果中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í)行加載
 * - 其他線程等待結(jié)果
 */
@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結(jié)果也進行緩存(特殊標(biāo)記對象)
 * - 設(shè)置較短過期時間(配置文件中定義)
 */
@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. 復(fù)合緩存鍵

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

/**
 * 獲取用戶角色列表(帶枚舉參數(shù)的Key示例)
 * @param userId 用戶ID
 * @param roleType 角色類型枚舉
 * 
 * 枚舉類型處理技巧:
 * 1. 調(diào)用枚舉的name()方法轉(zhuǎn)換為字符串
 * 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è)務(wù)更新方法建議同時使用 @CachePut@CacheEvict
  • 高頻訪問數(shù)據(jù)考慮設(shè)置 sync=true

總結(jié) 

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

相關(guān)文章

最新評論