package com.xzx.gc.config;
|
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.xzx.gc.listener.RedisMessageListener;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Primary;
|
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.listener.ChannelTopic;
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
import org.springframework.data.redis.serializer.*;
|
|
import javax.annotation.Resource;
|
import java.time.Duration;
|
|
@Configuration
|
@EnableCaching
|
public class RedisConfig extends CachingConfigurerSupport {
|
@Resource
|
private LettuceConnectionFactory lettuceConnectionFactory;
|
|
@Autowired
|
private RedisMessageListener redisMessageListener;
|
|
|
private Duration timeToLive = Duration.ofMinutes(30);
|
|
@Override
|
@Bean //在没有指定缓存Key的情况下,key生成策略
|
public KeyGenerator keyGenerator() {
|
return (target, method, params) -> {
|
StringBuffer sb = new StringBuffer();
|
sb.append(target.getClass().getName());
|
sb.append(method.getName());
|
for (Object obj : params) {
|
sb.append(obj.toString());
|
}
|
return sb.toString();
|
};
|
}
|
|
// 缓存管理器 使用Lettuce,和jedis有很大不同
|
@Override
|
@Bean
|
public CacheManager cacheManager() {
|
//关键点,spring cache的注解使用的序列化都从这来,没有这个配置的话使用的jdk自己的序列化,实际上不影响使用,只是打印出来不适合人眼识别
|
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))//key序列化方式
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))//value序列化方式
|
.disableCachingNullValues()
|
.entryTtl(timeToLive);//缓存过期时间
|
|
|
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder
|
.fromConnectionFactory(lettuceConnectionFactory)
|
.cacheDefaults(config)
|
.transactionAware();
|
|
return builder.build();
|
}
|
|
|
/**
|
* RedisTemplate配置 在单独使用redisTemplate的时候 重新定义序列化方式
|
*/
|
@Bean
|
@Primary
|
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
// 设置序列化
|
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
|
Object.class);
|
ObjectMapper om = new ObjectMapper();
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
jackson2JsonRedisSerializer.setObjectMapper(om);
|
// 配置redisTemplate
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
|
redisTemplate.setKeySerializer(stringSerializer);// key序列化
|
redisTemplate.setValueSerializer(stringSerializer);// value序列化
|
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
|
redisTemplate.setHashValueSerializer(stringSerializer);// Hash value序列化
|
redisTemplate.afterPropertiesSet();
|
return redisTemplate;
|
}
|
|
@Bean
|
public RedisTemplate<String, Object> redisTemplateForJdk(LettuceConnectionFactory lettuceConnectionFactory) {
|
// 设置序列化
|
// 配置redisTemplate
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
|
redisTemplate.setKeySerializer(stringSerializer);// key序列化
|
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());// value序列化
|
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
|
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());// Hash value序列化
|
redisTemplate.afterPropertiesSet();
|
return redisTemplate;
|
}
|
|
private RedisSerializer<String> keySerializer() {
|
return new StringRedisSerializer();
|
}
|
|
private RedisSerializer<Object> valueSerializer() {
|
// 设置序列化
|
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
|
Object.class);
|
ObjectMapper om = new ObjectMapper();
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
jackson2JsonRedisSerializer.setObjectMapper(om);
|
return jackson2JsonRedisSerializer;
|
}
|
|
|
@Bean
|
public ChannelTopic expiredTopic() {
|
return new ChannelTopic("__keyevent@0__:expired");
|
}
|
|
@Bean
|
public RedisMessageListenerContainer redisMessageListenerContainer(LettuceConnectionFactory lettuceConnectionFactory) {
|
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
|
redisMessageListenerContainer.setConnectionFactory(lettuceConnectionFactory);
|
redisMessageListenerContainer.addMessageListener(redisMessageListener, expiredTopic());
|
return redisMessageListenerContainer;
|
}
|
|
|
}
|