一. 介紹
Spring Cache 是 Spring 框架提供的緩存抽象層,它簡化了在應用中添加緩存功能的開發工作。通過 Spring Cache,開發者無需關注具體緩存實現的細節,只需通過注解就能快速實現方法級別的緩存管理。
核心特點
1. 與具體緩存實現解耦:
支持多種緩存技術(如 Caffeine、EhCache、Redis 等),可通過配置靈活切換
2. 注解驅動:
通過簡單的注解即可實現緩存的增、刪、改、查操作
3. 支持多種緩存操作
包括緩存數據存儲、讀取、更新和清除
4. 事務感知:
能與 Spring 事務結合,確保緩存與數據的一致性
核心注解說明
注解 | 作用 | 關鍵屬性 |
---|---|---|
@Cacheable | 緩存方法結果,優先從緩存讀取 | key :緩存鍵;condition :條件緩存 |
@CachePut | 執行方法后更新緩存(方法必執行) | key :緩存鍵 |
@CacheEvict | 從緩存中刪除數據 | key :刪除指定鍵;allEntries=true :刪除所有 |
@Caching | 組合多個緩存注解(如同時更新和刪除) | 包含?cacheable 、put 、evict ?等屬性 |
@CacheConfig | 類級別配置緩存名稱、鍵生成器等 | cacheNames :默認緩存名稱 |
二. 使用步驟
1.導入maven坐標
使用的緩存中間件為redis
<!-- Spring Cache 核心依賴 -->
<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>
2. 在Spring啟動類上添加@EnableCaching注解開啟緩存功能
@SpringBootApplication
@Slf4j
@EnableCaching//開啟緩存注解功能
public class SkyApplication {public static void main(String[] args) {SpringApplication.run(SkyApplication.class, args);log.info("server started");}
}
3. 在業務方法上使用緩存注解
@Service
@CacheConfig(cacheNames = "users") // 類級別統一指定緩存名稱
public class UserService {// 1. 查詢用戶:緩存結果,鍵為用戶 ID@Cacheable(key = "#id") // 緩存鍵 = id,如 "users::1"public User getUserById(Long id) {// 實際業務:查詢數據庫(僅第一次執行,后續從緩存獲取)System.out.println("查詢數據庫,用戶 ID:" + id);return userRepository.findById(id).orElse(null);}// 2. 更新用戶:更新緩存(方法始終執行,結果存入緩存)@CachePut(key = "#user.id") // 緩存鍵 = user.idpublic User updateUser(User user) {// 實際業務:更新數據庫System.out.println("更新數據庫,用戶 ID:" + user.getId());return userRepository.save(user);}// 3. 刪除用戶:清除緩存@CacheEvict(key = "#id") // 清除鍵 = id 的緩存public void deleteUser(Long id) {// 實際業務:刪除數據庫記錄System.out.println("刪除數據庫,用戶 ID:" + id);userRepository.deleteById(id);}// 4. 清除所有緩存(如批量刪除場景)@CacheEvict(allEntries = true) // 清除 "users" 緩存中所有數據public void clearAllUsersCache() {// 無需業務邏輯,僅用于清除緩存}
}
@Cacheable的執行邏輯:每次調用有這個注解的方法時,先去redis緩存中查詢數據,如果有,直接將緩存中的數據返回,不執行方法;如果沒有,執行方法,調用數據庫,將方法的返回值存入redis中,這樣一來,下次執行方法就不用查詢數據庫,提高了效率
@CacheEvict:在修改員工信息,批量刪除員工,啟用停用員工等場景下,會使用allEntries = true
(清空全部緩存)
現在有一個場景:一個公司內有幾個部門,部門下分別有各自的員工,redis中以部門id為鍵存儲員工信息,為什么刪除或者新增一個用戶就要將員工所在的部門的緩存清空呢,原因是這樣的增刪操作并不頻繁,而精確在redis中操作比較麻煩,且在刪除或者新增時,redis中的緩存已經和數據庫中的數據不一致,所以需要清空緩存,下次查詢操作時又將新的數據緩存到redis