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

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

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

  1. SpringBoot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cacheorg.springframework.cache.CacheManager缓存管理器接口
  2. 如果当前程序没有定义类型为CacheManagerBean组件或者是名为cacheResolver缓存解析器,SpringBoot将尝试选择并启用以下缓存组件(按照指定顺序)
    1. Generic
    2. JCache (JSR-107) (EhCache3 、Hazelcast、 Infinispan等)
    3. EhCache 2.x
    4. Hazelcast
    5. Infinispan
    6. Couchbase
    7. Redis
    8. Caffeine
    9. Simple

在这里插入图片描述
在这里插入图片描述

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

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

    <dependency> 
    		<groupId>org.springframework.boot</groupId> 
    		<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 对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
    
  3. 编写业务层,实现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. 查看源码,可以将源码分成两部分 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缓存自定义序列化机制

  1. 引入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

在这里插入图片描述

  1. 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

  1. 自定义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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值