springboot整合mybatis使用redis缓存自定义json序列化器@Conditional注解SimpleCacheConfiguration缓存

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!

在整合redis做缓存前先看一下我们之前缓存的时候用的是什么呢,spring默认匹配的是SimpleCacheConfiguration缓存,它的底层用了一个key-value的Map,不能像redis一样持久化,一般情况下我们是需要持久化缓存的,那就需要替换默认的SimpleCacheConfiguration。

我们可以通过在配置文件中添加debug=true来使自动配置报告打印在控制台,我们看下springboot的自动配置为我们做了什么,我们先找到自动配置类CacheAutoConfiguration源码

可以看到它为我们导入了一个CacheConfigurationImportSelector,接着看CacheConfigurationImportSelector,并打上断点启动看下它做了什么,

可以看出它为我们导入了10个缓存配置类,并且从控制台可以看到SimpleCacheConfiguration也确实匹配到了,

那他是怎么匹配上SimpleCacheConfiguration的呢,看下它的源码

可以看到类上有@Conditional派生的@ConditionalOnMissingBean注解,@Conditional的作用是必须它指定的条件成立,才给容器中添加组件,派生的一些组件是在它基础之上进行的扩展,如这个@ConditionalOnMissingBean作用是:容器中不存在指定的CacheManager时它就会被注入(即匹配到),我们并没有添加任何的CacheManager,当然会匹配到,关于@Conditional相关的注解,它就是为了方便程序根据当前环境或者容器情况来动态注入bean,可以查看spring的官方文档了解下,或者看一下网上的博客,有很多,贴一张图,

继续看SimpleCacheConfiguration,它注入了一个ConcurrentMapCacheManager,

而ConcurrentMapCacheManager实现了CacheManager接口,那他必定有一个获取缓存的方法,看下ConcurrentMapCacheManager中获取缓存的方法

可以看到,缓存对象Cache是从cacheMap中获取的,如果没有就创建一个放进去,而cacheMap是个ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>(16);

查看完源码总结一下:springboot自动配置默认匹配的是SimpleCacheConfiguration,它给容器中注入了一个ConcurrentMapCacheManager,ConcurrentMapCacheManager可以获取和创建ConcurrentMapCache类型的缓存组件,它的作用将数据保存在ConcurrentMap中。

好了,不废话了,开始整合redis吧

第一步:首先引入springboot对redis的启动依赖

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

这时候启动程序,从控制台就可以看到现在匹配到了RedisCacheConfiguration这个缓存配置类,按照上面的方法感兴趣的小伙伴可以追踪下源码,

第二步:配置文件中配置连接redis :spring.redis.host=127.0.0.1

完成!(可以使用JedisPool来作为redis连接池)

可以测试了,访问:http://localhost:8080/user/1 两次,控制台打印如下:

两次查询只访问了一次数据库,达到了缓存效果,再看下redis中:

redis中也持久化了缓存数据。

但是看缓存的内容,因为默认使用的是JdkSerializationRedisSerializer这个序列化器,导致缓存的结果根本看不懂是啥吧,我们也可以使用其他序列化方式来达到不同的需求。比如我们希望缓存的数据具有可读性就可以将其序列化为json格式,json序列化可以使用Jackson2JsonRedisSerialize或FastJsonRedisSerializer。如果我们希望拥有更快的速度和占用更小的存储空间推荐使用KryoRedisSerializer进行序列化。如下使用Jackson2JsonRedisSerialize序列化器,自定义RedisTemplate和RedisCacheManager

@Configuration
public class MyRedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置序列化(解决乱码的问题),过期时间30秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(1800000))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }


}

完成!

清空redis ,访问:http://localhost:8080/user/1 两次,控制台打印如下:

查看redis中:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值