spring-data-redis - springmvc项目中使用@CachePut缓存数据到redis的问题

查看:114
本文介绍了spring-data-redis - springmvc项目中使用@CachePut缓存数据到redis的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

在springmvc项目中使用@CachePut缓存数据到redis,存储到redis的数据变成了key和value独立的两条数据:

而在springboot项目中进行相同的操作却没用这样的问题,缓存的是正常的数据:

springmvc项目中redis的相关如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 配置JedisPoolConfig相关参数 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${spring.redis.pool.maxTotal}"></property>
        <property name="maxIdle" value="${spring.redis.pool.maxIdle}"></property>
        <property name="minIdle" value="${spring.redis.pool.minIdle}"></property>
        <property name="maxWaitMillis" value="${spring.redis.pool.maxWait}"></property>
    </bean>

    <!-- 配置redis服务器信息 -->
    <bean id="connectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig" ref="poolConfig"></property>
        <property name="hostName" value="${spring.redis.host}"></property>
        <property name="port" value="${spring.redis.port}"></property>
        <property name="password" value="${spring.redis.password}"></property>
        <property name="database" value="${spring.redis.database}"></property>
        <property name="timeout" value="${spring.redis.timeout}"></property>
    </bean>

    <!-- 配置RedisCacheManager -->
    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
    </bean>

    <!-- 配置redis连接池 -->
    <bean class="redis.clients.jedis.JedisPool">
        <constructor-arg ref="poolConfig"/>
        <constructor-arg value="${spring.redis.host}"/>
        <constructor-arg type="int" value="${spring.redis.port}"/>
        <constructor-arg type="int" value="${spring.redis.timeout}"/>
        <constructor-arg type="java.lang.String" value="${spring.redis.password}"/>
        <constructor-arg type="int" value="${spring.redis.database}"/>
    </bean>

</beans>

以及

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    private static final Java8TimePatternProperties properties = new Java8TimePatternProperties();

    @Bean
    public RedisTemplate<String , Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(properties.dateFormatter()));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(properties.timeFormatter()));
        javaTimeModule.addSerializer(YearMonth.class, new YearMonthSerializer(properties.yearMonthFormatter()));
        javaTimeModule.addSerializer(MonthDay.class, new MonthDaySerializer(properties.monthDayFormatter()));
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(properties.dateTimeFormatter()));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(properties.dateFormatter()));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(properties.timeFormatter()));
        javaTimeModule.addDeserializer(YearMonth.class, new YearMonthDeserializer(properties.yearMonthFormatter()));
        javaTimeModule.addDeserializer(MonthDay.class, new MonthDayDeserializer(properties.monthDayFormatter()));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(properties.dateTimeFormatter()));
        mapper.registerModule(javaTimeModule);
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }

}

请问是哪里配置有问题吗?

解决方案

找到原因了,RedisCacheManager里的usePrefix默认为false,


跟踪源码发现usePrefix=false时,key也会存为一行数据:

解决办法

去掉xml配置里的RedisCacheManager配置,

   <!-- 配置RedisCacheManager -->
   <!-- <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
    </bean> -->

在JavaConfig里面加上如下配置:

    @Bean
    public RedisCacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }

RedisCacheManagerusePrefix改为true即可。

这篇关于spring-data-redis - springmvc项目中使用@CachePut缓存数据到redis的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆