springboot2+ redis+fastjson 自定义缓存管理器,设置序列化方式为fastjson

 

   spring boot 自动配置的缓存序列化为 JdkSerializationRedisSerializer  ,缺点大家都懂,占用过多空间,跨平台困难,可读信差,所以把他换成json的序列化方式。

    当然,spring boot 也已经准备了JSON的序列化器GenericJackson2JsonRedisSerializer , Jackson2JsonRedisSerializer

但是,这些我们通通不用,本文将自义定一个序列化器,使用fastjson来将数据转换为json

============================我是分割线=========================================================

首先按照spring boot的一贯尿性,配置类名字都叫  xxxxxConfiguration,果不其然:

自动配置,默认帮我配置的redisCache 在类RedisCacheConfiguration中。

该配置类打上了 @ConditionalOnMissingBean({CacheManager.class})注解,表示了,如果我们没有向ioc容器中注入CacheManager类,就自动创建该配置类。所以我们自定义CacheManager 只需直接注入ioc容器就会覆盖默认配置

然后往下看,默认spring boot是如何创建CacheManager的,方便我们copy

这就是spring boot 帮我们生成的CacheManager,先二话不说直接copy到我们自定义的配置类中

  @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());
    }

这一段从配置文件中初始化,已经设置好的缓存,我们可以先不要。

  List<String> cacheNames = this.cacheProperties.getCacheNames();
  if (!cacheNames.isEmpty()) {
       builder.initialCacheNames(new LinkedHashSet(cacheNames));
   }

     这段创建了CacheManager对象,并且设置了一些配置,为了方便观看,把它拆开写

RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader()));

所以最后copy下来的代码是这个样子的

  @Bean
    public RedisCacheManager cust_cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //redis默认配置文件
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        //RedisCacheManager 生成器创建
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration);
        return builder.build();
    }

RedisCacheConfiguration 为redisCache的自定义设置类 他和上文提高的 RedisCacheConfiguration 不是一个类,前者所在包为org.springframework.data.redis.cache,后者所在包为 org.springframework.boot.autoconfigure.cache

进入该类有:

    private final Duration ttl;  //过期时间
    private final boolean cacheNullValues; //缓存是否为null
    private final CacheKeyPrefix keyPrefix; 
    private final boolean usePrefix;  
    private final SerializationPair<String> keySerializationPair;  //key的序列化器
    private final SerializationPair<Object> valueSerializationPair; //value的序列化器
    private final ConversionService conversionService;

所以很简单,只要设置了该类的属性,就能改变manager的一些配置。如:过期时间,以及序列化器

但是注意,该类的属性都是final类型无法修改,所以我们看该类的设置值的方法

  public RedisCacheConfiguration entryTtl(Duration ttl) {
        Assert.notNull(ttl, "TTL duration must not be null!");
        return new RedisCacheConfiguration(ttl, this.cacheNullValues, this.usePrefix, this.keyPrefix, this.keySerializationPair, this.valueSerializationPair, this.conversionService);
    }

这个看名字是 设置过期时间,在该方法内部,他没有直接改变属性的值,而是把之前设置的值和本次需要改变的值一起拿来,new了一个新的对象。

所以正确的设置姿势应该是这样的:

  @Bean
    public RedisCacheManager cust_cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //redis默认配置文件
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(1));
        //RedisCacheManager 生成器创建
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration);
        return builder.build();
    }

同理我们要改变序列化器为fastjson 也只要设置值valueSerializationPair就可以了

回到自动配置的 RedisCacheConfiguration 类,我们看看spring boot是怎么创建序列化对象的

点进去发现JdkSerializationRedisSerializer是RedisSerializer接口的实现类

总的来说 很简单,创建一个RedisSerializer接口的对象,然后用SerializationPair.fromSerializer封装一下,就能直接扔配置文件里了

查看RedisSerializer接口的现实关系

本文开头提到的 GenericJackson2JsonRedisSerializer , Jackson2JsonRedisSerializer 这些Spring boot 默认的JSON序列化器就在这里。如果不想自定义fastjson 序列化器,那么直接把这2个类的其中一个 设置进valueSerializationPair 就可以实现json 序列化了

============================我是分割线=========================================================

创建一个类 实现RedisSerializer接口,我这里名字叫FastJsonRedisSerializer

他将重写2个方法,看名字也知道,一个是序列化,一个是反序列化。

 @Nullable
    byte[] serialize(@Nullable T var1) throws SerializationException;

    @Nullable
    T deserialize(@Nullable byte[] var1) throws SerializationException;

fastjson序列化,反序列化方法很简单,这里就不多说了 直接上代码

public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return  new byte[0];
        }
        try {
           return JSON.toJSONBytes(t, SerializerFeature.WriteClassName);
        } catch (Exception ex) {
            throw new SerializationException("Could not write JSON: " + ex.getMessage(), ex);
        }
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        String data =new String(bytes);
        T result = (T)JSON.parse(data);
        return result;
    }

这里注意的是,序列化的时候,我设置了 SerializerFeature.WriteClassName,这会讲泛型T的类型写入JSON中多了一个@type的属性,来存储类型,这样反序列化的时候就能自动转成原本的类型

同时需要在spring boot中全局设置 ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

获得序列化器后把它设置进manager中

最终的配置为:

   @Bean
    public RedisCacheManager cust_cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //创建自定义序列化器
        FastJsonRedisSerializer jsonSeria = new  FastJsonRedisSerializer();
        //包装成SerializationPair类型
        RedisSerializationContext.SerializationPair serializationPair = RedisSerializationContext.SerializationPair.fromSerializer(jsonSeria);
        //redis默认配置文件,并且设置过期时间
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(1));
        //设置序列化器
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(serializationPair);
        //RedisCacheManager 生成器创建
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration);
        return builder.build();
    }

 

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值