SpringBoot2.x操作缓存的新姿势
涅槃重生, 人气:0
一、介绍
spring cache 是spring3版本之后引入的一项技术,可以简化对于缓存层的操作,spring cache与springcloud stream类似,都是基于抽象层,可以任意切换其实现。其核心是CacheManager
、Cache
这两个接口,所有由spring整合的cache都要实现这两个接口、Redis的实现类则是 RedisCache
和 RedisManager。
二、使用
Ⅰ、查询
需要导入的依赖
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-cache</artifactId> 4 <https://img.qb5200.com/download-x/dependency> 5 <dependency> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-data-redis</artifactId> 8 <https://img.qb5200.com/download-x/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
你想成为什么样的人,就会成为什么样的人!
加载全部内容