1、概述
Spring定義了org.springframework.cache.Cache 和org.springframework.cache.CacheManager接口來統一不一樣的緩存技術,並支持使用JCache(JSR-107)註解簡化咱們開發;java
-
Cache接口爲緩存的組件規範了定義,包含緩存的各類操做集合; -
Cache接口下Spring提供了各類xxxCache的實現;如RedisCache,EhCacheCache , ConcurrentMapCache等;
-
每次調用須要緩存功能的方法時,Spring會檢查指定參數所指定的目標方法是否 已經被調用過;若是有就直接從緩存中獲取方法調用後的結果,若是沒有就調用方法;並緩存結果後返回給用戶。下次調用直接從緩存中獲取。 -
使用Spring緩存抽象時咱們須要關注如下兩點;
-
[x] 肯定方法須要被緩存以及他們的緩存策略 -
[x] 從緩存中讀取以前緩存存儲的數據
2、經常使用註解及其參數
註解簡介
註解 | 功能 |
---|---|
@Cacheable | 主要針對方法配置,可以根據方法的請求參數對其結果進行緩存 |
@CacheEvict | 清空緩存 |
@CachePut | 對存入緩存的數據進行更新 |
@EnableCaching | 開啓基於註解的緩存 |
@Caching | 定義複雜的緩存規則 |
@Cacheable/@CachePut/@CacheEvict主要的參數
經常使用參數 | 功能介紹 | 使用 |
---|---|---|
value/cacheNames | 緩存的名稱,在spring配置文件中定義,必須指定至少一個 | @Cacheable(value ="user")或者 @Cacheable(value={"user","mycache"}; |
key | 緩存的key,能夠爲空,若是指定要按照SpEL表達式編寫,若是不指定,則缺省按照方法的全部參數進行組合 | @Cacheable(value = {"user"},key = "#id") |
condition | 緩存的條件,能夠爲空,使用SpEL編寫,返回true或者false,只有爲true才進行緩存/清除緩存,在調用方法以前以後都能判斷 | @Cacheable(value="user",condition="#id>2") |
allEntries(@CacheEvict) | 是否清空全部緩存內容,缺省爲false,若是指定爲true,則方法調用後將當即清空全部緩存 | @CachEvict(value="user",allEntries=true) |
beforeInvocation(@CacheEvict) | 是否在方法執行前就清空,缺省爲false,若是指定爲true,則在方法尚未執行的時候就清空緩存,缺省狀況下,若是方法執行拋出異常,則不會清空緩存 | @CachEvict(value="user",beforeInvocation=true) |
unless(@CachePut)(@Cacheable) | 用於否決緩存的,不像condition,該表達式只方法執行以後判斷,此時能夠拿到返回值result進行判斷。條件爲true不會緩存,fasle才緩存 | @Cacheable(value="user",unless="#result == null") |
sync | 是否支持異步 | @Cacheable(value = {"user"},key = "#id",sync = true) |
keyGenerator | 指定key的生成策略,不能和key同時使用 | @Cacheable(value ={"user"},keyGenerator = "myKeyGenerator") |
cacheManager | 用來指定緩存管理器 |
Cache SpEL available metadata(可用的緩存元數據)
名字 | 位置 | 描述 | 示例 |
---|---|---|---|
methodName | root object | 當前被調用的方法名 | #root.methodName |
method | root object | 當前被調用的方法 | #root.method.name |
target | root object | 當前被調用的目標對象 | #root.target |
targetClass | root object | 當前被調用的目標對象類 | #root.targetClass |
args | root object | 當前被調用的方法的參數列表 | #root.args[0] |
caches | root object | 當前方法調用使用的緩存列表(如@Cacheable(value={"cache1","cache2"})),則有兩個cache | #root.caches[0] |
argumentname | evaluation context | 方法參數的名字.能夠直接#參數名,也可使用#p0或#a0的形式,0表明參數的索引; | #iban、#a0、#p0 |
result | evaluation context | 方法執行後的返回值(僅當方法執行以後的判斷有效,如"unless" cache put’的表達式’cache evict’的表達式,beforeInvocation=false) | #result |
3、簡單的使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
package com.example.jpa.controller;
import com.example.jpa.entity.User;
import com.example.jpa.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class UserController {
@Autowired
private UserService userService;
@Cacheable(value = {"user"},key = "#id") //調用方法以前調用
@GetMapping("/user")
public User getUserById(@RequestParam Integer id){
return userService.getUserById(id);
}
@GetMapping("/users")
public List<User> getAll(){
return userService.getAll();
}
@Cacheable(value = "user",key = "#pageOffset")
@GetMapping("/usersByPage")
public Page<User> getAllByPage(@RequestParam Integer pageOffset,@RequestParam Integer pageSize){
return userService.getAll(PageRequest.of(pageOffset,pageSize));
}
@CachePut(value = "user",key = "#result.id") //即調用方法又更新緩存數據
@PostMapping("/user")
public User saveUser(@RequestBody User user){
return userService.saveUser(user);
}
//@CachePut(value = "user",key = "#result.id") //即調用方法又更新緩存數據
@Caching
@PutMapping("/user")
public User updateUser(@RequestBody User user){
return userService.updateUser(user);
}
@CacheEvict(value = "user",key = "#id")
@DeleteMapping("/user")
public void deleteUser(Integer id){
userService.deleteUserById(id);
}
}
在這裏碰到了一個問題,在更新數據的時候怎麼確保分頁裏面的緩存數據也隨之更新而不是返回更新前的數據?web
本文分享自微信公衆號 - 全民java空間(ljl236915692)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。spring