前言
Spring Cache 是 Spring 3 版本之后引入的一项技术,可以简化对于缓存层的操作,spring cache与springcloud stream类似,都是基于抽象层,可以任意切换其实现。其核心是CacheManager、Cache这两个接口,所有由spring整合的cache都要实现这两个接口、Redis的实现类则是 RedisCache 和 RedisManager。
使用
1、查询
需要导入的依赖
<code> <dependency><groupid>org.springframework.boot/<groupid><artifactid>spring-boot-starter-cache/<artifactid>/<dependency> <dependency> <groupid>org.springframework.boot/<groupid> <artifactid>spring-boot-starter-data-redis/<artifactid>/<dependency>/<code>
编写对于cache的配置
<code> @EnableCaching 2 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 }/<object>/<string>/<code>
进行以上配置即可使用springboot cache了,还有一个key的生成策略的配置(可选)
<code>@Bean public KeyGenerator keyGenerator() { return (target, method, params) -> { StringBuffer key = new StringBuffer(); key.append(target.getClass().getSimpleName() + "#" + method.getName() + "("); for (Object args : params) { key.append(args + ","); } key.deleteCharAt(key.length() - 1); key.append(")"); return key.toString(); }; }/<code>
注意:如果配置了KeyGenerator ,在进行缓存的时候如果不指定key的话,最后会把生成的key缓存起来,如果同时配置了KeyGenerator 和key则优先使用key。
在controller或者service的类上面添加 @CacheConfig ,注解里面的参数详情见下表:
在标有@CacheConfig的类里面编写一个查询单个对象的方法并添加 @Cacheable注解。
<code>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 }/<code>
执行完该方法后,执行结果将会被缓存到Redis:
@Cacheable注解中参数详情见下表:
2、 修改
编写一个修改的方法,参数传对象,返回值也改成这个对象
<code> @PutMapping("/course") public Course modifyCoruse(@RequestBody Course course) { courseService.updateCourse(course); return course; }/<code>
在方法上面添加 @CachePut(key = "#course.id") 注解,这个注解表示将方法的返回值更新到缓存中,注解中的参数和 @Cacheable 中的一样,这里就略过了。
3、 删除
编写删除方法,在方法上添加@CacheEvict 注解
<code>1 @CacheEvict(key = "#id")2 @DeleteMapping("/course/{id}")3 public void removeCourse(@PathVariable Integer id) {4 courseService.remove(id);5 }/<code>
@CacheEvict 的参数信息见下表:
基于代码的 Cache 的使用
因为我们有配置的CacheManager,所以可以利用RedisCacheManager对象去手动操作cache,首先将CacheManager注入进来:
<code>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 // 将缓存的结果返回 return (Course) wrapper.get(); } }/<code>
閱讀更多 Java高級架構師 的文章