一、主要類&緩存注解
| 名稱 | 解釋 |
|---|---|
| @Cacheable | 主要針對方法配置,能夠根據方法的請求參數對其進行緩存 |
| @CachePut | 保證方法被調用,又希望結果被緩存。 與@Cacheable區(qū)別在于是否每次都調用方法,常用于更新 |
| @CacheEvict | 清空緩存 |
| @EnableCaching | 開啟基于注解的緩存 |
| @CacheConfig | 統一配置本類的緩存注解的屬性 |
| keyGenerator | 緩存數據時key生成策略 |
| serialize | 緩存數據時value序列化策略 |
| Cache | 緩存接口,定義緩存操作。實現有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
| CacheManager | 緩存管理器 |
核心注解參數
| 名稱 | 解釋 |
|---|---|
| value | 緩存的名稱,在 spring 配置文件中定義 |
| key | 緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫, 如果不指定,則缺省按照方法的所有參數進行組合 例如: @Cacheable(value=”testcache”,key=”#id”) |
| condition | 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false, 只有為 true 才進行緩存/清除緩存 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
| unless | 否定緩存。當條件結果為TRUE時,就不會緩存。 @Cacheable(value=”testcache”,unless=”#userName.length()>2”) |
| allEntries (@CacheEvict ) | 是否清空所有緩存內容,缺省為 false,如果指定為 true, 則方法調用后將立即清空所有緩存 例如: @CachEvict(value=”testcache”,allEntries=true) |
| beforeInvocation (@CacheEvict) | 是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true, 則在方法還沒有執(zhí)行的時候就清空緩存,缺省情況下,如果方法 執(zhí)行拋出異常,則不會清空緩存 例如: @CachEvict(value=”testcache”,beforeInvocation=true) |
二、開啟緩存
1、在啟動類上加注解 @EnableCaching
@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {
public static void main(String[] args) {
SpringApplication.run(RedisCacheApplication.class, args);
}
}
2、EnableCaching
完成了這些配置之后,Spring Boot就會自動幫我們在后臺配置一個RedisCacheManager,相關的配置是在RedisCacheConfiguration類中完成的。
@Configuration
@ConditionalOnClass(RedisConnectionFactory.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class RedisCacheConfiguration {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.build());
}
}
三、添加@Cacheable
1、作用
表示將一個方法的返回值緩存起來,一般用于查詢方法,默認情況下,緩存的key就是方法的參數,緩存的value就是方法的返回值。執(zhí)行過程
- 先查詢是否已經有緩存
- 有會使用緩存
- 沒有則會執(zhí)行方法并緩存
2、源代碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
String key() default "";
String keyGenerator() default "";
String cacheManager() default "";
String cacheResolver() default "";
String condition() default "";
String unless() default "";
boolean sync() default false;
}
2、屬性說明
| 屬性說明 | 說明 |
|---|---|
| String key() | key的生成器。可以是spEL表達式。默認情況下,緩存的key就是方法的參數 |
| String[] value() | 同cacheNames |
| String[] cacheNames() | 必要參數,指定一個或多個Cache名字 |
| String keyGenerator() | key的生成器。key/keyGenerator二選一使用 |
| String cacheManager() | 指定緩存管理器 |
| String cacheResolver() | 指定獲取解析器 |
| String condition() | 條件符合則緩存 |
| String unless() | 條件符合則不緩存 |
| boolean sync() | 是否使用異步模式 |
4、栗子
@RestController
public class CacheController {
// @Cacheable(cacheNames = "index",key = "#name")
@RequestMapping("/")
@Cacheable(cacheNames = "index", key = ("targetClass.getName() + '.'+methodName"))
public String index() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}
5、key自定義策略
當有多個參數時,默認就使用多個參數來做key,如果只需要其中某一個參數做key,則可以在@Cacheable注解中,通過key屬性來指定key,如上代碼就表示只使用id作為緩存的key,如果對key有復雜的要求,可以自定義keyGenerator。
當然,Spring Cache 中提供了root對象,可以在不定義keyGenerator的情況下實現一些復雜的效果
#root可以省略
| 屬性名稱 | 描述 | 示例 |
|---|---|---|
| methodName | 當前方法名 | #root.methodName |
| method | 當前方法 | #root.method.name |
| target | 當前被調用的對象 | #root.target |
| targetClass | 當前被調用的對象的class | #root.targetClass |
| args | 當前方法參數組成的數組 | #root.args[0] |
| caches | 當前被調用的方法使用的Cache | #root.caches[0].name |
@Bean
public KeyGenerator myKeyGenerator(){
return new KeyGenerator(){
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
四、更新@CachePut
1、作用
主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存,和 @Cacheable 不同的是,它每次都會觸發(fā)真實方法的調用 。簡單來說就是用戶更新緩存數據。但需要注意的是該注解的value 和 key 必須與要更新的緩存相同,也就是與@Cacheable 相同
2、源碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
String key() default "";
String keyGenerator() default "";
String cacheManager() default "";
String unless() default "";
}
3、屬性說明
同@Cacheable
4、栗子
@CachePut(value = "index", key = ("targetClass.getName() + '.'+methodName"))
public String updateDate() {
return "更新數據";
}
5、注意
- key和value一定要和查詢的(@Cacheable)一樣
五、刪除@CacheEvict
1、作用
主要針對方法配置,能夠根據一定的條件對緩存進行清空 。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheEvict {
// ...其它屬性同上
boolean allEntries() default false;
boolean beforeInvocation() default false;
}
2、屬性說明
| 屬性 | 解釋 | 示例 |
|---|---|---|
| allEntries | 是否清空所有緩存內容,缺省為 false,如果指定為 true,則方法調用后將立即清空所有緩存 | @CachEvict(value="index",allEntries=true) |
| beforeInvocation | 是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執(zhí)行的時候就清空緩存,缺省情況下,如果方法執(zhí)行拋出異常,則不會清空緩存 | @CachEvict(value="index",beforeInvocation=true) |
六、配置@CacheConfig
1、作用
這個注解是用于在同一個類中共享一些基礎的cache配置的
一個類級別的注解,允許共享緩存的名稱、KeyGenerator、CacheManager 和CacheResolver。
該操作會被覆蓋。
七、組合@Caching
1、作用
有時候我們可能組合多個Cache注解使用,此時就需要@Caching組合多個注解標簽了。
2、源碼
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}