Cache with redis cache manager, redisTemplate and

2019-09-05 21:18发布

I need to cache multiple types like:

public Country findCountry(String countryName)

and:

public List<Destination> findAllDestinations(String countryName)

I am using RedisCacheManager and RedisTemplate only support only one serializer.

1条回答
祖国的老花朵
2楼-- · 2019-09-05 21:52

It is solved now after some research.

  1. change spring-data-redis to 1.4.2.RELEASE
  2. extend RedisCacheManager with your class with cache map to serializer (cacheName->serializer) and caches names
  3. overrides the getCache method(Cache getCache(String name)) and based on cache name, set the serializer name in the redis template
  4. use your customized cache manager

Example -

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;
}
}
查看更多
登录 后发表回答