如何在 spring-data 2.0.x 中创建 RedisCacheManager

Posted

技术标签:

【中文标题】如何在 spring-data 2.0.x 中创建 RedisCacheManager【英文标题】:How to create RedisCacheManager in spring-data 2.0.x 【发布时间】:2018-12-27 07:50:29 【问题描述】:

我正在将我的应用程序从 Spring Boot 1.5.x 迁移到 2.0.x。我想保留绝地武士,但RedisCacheManager 的实例化有问题。

现在构造函数签名是

RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration)

但在此之前:

RedisCacheManager(RedisOperations redisOperations)

我定义这个 bean 的范围内只有 RedisTemplate

@Bean
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) 
    HandleRedisCacheManager redisCacheManager = new HandleRedisCacheManager(redisTemplate);
    redisCacheManager.setUsePrefix(true);
    return redisCacheManager;

现在应该如何创建?

【问题讨论】:

【参考方案1】:

尝试以下代码,它适用于 spring-boot 2.1.0.RELEASE

@Bean
public RedisCacheManager redisCacheManager(LettuceConnectionFactory lettuceConnectionFactory) 
    RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            .disableCachingNullValues()
            .entryTtl(Duration.ofHours(1))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
    redisCacheConfiguration.usePrefix();

   return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
                    .cacheDefaults(redisCacheConfiguration).build();

    

【讨论】:

redisCacheConfiguration.usePrefix();没有任何意义。这是一个只返回布尔值的方法。该类是不可变的,因此 setUsePrefix 需要在构建器中具有一些等效项。如果未使用 RedisCacheConfiguration#disableKeyPrefix() 明确禁用,则 usePrefix 默认为 true @MikaelVandmo 我读代码的方式,usePrefix 默认为false。如果您调用 .prefixKeysWith(String) 或 .computePrefixWith(),则为真【参考方案2】:

它不再接受 RedisTemplate。所以试试这个:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
                                      ResourceLoader resourceLoader) 
    RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
            .builder(redisConnectionFactory)
            .cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
    List<String> cacheNames = this.cacheProperties.getCacheNames();
    if (!cacheNames.isEmpty()) 
        builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
    
    return builder.build();


private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
        ClassLoader classLoader) 
    if (this.redisCacheConfiguration != null) 
        return this.redisCacheConfiguration;
    
    CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

    ObjectMapper mapper = new Jackson2ObjectMapperBuilder()
            .modulesToInstall( new SimpleModule().addSerializer( new NullValueSerializer(null)) )
            .failOnEmptyBeans( false )
            .build();
    mapper.enableDefaultTyping( ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

    GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer( mapper );

    //get the mapper b/c they registered some internal modules
    config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));;

    if (redisProperties.getTimeToLive() != null) 
        config = config.entryTtl(redisProperties.getTimeToLive());
    
    if (redisProperties.getKeyPrefix() != null) 
        config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        config = config.computePrefixWith(cacheName -> redisProperties.getKeyPrefix() + cacheName + "::");
    
    if (!redisProperties.isCacheNullValues()) 
        config = config.disableCachingNullValues();
    
    if (!redisProperties.isUseKeyPrefix()) 
        config = config.disableKeyPrefix();
    
    return config;

【讨论】:

如果它停止接受 RedisTemplate 作为构造函数的参数 - 忽略它的代码逻辑是否改变了?还是和 SpringBoot 1.5 一样?

以上是关于如何在 spring-data 2.0.x 中创建 RedisCacheManager的主要内容,如果未能解决你的问题,请参考以下文章

如何像在 babelrc 中创建依赖别名一样在 typescript 中创建类型别名?

如何在 Spring-data 中更改/定义 Mongodb 的默认数据库?

在 Azure Blob 容器中创建两个文件时,如何在 Azure 数据工厂中创建事件触发器?

如何在你的库中使用 Spring-Data 以及如何在你的项目中使用这个库?

如何在 Oz 中创建列表?

如何在android中创建链接按钮