在SpringBoot中主要有以下幾種注解:
一.總覽
| Cache | 緩存接口,定義緩存操作。實現(xiàn)有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
|---|---|
| CacheManager | 緩存管理器,管理各種緩存(Cache)組件 |
| @Cacheable | 主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存 |
| @CacheEvict | 清空緩存 |
| @CachePut | 保證方法被調(diào)用,又希望結(jié)果被緩存。 |
| @EnableCaching | 開啟基于注解的緩存,用于Config文件 |
| keyGenerator | 緩存數(shù)據(jù)時key生成策略 |
| serialize | 緩存數(shù)據(jù)時value序列化策略 |
spEL表達式:
| 名字 | 位置 | 描述 | 示例 |
|---|---|---|---|
| methodName | root object | 當前被調(diào)用的方法名 | #root.methodName |
| method | root object | 當前被調(diào)用的方法 | #root.method.name |
| target | root object | 當前被調(diào)用的目標對象 | #root.target |
| targetClass | root object | 當前被調(diào)用的目標對象類 | #root.targetClass |
| args | root object | 當前被調(diào)用的方法的參數(shù)列表 | #root.args[0] |
| caches | root object | 當前方法調(diào)用使用的緩存列表(如@Cacheable(value={"cache1", "cache2"})),則有兩個cache | #root.caches[0].name |
| argument name | evaluation context | 方法參數(shù)的名字. 可以直接 #參數(shù)名 ,也可以使用 #p0或#a0 的形式,0代表參數(shù)的索引; | #id 、 #a0 、 #p0 |
| result | evaluation context | 方法執(zhí)行后的返回值(僅當方法執(zhí)行之后的判斷有效,如‘unless’,’cache put’的表達式 ’cache evict’的表達式,'cacheable'中不可用’'beforeInvocation=false) | #result |
二.@Cacheable & @CachePut 簡介
@Cacheable:是運行了該方法后,下次請求時就請求緩存不再運行方法,主要用于查詢。
@CachePut:保證方法每次都被運行,并把結(jié)果加入到緩存中,主要用于更新數(shù)據(jù)。
@Cacheable & @CachePut 可配置的屬性一樣。關于功能查看源代碼英文注解已經(jīng)寫的十分詳細,不過這里還是重寫編輯轉(zhuǎn)化成自己的語言,為了加深理解印象。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
/**
* cacheNames/value 指定緩存組件的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 緩存數(shù)據(jù)用的key,默認說是利用SpEL把所有方法的參數(shù)動態(tài)生成一個Key。當然你也可以自己指定
*/
String key() default "";
/**
* 指定key的生成器,可以自己指定key生成器的,與key屬性互斥
*/
String keyGenerator() default "";
/**
* 指定緩存管理器,與cacheResolver緩存解析器互斥
*/
String cacheManager() default "";
/**
* 指定緩存解析器。
*/
String cacheResolver() default "";
/**
* 利用SpEL語言,指定符合緩存的條件
*/
String condition() default "";
/**
* condition相當于if,unless相當于if not
*/
String unless() default "";
/**
* 是否使用同步模式。這個設置可以減少對數(shù)據(jù)庫的瞬間并發(fā)訪問。
* 1.不支持unless
* 2.只能指定一個緩存
* 3.不能組合其他緩存相關操作
* 4.使用之前先確認你使用的緩存支持同步模式,
*/
boolean sync() default false;
}
實驗一:替換key
@Cacheable(cacheNames = {"empCache"} ,key = "#root.method+'['+#id+']'")
public Employee getEmp(Integer id) {
System.out.println("查詢了");
return mapper.getEmpById(id);
}

CacheAspectSupport中的findCachedItem方法
實驗二:替換Key生成器&添加條件緩存
/**
* @author BaoZhou
* @date 2018/5/30
*/
@Configuration
public class MyKeyGenerateConfig {
@Bean(name = "MyKeyGenerate")
public KeyGenerator myKeyGenerator() {
return (target, method, params) -> method.getName() + "[" + Arrays.asList(params).toString() + "]";
}
}
@Cacheable(cacheNames = {"empCache"} ,keyGenerator = "MyKeyGenerate",condition = "#id>0",unless = "#a0==2")
public Employee getEmp(Integer id) {
System.out.println("查詢了");
return mapper.getEmpById(id);
}

CacheAspectSupport中的findCachedItem方法
實驗三:更新緩存
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper mapper;
//保證查詢Key和更新Key保持一致
@Cacheable(cacheNames = {"empCache"}, key = "#id")
public Employee getEmp(Integer id) {
System.out.println("查詢");
return mapper.getEmpById(id);
}
@CachePut(cacheNames = {"empCache"},key = "#employee.id")
public Employee updateEmp(Employee employee) {
System.out.println("更新");
mapper.updateEmp(employee);
return employee;
}
}
三.@CacheEvict 簡介
@CacheEvict主要用于刪除緩存
其參數(shù)基本與@Cacheable & @CachePut一致,但是有幾個特有參數(shù)。
- @allEntries:是否刪除指定緩存組件下所有的緩存。
- @beforeInvocation:緩存的清楚是否在方法之前執(zhí)行。假如為True就是假如刪除方法出現(xiàn)異常,緩存還是會被清除。假如為False,那么緩存還會保留。
四.@Catching 簡介
@Catching: 多個緩存注釋的組合注釋(不同或相同類型),在有多種緩存需求的時候使用。
示例代碼
@Caching(
cacheable = {
@Cacheable(value = "empCache",key = "#lastName")
},
put =
{
@CachePut(value = "empCache",key = "#lastName")
@CachePut(value = "empCache",key = "#result.id")
@CachePut(value = "empCache",key = "#result.email")
}
)
public Employee getEmpByLastName(String lastName)
{
return mapper.getEmpByLastName(lastName);
}
五.@CacheConfig 簡介
假如一個功能下,每個緩存操作都要寫cacheName,keygenerator那一定是太麻煩了。
@CacheConfig就是為了統(tǒng)一配置而生。只要在你service上統(tǒng)一配置,就一勞永逸了。
@CacheConfig(cacheNames = "cacheNames")
@Service
public class EmployeeService {
...
}
那么有關于緩存的注解以及作用就介紹到這里了。