|
@@ -0,0 +1,98 @@
|
|
|
|
+package com.ozs.config;
|
|
|
|
+
|
|
|
|
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
|
|
|
+import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
+import org.springframework.cache.CacheManager;
|
|
|
|
+import org.springframework.cache.annotation.CachingConfigurerSupport;
|
|
|
|
+import org.springframework.cache.annotation.EnableCaching;
|
|
|
|
+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.core.RedisTemplate;
|
|
|
|
+import org.springframework.data.redis.core.script.DefaultRedisScript;
|
|
|
|
+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.time.Duration;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * redis配置
|
|
|
|
+ *
|
|
|
|
+ * @author hx
|
|
|
|
+ */
|
|
|
|
+@Configuration
|
|
|
|
+@EnableCaching
|
|
|
|
+public class RedisConfig extends CachingConfigurerSupport {
|
|
|
|
+ @Bean
|
|
|
|
+ @SuppressWarnings(value = {"unchecked", "rawtypes"})
|
|
|
|
+ public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
|
|
|
|
+ RedisTemplate<Object, Object> template = new RedisTemplate<>();
|
|
|
|
+ template.setConnectionFactory(connectionFactory);
|
|
|
|
+
|
|
|
|
+ FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
|
|
|
|
+
|
|
|
|
+ // 使用StringRedisSerializer来序列化和反序列化redis的key值
|
|
|
|
+ template.setKeySerializer(new StringRedisSerializer());
|
|
|
|
+ template.setValueSerializer(serializer);
|
|
|
|
+
|
|
|
|
+ // Hash的key也采用StringRedisSerializer的序列化方式
|
|
|
|
+ template.setHashKeySerializer(new StringRedisSerializer());
|
|
|
|
+ template.setHashValueSerializer(serializer);
|
|
|
|
+
|
|
|
|
+ template.afterPropertiesSet();
|
|
|
|
+ return template;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ public CacheManager cacheManager(RedisConnectionFactory factory) {
|
|
|
|
+ RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
|
|
|
+ Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
|
|
|
|
+ Jackson2JsonRedisSerializer(Object.class);
|
|
|
|
+//解决查询缓存转换异常的问题
|
|
|
|
+ ObjectMapper om = new ObjectMapper();
|
|
|
|
+ om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
|
|
|
+ om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
|
|
|
+ jackson2JsonRedisSerializer.setObjectMapper(om);
|
|
|
|
+// 配置序列化(解决乱码的问题),过期时间600秒
|
|
|
|
+ RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
|
|
|
+ .entryTtl(Duration.ofSeconds(600))
|
|
|
|
+ .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
|
|
|
|
+ .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
|
|
|
|
+ .disableCachingNullValues();
|
|
|
|
+ RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
|
|
|
|
+ .cacheDefaults(config)
|
|
|
|
+ .build();
|
|
|
|
+ return cacheManager;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ public DefaultRedisScript<Long> limitScript() {
|
|
|
|
+ DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
|
|
|
|
+ redisScript.setScriptText(limitScriptText());
|
|
|
|
+ redisScript.setResultType(Long.class);
|
|
|
|
+ return redisScript;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 限流脚本
|
|
|
|
+ */
|
|
|
|
+ private String limitScriptText() {
|
|
|
|
+ return "local key = KEYS[1]\n" +
|
|
|
|
+ "local count = tonumber(ARGV[1])\n" +
|
|
|
|
+ "local time = tonumber(ARGV[2])\n" +
|
|
|
|
+ "local current = redis.call('get', key);\n" +
|
|
|
|
+ "if current and tonumber(current) > count then\n" +
|
|
|
|
+ " return tonumber(current);\n" +
|
|
|
|
+ "end\n" +
|
|
|
|
+ "current = redis.call('incr', key)\n" +
|
|
|
|
+ "if tonumber(current) == 1 then\n" +
|
|
|
|
+ " redis.call('expire', key, time)\n" +
|
|
|
|
+ "end\n" +
|
|
|
|
+ "return tonumber(current);";
|
|
|
|
+ }
|
|
|
|
+}
|