Sprintg boot 熱數據緩存

一、主要類&緩存注解

名稱 解釋
@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í)行過程

  1. 先查詢是否已經有緩存
  2. 有會使用緩存
  3. 沒有則會執(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ā)真實方法的調用 。簡單來說就是用戶更新緩存數據。但需要注意的是該注解的valuekey 必須與要更新的緩存相同,也就是與@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 {};
}
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容