package com.ruoyi.framework.config; 
 | 
  
 | 
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.connection.RedisConnectionFactory; 
 | 
import org.springframework.data.redis.core.RedisTemplate; 
 | 
import org.springframework.data.redis.core.script.DefaultRedisScript; 
 | 
import org.springframework.data.redis.serializer.StringRedisSerializer; 
 | 
import com.fasterxml.jackson.annotation.JsonAutoDetect; 
 | 
import com.fasterxml.jackson.annotation.JsonTypeInfo; 
 | 
import com.fasterxml.jackson.annotation.PropertyAccessor; 
 | 
import com.fasterxml.jackson.databind.ObjectMapper; 
 | 
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; 
 | 
  
 | 
/** 
 | 
 * redis配置 
 | 
 *  
 | 
 * @author ruoyi 
 | 
 */ 
 | 
@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); 
 | 
  
 | 
        ObjectMapper mapper = new ObjectMapper(); 
 | 
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 
 | 
        mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); 
 | 
        serializer.setObjectMapper(mapper); 
 | 
  
 | 
        // 使用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 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);"; 
 | 
    } 
 | 
} 
 |