一尘不染

使用Redis缓存管理器,redisTemplate和多个序列化器进行缓存

redis

我需要缓存多种类型,例如:

public Country findCountry(String countryName)

和:

public List<Destination> findAllDestinations(String countryName)

我正在使用RedisCacheManager和RedisTemplate仅支持一个串行器。


阅读 710

收藏
2020-06-20

共1个答案

一尘不染

经过一些研究,现在已解决。

  1. 将spring-data-redis更改为1.4.2。
  2. 使用带有缓存映射的类将RedisCacheManager扩展到序列化器(cacheName-> serializer)并缓存名称
  3. 覆盖getCache方法(Cache getCache(字符串名称)),并基于缓存名称,在redis模板中设置序列化程序名称
  4. 使用您的自定义缓存管理器

范例-

public class CustomRedisCacheManager extends RedisCacheManager
{
    public static final String CACHE_NAME_DEFAULT = "default";
    public static final String CACHE_NAME_COUNTRY = "country";
    public static final String CACHE_NAME_DESTINATIONS = "destinations";

    private Map<String, RedisCache> redisCaches = new HashMap<>();

    public CustomRedisCacheManager(Map<String, RedisTemplate> redisTemplates)
    {
        super(redisTemplates.get(CACHE_NAME_DEFAULT), redisTemplates.keySet());

        redisTemplates.keySet().stream().forEach(cacheName ->    redisCaches.put(cacheName, new RedisCache(cacheName, null,   redisTemplates.get(cacheName), 0)));
    }

    @Override
    public Cache getCache(String cacheName)
    {
        return redisCaches.get(cacheName);
    }
}

@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport
{    
    @Bean
    public JedisConnectionFactory jedisConnectionFactory()
    {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(redisHostName);
        factory.setPort(redisPort);            
        factory.setTimeout(100);

        return factory;
    }

    @Bean
    public CacheManager cacheManager()
    {
        Map<String, RedisTemplate> templates = new HashMap<>();
        templates.put(CACHE_NAME_DEFAULT, getDefaultRedisTemplate());
        templates.put(CACHE_NAME_COUNTRY, getMetadataRedisTemplate());
        templates.put(CACHE_NAME_DESTINATIONS, getDestinationsRedisTemplate());

        SabreRedisCacheManager sabreRedisCacheManager = new    SabreRedisCacheManager(templates);

        return sabreRedisCacheManager;
    }

    @Bean
    public RedisTemplate<Object, Object> getDefaultRedisTemplate()
    {
        return getBaseRedisTemplate();
    }

    @Bean
    public RedisTemplate<Object, Object> getCountryRedisTemplate()
    {
        RedisTemplate<Object, Object> redisTemplate = getBaseRedisTemplate();
          redisTemplate.setValueSerializer(jsonRedisSerializer(Country.class));

        return redisTemplate;
    }

    @Bean
public RedisTemplate<Object, Object> getDestinationsRedisTemplate()
{
    RedisTemplate<Object, Object> redisTemplate = getBaseRedisTemplate();
    redisTemplate.setValueSerializer(jsonRedisSerializer(TypeFactory.defaultInstance().constructCollectionType(List.class, Destination.class)));


    return redisTemplate;
}

private RedisTemplate<Object, Object> getBaseRedisTemplate()
{
    RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(jedisConnectionFactory());
    redisTemplate.setKeySerializer(stringRedisSerializer());
    redisTemplate.setHashKeySerializer(stringRedisSerializer());
    redisTemplate.setValueSerializer(jsonRedisSerializer(Object.class));

    return redisTemplate;
}

private Jackson2JsonRedisSerializer jsonRedisSerializer(Class type)
{
    return jsonRedisSerializer(TypeFactory.defaultInstance().constructType(type));
}

private Jackson2JsonRedisSerializer jsonRedisSerializer(JavaType javaType)
{
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(javaType);
    jackson2JsonRedisSerializer.setObjectMapper(new JsonObjectMapper());

    return jackson2JsonRedisSerializer;
}
}
2020-06-20