188 lines
7.9 KiB
Java
188 lines
7.9 KiB
Java
package com.xkrs.common.config;
|
||
|
||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||
import com.fasterxml.jackson.core.JsonGenerator;
|
||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
import org.springframework.cache.CacheManager;
|
||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||
import org.springframework.cache.annotation.EnableCaching;
|
||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||
import org.springframework.cache.interceptor.CacheResolver;
|
||
import org.springframework.cache.interceptor.KeyGenerator;
|
||
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.connection.RedisConnectionFactory;
|
||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||
import org.springframework.data.redis.core.RedisTemplate;
|
||
import org.springframework.data.redis.serializer.*;
|
||
|
||
import javax.annotation.Resource;
|
||
import java.io.IOException;
|
||
import java.time.Duration;
|
||
|
||
/**
|
||
* redis配置
|
||
* @author tajochen
|
||
*/
|
||
@Configuration
|
||
@EnableCaching
|
||
public class RedisConfig extends CachingConfigurerSupport{
|
||
|
||
private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class);
|
||
|
||
@Resource
|
||
private LettuceConnectionFactory lettuceConnectionFactory;
|
||
|
||
private static final Duration TIME_TO_LIVE = Duration.ofSeconds(3600*6);
|
||
|
||
@Bean
|
||
@Override
|
||
public KeyGenerator keyGenerator() {
|
||
|
||
// 设置自动key的生成规则,配置spring boot的注解,进行方法级别的缓存
|
||
return (target, method, params) -> {
|
||
StringBuilder sb = new StringBuilder();
|
||
sb.append(target.getClass().getName());
|
||
sb.append(":");
|
||
sb.append(method.getName());
|
||
for (Object obj : params) {
|
||
sb.append(":").append(obj);
|
||
}
|
||
// logger.info("自动生成Redis Key -> [{}]", rsToUse);
|
||
return String.valueOf(sb);
|
||
};
|
||
}
|
||
|
||
@Bean
|
||
@Override
|
||
public CacheManager cacheManager() {
|
||
// 关键点,spring cache的注解使用的序列化都从这来,没有这个配置的话使用的jdk自己的序列化
|
||
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
||
//key序列化方式
|
||
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
|
||
//value序列化方式
|
||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
|
||
.disableCachingNullValues()
|
||
.entryTtl(TIME_TO_LIVE);
|
||
|
||
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder
|
||
.fromConnectionFactory(lettuceConnectionFactory)
|
||
.cacheDefaults(config)
|
||
.transactionAware();
|
||
|
||
return builder.build();
|
||
}
|
||
|
||
|
||
/**
|
||
* RedisTemplate配置 在单独使用redisTemplate的时候 重新定义序列化方式
|
||
*/
|
||
@Bean(name = "redisTemplate")
|
||
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
||
// 设置序列化
|
||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||
ObjectMapper om = new ObjectMapper();
|
||
// 配置null值序列化成空字符串
|
||
om.getSerializerProvider().setNullValueSerializer(new JsonSerializer<>() {
|
||
@Override
|
||
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||
jsonGenerator.writeString("");
|
||
}
|
||
});
|
||
// 解决jackson无法反序列化LocalDateTime的问题,引入jsr310标准
|
||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||
om.registerModule(javaTimeModule);
|
||
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||
// 其他设置
|
||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
|
||
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||
// 配置redisTemplate
|
||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
|
||
redisTemplate.setKeySerializer(stringSerializer);
|
||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
||
redisTemplate.setHashKeySerializer(stringSerializer);
|
||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||
redisTemplate.afterPropertiesSet();
|
||
return redisTemplate;
|
||
}
|
||
|
||
private RedisSerializer<String> keySerializer() {
|
||
return new StringRedisSerializer();
|
||
}
|
||
|
||
private RedisSerializer<Object> valueSerializer() {
|
||
// 设置序列化
|
||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
|
||
Object.class);
|
||
ObjectMapper om = new ObjectMapper();
|
||
// 解决jackson无法反序列化LocalDateTime的问题,引入jsr310标准
|
||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||
om.registerModule(javaTimeModule);
|
||
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||
// 其他设置
|
||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
|
||
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||
return jackson2JsonRedisSerializer;
|
||
}
|
||
|
||
@Override
|
||
public CacheResolver cacheResolver() {
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 设置数据存入 redis 的序列化方式,并开启事务
|
||
*
|
||
* @param redisTemplate
|
||
* @param factory
|
||
*/
|
||
private void initRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
|
||
//如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!
|
||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||
// 开启事务
|
||
redisTemplate.setEnableTransactionSupport(true);
|
||
redisTemplate.setConnectionFactory(factory);
|
||
}
|
||
|
||
/**
|
||
* 注入封装RedisTemplate 给RedisUtil提供操作类
|
||
* @param redisTemplate
|
||
* @return RedisUtil
|
||
*/
|
||
@Bean(name = "redisUtil")
|
||
public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
|
||
RedisUtil redisUtil = new RedisUtil();
|
||
redisUtil.setRedisTemplate(redisTemplate);
|
||
return redisUtil;
|
||
}
|
||
|
||
@Override
|
||
@Bean
|
||
public CacheErrorHandler errorHandler() {
|
||
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
|
||
logger.info("初始化 -> [{}]", "Redis CacheErrorHandler");
|
||
return null;
|
||
}
|
||
|
||
}
|