SpringBoot - 整合Redis缓存cache及键值序列化

本文详细介绍了如何在SpringBoot项目中整合Redis作为缓存,并使用SpringCache进行缓存管理。讨论了SpringBoot配置Redis的步骤,包括引入依赖、配置文件设置、序列化方式选择。此外,文章还探讨了RedisUtils工具类的使用,以及SpringCache的读写模式和不足之处,如缓存穿透、缓存击穿和缓存雪崩的问题及其解决方案。最后,作者总结了不同序列化方法的优缺点,包括JDK序列化、JSON序列化和二进制序列化。
摘要由CSDN通过智能技术生成

前面的SpringCache缓存说过在没有引入其他缓存中间件时,默认使用的是ConcurrentMapCacheManager=ConcurrentMapCache,是将数据保存在ConcurrentMap<Object, Object>中。
在实际开发中,我们一般都会使用redismemcachedehcache来作为缓存中间件。

整合Redis

Redis是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
当我们引入Reidsstarter依赖的时候,使用RedisCacheManagerRedisCacheManager会帮我们创建RedisCache来作为缓存组件,RedisCache通过操作redis缓存数据。

1、引入Redis的starter的依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池 - luttuce依赖该连接池 -->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
	<version>2.4.2</version>
</dependency>

2、配置yml配置文件

spring:
  redis:
    host: 127.0.0.1  # Redis连接地址
    port: 6379 # redis连接端口
    lettuce: # 使用lettuce客户端
      pool:
        max-active: 8 # 连接池最大连接数(负值表示没有限制)
        max-idle: 8 # 连接池的最大空闲连接
        min-idle: 0 # 连接池的最小空闲连接
        max-wait: -1ms # 连接池最大阻塞等待时间(赋值表示没有限制)
    database: 0     # 默认使用索引为0的数据库
    timeout: 5000ms # 连接超时时间

3、序列化配置
Reids默认使用的是JDK的序列化机制,我们通过RedisDesktopManager去查看存储的数据,是无法用肉眼看出存的是什么的。
JDK序列化机制
比如说我们要存一个对象进去,并且想直接肉眼看到是一个怎么样的数据,可以通过修改配置,让其以Json的格式去保存。
创建一个配置类继承CachingConfigurerSupport

@Configuration
public class RedisConfiguration extends CachingConfigurerSupport {
   

    /**
     * 采用RedisCacheManager作为缓存管理器
     * @param connectionFactory Redis连接工厂 - 配置的是Luttuce客户端,则这里就是LuttuceFactory
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory){
   
        RedisCacheManager redisCacheManager = RedisCacheManager.create(connectionFactory);
        return redisCacheManager;
    }

    /**
     * RedisTemplate模板
     * @param factory Redis连接工厂
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
   
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 使用Jackson进行序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        // 如果enableDefaultTyping过期(SpringBoot后续版本过期了),则使用下面这个代替
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // String序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key采用String的序列方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化也采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

4、测试一下

// 注入RedisTemplate
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
// 向Redis中存数据
@GetMapping("/test")
public String test(){
   
    BoundHashOperations boundHashOps = redisTemplate.boundHashOps("User");
    List list = new ArrayList();
    User user1 = new User("柳成荫", "男", 22);
    list.add(user1);
    list.add(user1);
    boundHashOps.put("3",list);
    return "ok";
}
// 向Redis取数据
@GetMapping("/test1")
public List test1(){
   
    BoundHashOperations boundHashOps = redisTemplate.boundHashOps("User");
    List<User> users = (List<User>) boundHashOps.get("3");
    return users;
}

可以看到确实存入的是JSON序列化的结果
RedisDesktopManager
取出来也是没有问题的
在这里插入图片描述

RedisUtils

自定义的RedisUtils用着比RidsTemplate方便很多,所以一般都会自己封装一个工具类。

@Component
public class RedisUtils {
   
    // 注入自己的RedisTemplate
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // ================================== 共用部分 ====================================

    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     */
    public boolean expire(String key, long time){
   
        
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值