springboot集成redis(源碼)

springboot項目配置redis

application.yml文件redis配置

redis:
    # 本地
    # 數據庫(默認0)
    database: 1
    host: 127.0.0.1
    port: 6379
    password: XXX
    pool:
      max-active: 8
      max-wait: -1
      max-idle: 20
      min-idle: 0
    timeout: 30000

springboot項目maven配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.67</version>
</dependency>

redis配置

@Configuration
@EnableCaching //開啓註解式緩存
//繼承CachingConfigurerSupport,爲了自定義生成KEY的策略。可以不繼承。
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * @Description: 生成key的策略 根據類名+方法名+所有參數的值生成唯一的一個key
     * @Author: Mr.Jkx
     * @date: 2020/3/24 13:16
     */
    @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();
            }
        };
    }

    /**
     * @Description: 管理緩存
     * @Author: Mr.Jkx
     * @date: 2020/3/24 13:17
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //通過Spring提供的RedisCacheConfiguration類,構造一個自己的redis配置類,從該配置類中可以設置一些初始化的緩存命名空間
        // 及對應的默認過期時間等屬性,再利用RedisCacheManager中的builder.build()的方式生成cacheManager:
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();  // 生成一個默認配置,通過config對象即可對緩存進行自定義配置
        config = config.entryTtl(Duration.ofMinutes(1))     // 設置緩存的默認過期時間,也是使用Duration設置
                .disableCachingNullValues();     // 不緩存空值

        // 設置一個初始化的緩存空間set集合
        Set<String> cacheNames = new HashSet<>();
        cacheNames.add("my-redis-cache1");
        cacheNames.add("my-redis-cache2");

        // 對每個緩存空間應用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("my-redis-cache1", config);
        configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)     // 使用自定義的緩存配置初始化一個cacheManager
                .initialCacheNames(cacheNames)  // 注意這兩句的調用順序,一定要先調用該方法設置初始化的緩存名,再初始化相關的配置
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

    /**
     * @Description: 自定義序列化方式(使用alibaba >>> FastJsonRedisSerializer)
     * @Author: Mr.Jkx
     * @date: 2020/4/16 18:03
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        // 全局開啓AutoType
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

        // 設置值(value)的序列化採用FastJsonRedisSerializer。
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        // 設置鍵(key)的序列化採用StringRedisSerializer。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }
}

redis數據過期事件處理

/**
 * @program: youpin
 * @description: redis過期事件的監聽類
 * @author: Mr.Jkx
 * @create: 2020-04-16 18:52
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    private static final Logger LOGGER = (Logger) LoggerFactory.getLogger(RedisKeyExpirationListener.class);

    public RedisKeyExpirationListener(RedisMessageListenerContainer container) {
        super(container);
    }

    /**
     * @Description: 針對redis數據失效事件,進行數據處理
     * <p>
     * 此處獲取的信息均爲未支付的過期訂單,支付過的訂單在支付回調中已經刪除了
     * @Author: Mr.Jkx
     * @date: 2020/4/16 18:58
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        //生效的key
        String key = message.toString();
        LOGGER.info("----redis listener get data key:{}----", key);
        //從失效key中篩選代表訂單失效的key(startsWith:檢測字符串是否以指定的前綴開始)
        if (key != null && key.startsWith("redis_")) {
            //截取訂單主鍵id,查詢訂單
            String orderId = key.substring(8);
            // 根據主鍵id查詢數據進行業務邏輯處理 TODO
        }
    }
}

redis監聽信息配置

/**
 * @program: youpin
 * @description: redis 監聽配置
 * @author: Mr.Jkx
 * @create: 2020-04-16 18:37
 */
@Configuration
public class RedisListenerConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);

        //可以添加多個 messageListener,訂閱了一個叫“redisListener”的通道
        container.addMessageListener(listenerAdapter, new PatternTopic("redisListener"));

        return container;
    }

    /**
     * 消息監聽器適配器,綁定消息處理器,利用反射技術調用消息處理器的業務方法
     *
     * @param redisReceiver
     * @return
     */
    @Bean
    MessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) {
        // 這個地方 是給messageListenerAdapter 傳入一個消息接受的處理器,利用反射的方法調用“receiveMessage”
        // 也有好幾個重載方法,這邊默認調用處理器的方法 叫handleMessage 可以自己到源碼裏面看
        return new MessageListenerAdapter(redisReceiver, "receiveMessage");
    }

    //使用默認的工廠初始化redis操作模板
    @Bean
    StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }
} 

redis監聽消息處理

/**
 * @program: youpin
 * @description: 消息接收(消費)
 * @author: Mr.Jkx
 * @create: 2020-04-17 16:57
 */
@Component
public class RedisReceiver {
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisReceiver.class);

    /**
     * @Description: 消息消費
     * @Author: Mr.Jkx
     * @date: 2020/4/17 17:30
     * 此方法是在“RedisListenerConfig”反射調用
     */
    public void receiveMessage(String message) {
    	LOGGER.info("消息來了:" + message);
    }
}

redis數據處理工具類

/**
 * @program: youpin
 * @description: redis
 * @author: Mr.Jkx
 * @create: 2020-03-24 13:13
 */
@Service
public class RedisService {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 寫入緩存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 寫入緩存設置時效時間
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 批量刪除對應的value
     *
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量刪除key
     *
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 刪除對應的value
     *
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判斷緩存中是否有對應的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 讀取緩存
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        return operations.get(key);
    }

    /**
     * 哈希 添加
     *
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, hashKey, value);
    }

    /**
     * 哈希獲取數據
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, hashKey);
    }

    /**
     * 哈希數據刪除
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Long hmDel(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.delete(key, hashKey);
    }

    /**
     * 哈希數據加減計算
     *
     * @param key
     * @param hashKey
     * @param index
     * @return
     */
    public Long hmcompute(String key, Object hashKey, long index) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.increment(key, hashKey, index);
    }

    /**
     * 列表添加
     *
     * @param k
     * @param v
     */
    public void rPush(String k, Object v) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k, v);
    }

    /**
     * 獲取最左側的列表數據
     *
     * @param k
     * @param timeout
     * @param unit
     * @return
     */
    public Object leftPop(String k, long timeout, TimeUnit unit) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.leftPop(k, timeout, unit);
    }

    /**
     * 列表獲取
     *
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k, l, l1);
    }

    /**
     * 集合添加
     *
     * @param key
     * @param value
     */
    public void add(String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    /**
     * 集合獲取
     *
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     *
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }

    /**
     * 有序集合獲取
     *
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }

    /**
     * @Description: redis 消息訂閱發佈,向通道發送消息的方法
     * @Author: Mr.Jkx
     * @date: 2020/4/17 17:09
     */
    public void sendChannelMess(String channel, Object message) {
        redisTemplate.convertAndSend(channel, message);
    }
}

作者能力有限,如有問題歡迎批評指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章