zoukankan      html  css  js  c++  java
  • 配置spring cache RedisCacheManager的序列化方法

    通过查看autoconfigure源码

    org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration;

    部分源码如下:

    private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
    ClassLoader classLoader) {
    if (this.redisCacheConfiguration != null) {
    return this.redisCacheConfiguration;
    }
    Redis redisProperties = this.cacheProperties.getRedis();
    org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration
    .defaultCacheConfig();
    config = config.serializeValuesWith(SerializationPair
    .fromSerializer(new JdkSerializationRedisSerializer(classLoader)));
    if (redisProperties.getTimeToLive() != null) {
    config = config.entryTtl(redisProperties.getTimeToLive());
    }
    if (redisProperties.getKeyPrefix() != null) {
    config = config.prefixKeysWith(redisProperties.getKeyPrefix());
    }
    if (!redisProperties.isCacheNullValues()) {
    config = config.disableCachingNullValues();
    }
    if (!redisProperties.isUseKeyPrefix()) {
    config = config.disableKeyPrefix();
    }
    return config;
    }

    可以看到默认是使用的 JdkSerializationRedisSerializer ,还有就是如果容器里已经有 redisCacheConfiguration 就直接使用了。

    那么只需要自己注入一个 RedisCacheConfiguration 即可。

    代码可以直接用源码里面的:),调整序列化部分即可。

     1 @Configuration
     2 @Conditional(SimpleCacheCondition.class)
     3 public class MyRedisCacheConfiguration {
     4     private final CacheProperties cacheProperties;
     5     MyRedisCacheConfiguration(CacheProperties cacheProperties) {
     6         this.cacheProperties = cacheProperties;
     7     }
     8     @Bean
     9     public org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration() {
    10         CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
    11         org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration
    12                 .defaultCacheConfig();
    13         config = config.serializeValuesWith(RedisSerializationContext.SerializationPair
    14                 .fromSerializer(valueSerializer()));
    15         if (redisProperties.getTimeToLive() != null) {
    16             config = config.entryTtl(redisProperties.getTimeToLive());
    17         }
    18         if (redisProperties.getKeyPrefix() != null) {
    19             config = config.prefixKeysWith(redisProperties.getKeyPrefix());
    20         }
    21         if (!redisProperties.isCacheNullValues()) {
    22             config = config.disableCachingNullValues();
    23         }
    24         if (!redisProperties.isUseKeyPrefix()) {
    25             config = config.disableKeyPrefix();
    26         }
    27         return config;
    28     }
    29     /**
    30      * 使用Jackson序列化器
    31      * @return
    32      */
    33     private RedisSerializer<Object> valueSerializer() {
    34         ObjectMapper objectMapper = new ObjectMapper();
    35         objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    36         objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    37         return new GenericJackson2JsonRedisSerializer(objectMapper);
    38     }
    39 
    40 }

    这里使用的是 GenericJackson2JsonRedisSerializer ;

    参考文档:

    https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/serializer/RedisSerializer.html

    可以看到已有的可用序列化器:

    GenericJackson2JsonRedisSerializerGenericToStringSerializerJackson2JsonRedisSerializerJdkSerializationRedisSerializerOxmSerializerStringRedisSerializer

    这里顺便学习一下 @Conditional ,这个注解可以帮我们控制什么时候来注册组件。

    比如这里写了一个 RedisCacheConfiguration 配置,那我只想在启用了redis缓存时再注册,就可以使用这个注解,如 @Conditional(SimpleCacheCondition.class) 。

    定义 SimpleCacheCondition ,部分代码参考 org.springframework.boot.autoconfigure.cache.CacheCondition 

    public class SimpleCacheCondition implements Condition {
    
        /**
         * Determine if the condition matches.
         *
         * @param context  the condition context
         * @param metadata metadata of the {@link AnnotationMetadata class}
         *                 or {@link MethodMetadata method} being checked
         * @return {@code true} if the condition matches and the component can be registered,
         * or {@code false} to veto the annotated component's registration
         */
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            try {
                String sourceClass = "";
                if (metadata instanceof ClassMetadata) {
                    sourceClass = ((ClassMetadata) metadata).getClassName();
                }
                Environment environment = context.getEnvironment();
                BindResult<CacheType> specified = Binder.get(environment)
                        .bind("spring.cache.type", CacheType.class);
                if (!specified.isBound()) {
                    return false;
                }
           //redis cache 启用 并且 是自定义的redisCacheConfiguration
    if (specified.get().equals(CacheType.REDIS) && sourceClass.equals(MyRedisCacheConfiguration.class.getTypeName())) { return true; } }catch (Exception ex) {} return false; } }
    
    
  • 相关阅读:
    nice -n 10 bash 和 chrt 10 bash 和 echo -17 > /proc/PID/oom_score_adj
    使用NGINX+LUA实现WAF功能 和nginx 防盗链
    hdfs 通过命令坏块监测和删除或者地址获取参数做监控
    kafka 的server.properties
    ntpd服务
    kafka笔记博客
    k8s高可用
    K8S集群Master高可用实践
    String:字符串常量池
    如何设计出优秀的Restful API?
  • 原文地址:https://www.cnblogs.com/huhangfei/p/10136705.html
Copyright © 2011-2022 走看看