这个注解以前也没使过,可以作用在contrller上,也可以作用在service层上,建议作用在service上
1.首先遇到了@cache注解配置无效的问题
2.遇到了jackson解析报错:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance
3.遇到了redis序列化java8 LocalDateTime错误的问题
================================================================================================
具体完整的配置如下:
1.在application.yml中启用缓存
spring:
cache:
type: redis
2.缓存的对象必须实现Serializable
3.SpringBootApplication中加@EnableCaching注解
注:@Cacheable是基于Spring AOP代理类,内部方法调用是不走代理的,@Cacheable是不起作用的
以上配置解决了,@cache注解配置无效的问题
================================================================================================
在每个类上添加构造方法注解,解决jackson解析报错:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance问题
@NoArgsConstructor
@AllArgsConstructor
================================================================================================
在每个LocalDateTime字段上添加
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
解决redis无法序列化java8 LocalDateTime错误的问题
================================================================================================
配置@cache过期时间
package com.rocwo.rwshop.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
/**
* @Description 配置redis(spring boot默认实现了redis配置,但是实现的是RedisTemplate<Object, Object>,为了便于写代码重新配置为RedisTemplate<Object, Object>)
* @Author chenjian
* @Date 2019/9/27 19:28
* @Version V1.0
**/
@Configuration
@EnableCaching
public class RedisCacheConfig{
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
//从这往下是配置@cache失效时间
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
this.getRedisCacheConfigurationWithTtl(60*60), // 默认策略,未配置的 key 会使用这个
this.getRedisCacheConfigurationMap() // 指定 key 策略
);
}
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
//自定义设置缓存时间
redisCacheConfigurationMap.put("goodsCompCache", this.getRedisCacheConfigurationWithTtl(60*60));
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer)
).entryTtl(Duration.ofSeconds(seconds));
return redisCacheConfiguration;
}
}
================================================================================================
具体使用:
@Cacheable(value="goodsCompCache",key="#goodsSkuSaleId")
value为缓存的名字,key为redis的key