一、介绍
Spring Cache 是spring3版本之后引入的一项技术,可以简化对于缓存层的操作,spring cache与springcloud stream类似,都是基于抽象层,可以任意切换其实现。其核心是CacheManager
、Cache
这两个接口,所有由spring整合的cache都要实现这两个接口、Redis的实现类则是 RedisCache
和 RedisManager。
往期关于Spring Boot实战文章可以关注微信公众号:Java后端,后台回复 技术博文 获取。
二、使用
Ⅰ、查询
需要导入的依赖
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
,注解里面的参数详情见下表:
在标有@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注解中参数详情见下表:
Ⅱ、 修改
编写一个修改的方法,参数传对象,返回值也改成这个对象
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
的参数信息见下表:
三、 基于代码的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
作者 | 涅槃重生
链接 | www.cnblogs.com/maolinjava/p/12335861.html
-END-
如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「web_resource」,欢迎添加小编微信「focusoncode」,每日朋友圈更新一篇高质量技术博文(无广告)。
↓扫描二维码添加小编↓
推荐阅读
1. 狠!删库跑路!
4. 快速建站利器!