package com.jilongda.common.redis;
|
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.cache.Cache;
|
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.KeyGenerator;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Import;
|
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
import org.springframework.data.redis.cache.RedisCacheManager;
|
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
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.RedisSerializer;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|
import java.lang.reflect.Method;
|
import java.time.Duration;
|
|
|
/**
|
* swagger2 的spring-boot启动器
|
* <p>
|
* <p>
|
* 开启缓存配置
|
*
|
* @author xiaochen
|
*/
|
@Configuration
|
@Slf4j
|
@EnableCaching
|
@Import(RedisAutoTemplate.class)
|
public class RedisAutoConfiguration extends CachingConfigurerSupport {
|
|
private final LettuceConnectionFactory lettuceConnectionFactory;
|
|
@Autowired
|
public RedisAutoConfiguration(LettuceConnectionFactory lettuceConnectionFactory) {
|
this.lettuceConnectionFactory = lettuceConnectionFactory;
|
}
|
|
|
/**
|
* 默认生成key
|
*
|
* @return
|
*/
|
@Bean
|
@Override
|
public KeyGenerator keyGenerator() {
|
return new KeyGenerator() {
|
@Override
|
public Object generate(Object target, Method method, Object... params) {
|
StringBuilder sb = new StringBuilder();
|
sb.append(target.getClass().getName());
|
sb.append("::" + method.getName() + ":");
|
for (Object obj : params) {
|
sb.append(obj.toString());
|
}
|
return sb.toString();
|
}
|
};
|
}
|
|
|
/**
|
* 缓存管理器
|
*
|
* @return
|
*/
|
@Override
|
@Bean
|
public CacheManager cacheManager() {
|
// 序列化 配置RedisCacheConfiguration的序列化方式为json
|
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
//创建Json序列化对象
|
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
//解决查询缓存转换异常的问题
|
ObjectMapper om = new ObjectMapper();
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
jackson2JsonRedisSerializer.setObjectMapper(om);
|
|
// 将默认序列化改为Jackson2JsonRedisSerializer序列化
|
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
// 默认5秒过期
|
.entryTtl(Duration.ofSeconds(5L))
|
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
|
// value 使用jdk的序列化方式
|
//.setValueSerializer(new JdkSerializationRedisSerializer());
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
|
.disableCachingNullValues();
|
RedisCacheManager cacheManager = RedisCacheManager.builder(lettuceConnectionFactory)
|
.cacheDefaults(config)
|
.build();
|
return cacheManager;
|
}
|
|
/**
|
* RedisTemplate配置
|
*
|
* @return
|
*/
|
@Bean
|
public RedisTemplate<String, Object> redisTemplate() {
|
//解决查询缓存转换异常的问题
|
ObjectMapper om = new ObjectMapper();
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
// 配置redisTemplate
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
// 使用fastjson序列化
|
// FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
|
//设置序列化
|
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
jackson2JsonRedisSerializer.setObjectMapper(om);
|
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
|
// key序列化
|
redisTemplate.setKeySerializer(stringSerializer);
|
// value序列化
|
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
// Hash key序列化
|
redisTemplate.setHashKeySerializer(stringSerializer);
|
// Hash value序列化
|
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
redisTemplate.afterPropertiesSet();
|
return redisTemplate;
|
}
|
|
@Bean
|
@ConditionalOnMissingBean(StringRedisTemplate.class)
|
public StringRedisTemplate stringRedisTemplate() {
|
StringRedisTemplate template = new StringRedisTemplate();
|
template.setConnectionFactory(lettuceConnectionFactory);
|
return template;
|
}
|
|
@Bean
|
public RedisMessageListenerContainer redisMessageListenerContainer() {
|
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
|
redisMessageListenerContainer.setConnectionFactory(lettuceConnectionFactory);
|
return redisMessageListenerContainer;
|
}
|
|
|
/**
|
* redis 异常日志
|
*
|
* @return
|
*/
|
@Override
|
@Bean
|
public CacheErrorHandler errorHandler() {
|
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
|
log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
|
CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
|
@Override
|
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
|
log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
|
}
|
|
@Override
|
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
|
log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
|
}
|
|
@Override
|
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
|
log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
|
}
|
|
@Override
|
public void handleCacheClearError(RuntimeException e, Cache cache) {
|
log.error("Redis occur handleCacheClearError:", e);
|
}
|
};
|
return cacheErrorHandler;
|
}
|
|
}
|