方法一 配置類
//redis配置類
@Configuration
public class RedisConf extends CachingConfigurerSupport {
/*
配置自定義RedisTemplate
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
//配置連接工廠
template.setConnectionFactory(factory);
template.setKeySerializer(keySerializer());
template.setValueSerializer(valueSerializer());
template.setHashKeySerializer(keySerializer());
template.setValueSerializer(valueSerializer());
return template;
}
/*
org.springframework.cache.interceptor包下的
自定義key的生成策略,對應@Cacheable中的keyGenerator
實例對象+方法名+參數名
*/
@Bean
public KeyGenerator keyGenerator() {
/*
target調用緩存方法的實例
method調用緩存的方法
params方法的參數
*/
return (tagert, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(tagert.getClass().getName())
.append(method.getName());
for (Object param : params) {
sb.append(param.toString());
}
//返回key
return sb.toString();
};
}
/*
自定義緩存管理
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
return RedisCacheManager.builder(factory).
//默認緩存策略
cacheDefaults(redisCacheConfiguration(600L)).
//配置不同緩存域,不同過期時間
withInitialCacheConfigurations(RedisCacheConfigurationMap()).
//更新刪除上鎖
transactionAware().
build();
}
/*
配置redis的cache策略
*/
private RedisCacheConfiguration redisCacheConfiguration(Long sec) {
return RedisCacheConfiguration.defaultCacheConfig().
//設置key的序列化,采用stringRedisSerializer
serializeKeysWith
(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())).
//設置value的序列化,采用Jackson2JsonRedis
serializeValuesWith
(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())).
//設置cache的過期策略
entryTtl(Duration.ofSeconds(sec)).
//不緩存null的值
disableCachingNullValues();
}
/*
不同緩存域,不同過期時間,map的key可以被@Cacheable中的value使用
*/
private Map<String, RedisCacheConfiguration> RedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
redisCacheConfigurationMap.put("userInfo", redisCacheConfiguration(3000L));
redisCacheConfigurationMap.put("otherInfo", redisCacheConfiguration(1000L));
return redisCacheConfigurationMap;
}
/*
key采用序列化策略
*/
private RedisSerializer<String> keySerializer() {
return new StringRedisSerializer();
}
/*
value采用序列化策略
*/
private RedisSerializer<Object> valueSerializer() {
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
//序列化所有類包括jdk提供的
ObjectMapper om = new ObjectMapper();
//設置序列化的域(屬性,方法etc)以及修飾范圍,Any包括private,public 默認是public的
//ALL所有方位,ANY所有修飾符
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//enableDefaultTyping 原來的方法存在漏洞,2.0后改用如下配置
//指定輸入的類型
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL);
//如果java.time包下Json報錯,添加如下兩行代碼
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new JavaTimeModule());
serializer.setObjectMapper(om);
return serializer;
}
}
方法二 POJO
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime date;