springboot框架学习积累---SpringBoot缓存管理之相关组件

tech2025-02-02  13

springboot框架学习积累—SpringBoot缓存管理之相关组件

1.SpringBoot支持的缓存组件有哪些

在SpringBoot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.springframework.cache.CacheManager缓存管理器接口如果当前程序没有定义类型为CacheManager的Bean组件或者是名为cacheResolver缓存解析器,SpringBoot将尝试选择并启用以下缓存组件(按照指定顺序) GenericJCache (JSR-107) (EhCache3 、Hazelcast、 Infinispan等)EhCache 2.xHazelcastInfinispanCouchbaseRedisCaffeineSimple

2.SpringBoot基于注解的Redis缓存实现

添加redis的依赖启动器:由于引入了Redis的依赖启动器,所以会将默认的SimpleCacheConfiguration缓存配置类变成RedisCacheConfiguration这个缓存配置类,容器中使用的缓存管理器也从ConcurrentMapCacheManager变成了RedisCacheManager,这时候缓存管理器创建的Cache是RedisCache,进而操作Redis进行数据的缓存

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>

对Redis服务进行配置

#Redis服务地址 spring.redis.host=127.0.0.1 #Redis服务端口号 spring.redis.port=6379 #Redis服务密码 spring.redis.password= #对基于注解的Redis缓存数据统一设置有效期为1分钟,单位毫秒 spring.cache.redis.time-to-live=60000

编写业务层,实现Redis缓存逻辑

controller

/** * @author yy */ @RestController public class CommentController { @Autowired private CommentService commentService; /** * 查询 * * @param id * @return */ @RequestMapping(value = "/findCommentById") public Comment findCommentById(Integer id){ Comment comment = commentService.findCommentById(id); return comment; } /** * 修改 * * @param comment * @return */ @RequestMapping("/updateComment") public Comment updateComment(Comment comment){ Comment commentById = commentService.findCommentById(comment.getId()); commentById.setAuthor(comment.getAuthor()); Comment comment1 = commentService.updateComment(commentById); return comment1; } /** * 删除 * * @param id */ @RequestMapping("/deleteComment") public void deleteComment(Integer id){ commentService.deleteComment(id); }

service

/** * @author yh */ @Service public class CommentService { @Autowired private CommentRepository commentRepository; /** * @Cacheable: 将该方法查询结果comment存放在springboot默认Simple缓存中(前提是没有引入其他缓存组件) * cacheNames: 起一个缓存命名空间 对应缓存唯一标识 * unless:当满足等号后面的条件时,结果不进入缓存 */ @Cacheable(cacheNames = "comment",unless = "#result == null ") public Comment findCommentById(Integer id){ Optional<Comment> byId = commentRepository.findById(id); if (byId.isPresent()){ //获取comment对象 Comment comment = byId.get(); return comment; } return null; } /** * 更新 */ @CachePut(cacheNames = "comment",key = "#result.id") public Comment updateComment(Comment comment){ commentRepository.updateComment(comment.getAuthor(),comment.getId()); return comment; } /** * 删除 */ @CacheEvict(cacheNames = "comment") public void deleteComment(Integer id){ commentRepository.deleteById(id); } }

3.SpringBoot基于API的Redis缓存实现

/** * @author yh */ @Service public class ApiCommentService { @Autowired private CommentRepository commentRepository; @Autowired private RedisTemplate redisTemplate; /** * 查询方法,使用API方式进行缓存。 * 先去缓存中查找,缓存中有直接返回,没有,查询数据库 * * @param id * @return */ public Comment findCommentById(Integer id){ //通过key找Object对象,get括号中的是key Object o = redisTemplate.opsForValue().get("comment_" + id); if (o!=null){ //查询到了数据直接返回 return (Comment) o; }else { //缓存中没有,去数据库中找 Optional<Comment> byId = commentRepository.findById(id); if (byId.isPresent()){ //获取comment对象 Comment comment = byId.get(); //将查询结果放到缓存中,并且设置有效期 redisTemplate.opsForValue().set("comment_" + id,comment,1, TimeUnit.DAYS); return comment; } } return null; } /** * 修改 * * @param comment * @return */ public Comment updateComment(Comment comment){ commentRepository.updateComment(comment.getAuthor(),comment.getId()); //将数据在数据库中修改完成,再存到redis库里面,将更新数据 redisTemplate.opsForValue().set("comment_" + comment.getId(),comment); return comment; } /** * 删除 * * @param id */ public void deleteComment(Integer id){ commentRepository.deleteById(id); redisTemplate.delete("comment_" + id); } }

4.SpringBoot之Redis缓存默认序列化机制

查看源码,可以将源码分成两部分 1.声明了key,value各种序列化的初始值,初始值为空 2.进行默认序列化设置方式,默认设置是JDK序列化方式

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware { // 声明了key,value各种序列化的初始值,初始值为空 @Nullable private RedisSerializer keySerializer = null; @Nullable private RedisSerializer valueSerializer = null; @Nullable private RedisSerializer hashKeySerializer = null; @Nullable private RedisSerializer hashValueSerializer = null; ... // 进行默认序列化设置方式,默认设置是JDK序列化方式 public void afterPropertiesSet() { super.afterPropertiesSet(); boolean defaultUsed = false; if(this.defaultSerializer == null) { this.defaultSerializer = new JdkSerializationRedisSerializer( this.classLoader != null? this.classLoader:this.getClass().getClassLoader()); } ... } ... }

2. 根据上述源码分析可以得出以下两个重要结论

5.SpringBoot之Redis缓存自定义序列化机制

引入Redis的依赖后,SpringBoot提供的RedisAutoConfiguration自动配置会生效,RedisAutoConfiguration这个类有关于RedisTemplate的定义方式

public class RedisAutoConfiguration { //将方法的返回值注入到ioc容器中,key是方法名 @Bean //当redisTemplate这个bean不存在时生效,如果自定义了一个redisTemplate的bean,那么这个方法的返回值就失效了 @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); return template; } ... }

6.SpringBoot缓存管理之自定义RedisCacheManager

Redis注解默认序列化机制:RedisCacheConfiguration

@Configuration class RedisCacheConfiguration { @Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) { RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader())); List<String> cacheNames = this.cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { builder.initialCacheNames(new LinkedHashSet(cacheNames)); } return (RedisCacheManager) this.customizerInvoker.customize(builder.build()); } private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(ClassLoader classLoader) { if (this.redisCacheConfiguration != null) { return this.redisCacheConfiguration; } else { Redis redisProperties = this.cacheProperties.getRedis(); org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConf ig(); config = config.serializeValuesWith(SerializationPair.fromSerializer( new JdkSerializationRedisSerializer(classLoader))); ... return config; } } }

制,需要自定义RedisCacheManager

自定义RedisCacheManager

@Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { // 分别创建String和JSON格式序列化对象,对缓存数据key和value进行转换 RedisSerializer<String> strSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class); // 解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jacksonSeial.setObjectMapper(om); // 定制缓存数据序列化方式及时效 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofDays(1)) .serializeKeysWith(RedisSerializationContext.SerializationPair .fromSerializer(strSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair .fromSerializer(jacksonSeial)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager .builder(redisConnectionFactory).cacheDefaults(config).build(); return cacheManager; }

最新回复(0)