自定义redis监听器

该监听器主要用于监听redis的失效Key,根据此key来做一些其他业务(在此我用来处理redis的list结构中保存的Key,该key本身使用string类型保存了一些其他的json数据,你们可根据自己的业务需求来做其他处理)

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.*;
import javax.annotation.Resource;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    private final RedisTemplate redisTemplate;

    @Autowired
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer, RedisTemplate redisTemplate) {
        super(listenerContainer);
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        log.info("进入key失效监听事件!");
        performOperationForRedis(message);
    }

    /**
     * 异步执行删除失效key业务
     *
     * @param message
     */
    @Async
    public void performOperationForRedis(Message message) {
        String uuid = message.toString(); // 获取到失效的key
        FileService fileService = new FileService();
        try {
            String substring = uuid.substring(0, 4);
            // 新开线程,执行redis删除操作
            Set keys = redisTemplate.keys("*");
            List list = new ArrayList<>(keys);
            log.info("执行redis删除操作!");
            for (String key : list) {
                // 过滤掉hash格式的key(不以图片存储格式结尾)
                if (!key.endsWith("Jpeg") && !key.endsWith("jpg")) {
                    ListOperations listOperations = redisTemplate.opsForList();
                    // 不是hash格式的key则获取整个列表
                    List redisList = getRedisList(listOperations, key); // 该方法处理了异常,key为空或值无法获取的则返回空集合
                    // 获取到的集合数据不为空
                    if (redisList != null) {
                        // 循环获取到集合中存在的单个元素(单个key)
                        for (Object aaa : redisList) {
                            // 判断获取出的Key是否是失效的key
                            if (StringUtils.equals(String.valueOf(aaa), uuid)) {
                                listOperations.remove(key, 0, uuid);
                                log.info("失效key删除成功");
                            }
                        }
                    }
                }
            }
            log.info("缓存清理完成!");
        } catch (Exception e) {
            log.info("删除redis数据失败-》uuid: " + uuid);
            e.printStackTrace();
        }
    }

    /**
     * 获取redis中该key下的所有值方法(考虑到key存在但数据不存在会报异常,或者key不存在会报异常的两种情况,抽出方法来做单独的异常捕获)
     *
     * @param listOperations
     * @param key
     * @return
     */
    public List getRedisList(ListOperations listOperations, String key) {
        try {
            // 获取redis列表中的值
            List range = listOperations.range(key, 0, -1);
            return range;
        } catch (Exception e) {
            // 异常返回空集合
            return null;
        }
    }
}

你可能感兴趣的:(Java合集,redis,java,mybatis)