SpringBoot2.x操作緩存的新姿勢

 

一、介紹

spring cache 是spring3版本之後引入的一項技術,可以簡化對於緩存層的操作,spring cache與springcloud stream類似,都是基於抽象層,可以任意切換其實現。其核心是CacheManagerCache這兩個接口,所有由spring整合的cache都要實現這兩個接口、Redis的實現類則是 RedisCacheRedisManager。

 

二、使用

Ⅰ、查詢

         需要導入的依賴

1 <dependency>
2     <groupId>org.springframework.boot</groupId>
3     <artifactId>spring-boot-starter-cache</artifactId>
4 </dependency>
5 <dependency>
6     <groupId>org.springframework.boot</groupId>
7     <artifactId>spring-boot-starter-data-redis</artifactId>
8 </dependency>

   編寫對於cache的配置

 1 @EnableCaching
 2 @SpringBootConfiguration
 3 public class CacheConfig {
 4 
 5     @Autowired
 6     private RedisConnectionFactory connectionFactory;
 7 
 8     @Bean // 如果有多個CacheManager的話需要使用@Primary直接指定那個是默認的
 9     public RedisCacheManager cacheManager() {
10         RedisSerializer<String> redisSerializer = new StringRedisSerializer();
11         Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
12 
13         ObjectMapper om = new ObjectMapper();
14         // 防止在序列化的過程中丟失對象的屬性
15         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
16         // 開啓實體類和json的類型轉換
17         om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
18         jackson2JsonRedisSerializer.setObjectMapper(om);
19 
20         // 配置序列化(解決亂碼的問題)
21         RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()   .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))             .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
22                 // 不緩存空值
23                 .disableCachingNullValues()
24                 // 1分鐘過期
25                 .entryTtl(Duration.ofMinutes(1))
26                 ;
27         RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
28                 .cacheDefaults(config)
29                 .build();
30         return cacheManager;
31     }
32 }

進行以上配置即可使用springboot cache了,還有一個key的生成策略的配置(可選)

 1 @Bean
 2 public KeyGenerator keyGenerator() {
 3     return (target, method, params) -> {
 4         StringBuffer key = new StringBuffer();
 5         key.append(target.getClass().getSimpleName() + "#" + method.getName() + "(");
 6         for (Object args : params) {
 7             key.append(args + ",");
 8         }
 9         key.deleteCharAt(key.length() - 1);
10         key.append(")");
11         return key.toString();
12     };
13 }

注意:如果配置了KeyGenerator ,在進行緩存的時候如果不指定key的話,最後會把生成的key緩存起來,如果同時配置了KeyGenerator 和key則優先使用key。

在controller或者service的類上面添加 @CacheConfig ,註解裏面的參數詳情見下表:

參數名參數值作用
cacheNames 可以隨意填寫,一般是一個模塊或者一個很重要的功能名稱 無具體作用,只是用來區分緩存,方便管理
keyGenerator 就是自己配置的KeyGenerator的名稱 全局key都會以他的策略去生成
cacheManager 自己配置的CacheManager 用來操作Cache對象的,很多對於緩存的配置也由他去管理

在標有@CacheConfig的類裏面編寫一個查詢單個對象的方法並添加 @Cacheable註解

1 @Cacheable(key = "#id", unless = "#result == null") 
2 @PatchMapping("/course/{id}")
3 public Course courseInfo(@PathVariable Integer id) {
4     log.info("進來了 .. ");
5     return courseService.getCourseInfo(id);
6 }

執行完該方法後,執行結果將會被緩存到Redis:

 

 @Cacheable註解中參數詳情見下表:

參數名作用
cacheNames  被緩存的時候的命名空間
key 這裏的key的優先級是最高的,可以覆蓋掉全局配置的key,如果不配置的話使用的就是全局的key
keyGenerator  指定的緩存的key的生成器,默認沒有
cacheManager  指定要使用哪個緩存管理器。默認是底層自動配置的管理器
condition 滿足什麼條件會進行緩存,裏面可以寫簡單的表達式進行邏輯判斷
unless 滿足什麼條件不進行緩存,裏面可以寫簡單的表達式進行邏輯判斷
sync 加入緩存的這個操作是否是同步的

Ⅱ、 修改

         編寫一個修改的方法,參數傳對象,返回值也改成這個對象

1 @PutMapping("/course")
2 public Course modifyCoruse(@RequestBody Course course) {
3     courseService.updateCourse(course);
4     return course;
5 }

        在方法上面添加 @CachePut(key = "#course.id") 註解,這個註解表示將方法的返回值更新到緩存中,註解中的參數和 @Cacheable 中的一樣,這裏就略過了。

Ⅲ、 刪除

       編寫刪除方法,在方法上添加@CacheEvict 註解

1 @CacheEvict(key = "#id")
2 @DeleteMapping("/course/{id}")
3 public void removeCourse(@PathVariable Integer id) {
4     courseService.remove(id);
5 }

  @CacheEvict 的參數信息見下表:

參數名描述
allEntries 是否刪除該命名空間下面的全部緩存,默認是false
beforeInvocation 在執行刪除方法前就執行清空緩存操作,默認是false,如果刪除方法執行報錯該註解則不執行

 

三、 基於代碼的Cache的使用

          因爲我們有配置的CacheManager,所以可以利用RedisCacheManager對象去手動操作cache,首先將CacheManager注入進來:

 1 @Resource 
 2 private CacheManager cacheManager;
 3 
 4 @PatchMapping("/course2/{id}")
 5 public Course course2(@PathVariable Integer id) {
 6     // 獲取指定命名空間的cache
 7     Cache cache = cacheManager.getCache("course");
 8     // 通過key獲取對應的value
 9     Cache.ValueWrapper wrapper = cache.get(2);
10     if (wrapper == null) {
11         // 查詢數據庫
12         Course course = courseService.getCourseInfo(id);
13         // 加入緩存
14         cache.put(course.getId(), course);
15         return course;
16     } else {
17         // 將緩存的結果返回
18         // 因爲配置了enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
19         // 所以在進行強轉的時候不會報錯
20         return (Course) wrapper.get(); 
21     }
22 }

如果還看不明白,請去碼雲拉取源碼 https://gitee.com/tianmaoliln/Spring-Boot-Cache.git

 

      你想成爲什麼樣的人,就會成爲什麼樣的人!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章