|
|
@@ -0,0 +1,128 @@
|
|
|
+package com.inspur.customer.config;
|
|
|
+
|
|
|
+import com.google.common.base.Joiner;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
|
|
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
|
|
+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.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.serializer.Jackson2JsonRedisSerializer;
|
|
|
+import org.springframework.data.redis.serializer.RedisSerializationContext;
|
|
|
+import org.springframework.data.redis.serializer.RedisSerializer;
|
|
|
+import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|
|
+import org.springframework.lang.Nullable;
|
|
|
+
|
|
|
+import java.time.Duration;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Redis 配置
|
|
|
+ *
|
|
|
+ * @author liangke
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Configuration
|
|
|
+@EnableCaching
|
|
|
+@AutoConfigureAfter(RedisAutoConfiguration.class)
|
|
|
+public class RedisConfig extends CachingConfigurerSupport {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 自定义缓存 key 的生成策略。默认的生成策略是不可读。
|
|
|
+ * 通过 Spring 的依赖注入特性进行自定义的配置注入并且此类是一个配置类可以更多程度的自定义配置
|
|
|
+ *
|
|
|
+ * @return KeyGenerator
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ @Override
|
|
|
+ public KeyGenerator keyGenerator() {
|
|
|
+ return (target, method, params) -> Joiner.on(':').skipNulls().join(target.getClass().getName(), method.getName(), params);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重写 errorHandler 方法,使 redis 异常后,不直接抛出异常,而是能继续执行函数,并且记录这次异常
|
|
|
+ *
|
|
|
+ * @return CacheErrorHandler
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ @Override
|
|
|
+ public CacheErrorHandler errorHandler() {
|
|
|
+ return new CacheErrorHandler() {
|
|
|
+ @Override
|
|
|
+ public void handleCacheGetError(@Nullable RuntimeException exception, @Nullable Cache cache, @Nullable Object key) {
|
|
|
+ log.error("Get {} from redis Error", key, exception);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void handleCachePutError(@Nullable RuntimeException exception, @Nullable Cache cache, @Nullable Object key, @Nullable Object value) {
|
|
|
+ log.error("Put {} from redis Error", key, exception);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void handleCacheEvictError(@Nullable RuntimeException exception, @Nullable Cache cache, @Nullable Object key) {
|
|
|
+ log.error("Evict {} from redis Error", key, exception);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void handleCacheClearError(@Nullable RuntimeException exception, @Nullable Cache cache) {
|
|
|
+ log.error("Clear from redis Error", exception);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存配置管理器
|
|
|
+ *
|
|
|
+ * @return CacheManager
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public CacheManager cacheManager(LettuceConnectionFactory factory) {
|
|
|
+ log.info("redisCacheManager");
|
|
|
+ RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
|
|
+ Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
|
|
+ jackson2JsonRedisSerializer.setObjectMapper(JsonObjectMapper.INSTANCE.getInstance());
|
|
|
+ // 创建默认缓存配置对象
|
|
|
+ RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
|
|
+ .entryTtl(Duration.ofHours(3L))
|
|
|
+ .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
|
|
|
+ .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
|
|
|
+ .disableCachingNullValues();
|
|
|
+ return RedisCacheManager.builder(factory)
|
|
|
+ .cacheDefaults(config)
|
|
|
+ .transactionAware()
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取缓存操作对象
|
|
|
+ *
|
|
|
+ * @return RedisTemplate
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) {
|
|
|
+ //创建 Redis 缓存模板操作 RedisTemplate 对象
|
|
|
+ RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
|
|
+ redisTemplate.setConnectionFactory(factory);
|
|
|
+ // 使用 Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是 JDK 序列化)
|
|
|
+ Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
|
|
+ jackson2JsonRedisSerializer.setObjectMapper(JsonObjectMapper.INSTANCE.getInstance());
|
|
|
+ // 设置键(key)的序列化采用 redisSerializer。
|
|
|
+ RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
|
|
+ redisTemplate.setKeySerializer(redisSerializer);
|
|
|
+ redisTemplate.setHashKeySerializer(redisSerializer);
|
|
|
+ // 设置值(value)的序列化采用 jackson2JsonRedisSerializer。
|
|
|
+ redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
|
|
+ redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
|
|
+
|
|
|
+ redisTemplate.afterPropertiesSet();
|
|
|
+ return redisTemplate;
|
|
|
+ }
|
|
|
+}
|