当前位置: 首页 > 面试题库 >

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

彭鸿哲
2023-03-14
问题内容

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

public Country findCountry(String countryName)

和:

public List<Destination> findAllDestinations(String countryName)

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


问题答案:

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

  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;
}
}


 类似资料:
  • 为spring boot应用程序集成EhCache3缓存提供程序。我需要决定使用哪个缓存管理器。理想情况下,我希望在我的缓存方法上使用Springs缓存注释,例如@Cacheable,而不是jsr(@CacheResult),但对于cachemanager/cache库,我无法决定以下内容 我决定使用ehcache3提供程序进行缓存库注释: 对哪种实施方式有何建议?也许我不清楚上面的实现有什么不同

  • 我在SpringBootApplication中实现了缓存,如下所示 那么,如果我们不定义CacheManager将使用什么呢?

  • 我了解到,使用服务工作者进行脱机缓存与浏览器缓存类似。如果是这样的话,那么为什么您希望使用服务工作者进行此缓存?浏览器缓存将检查文件是否被修改,然后从缓存中提供服务,通过服务工作者,我们将从代码中处理相同的事情。默认情况下,浏览器具有该功能,那么为什么更喜欢服务人员呢?

  • 目前,我正在使用带有Ehcache的@缓存来使用Spring cache。我将使用Spring Data Redis 2.0.3用Redis替换Ehcache。我在网上看到的所有示例都是基于旧版本的,但是新版本有不同格式的构造函数。 这是我当前的cacheManager配置: 基于旧版本使用Redis的示例如下: 新版本中的构造函数与旧版本完全不同,新版本的所有示例都像这样手动将所有内容放入缓存:

  • 我在我的应用程序中使用了spring缓存层,我在编写使用Mockito测试spring缓存层的单元测试时遇到了一个问题。 服务层的JUnit测试代码: 例外情况: 我得到了一个“”,因为缓存层没有工作,并且调用被传递到repository对象(两次),该对象返回了上面的'Customer2'模拟对象,即通过传递服务层,对同一个键调用了两次repository方法。

  • 我想缓存来自第三方API的响应,该API提供自己的客户端和数据类。但问题是,这两个数据类都没有实现接口,因此使用Spring Boot Cache Redis进行缓存时,在我尝试时抛出。 是否可以通过某种方式将Spring Boot Redis缓存配置为允许缓存未实现可序列化的对象?