一.实战需求:redis-key过期监听

二.问题:大量key会造成监听代码臃肿

三.解决方案:使用策略模式+工厂模式代替if-else

 

代码:

第一部分:redis-springboot配置

package com.htjx.common.redismonitor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;

/**
 * 功能描述: <br> rediskey监听
 * @Author: zhang
 * @Date: 2021/9/7 15:39
 */
@Configuration
public class RedisListenerConfig {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Autowired
    private RedisListenerHandel keyExpiredListener;
    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer() {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
        // 配置监听器监听的主题关联
        Topic topic = new ChannelTopic("__keyevent@0__:expired");
        redisMessageListenerContainer.addMessageListener(keyExpiredListener, topic);
        Topic topic2 = new ChannelTopic("__keyevent@1__:expired");
        redisMessageListenerContainer.addMessageListener(keyExpiredListener, topic2);
        return redisMessageListenerContainer;
    }

}

 

第二部分:监听处理器

package com.htjx.common.redismonitor;


import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;

/**
 * 功能描述: <br> key过期监听处理器
 * @Author: zhang
 * @Date: 2021/9/7 17:57
 */
@Component
public class RedisListenerHandel implements  MessageListener {

private static String SUFFIX="expire:";

    @Override
    public void onMessage(Message message, byte[] pattern) {
        System.err.println(message.toString());
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        String expiredKey = message.toString();
       String key= expiredKey.split(SUFFIX)[0]+SUFFIX;
        System.err.println(key);
        RedisListenerFactory.get(key).execute(expiredKey);
    }
}

 

第三部分:策略接口

package com.htjx.common.redismonitor;

public interface RedisListenerStrategy {
    void execute(String keyInfo);
}

 

第四部分:工厂类

package com.htjx.common.redismonitor;

import java.util.HashMap;

public class RedisListenerFactory {

    private static HashMap<String,RedisListenerStrategy> objMap=new HashMap<>();

    private RedisListenerFactory(){

    }
    public static void put(String key,RedisListenerStrategy redisListenerStrategy){
        objMap.put(key,redisListenerStrategy);
    }


    public static RedisListenerStrategy get(String key){
        RedisListenerStrategy educationalBackground = objMap.get(key);
        return educationalBackground;
    }


}

 

第五部分:任务处理类

package com.htjx.common.redismonitor.redisTask;

import com.htjx.common.enums.RedisKeyPrefix;
import com.htjx.common.redismonitor.RedisListenerFactory;
import com.htjx.common.redismonitor.RedisListenerStrategy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * 功能描述: <br> 设备手动启停
 * @Author: zhang
 * @Date: 2021/9/7 16:45
 */
@Component
public class DeviceSecRuningSwitch implements InitializingBean , RedisListenerStrategy {

    /**
     * 功能描述: <br> bean初始化完成后的操作
     * @Author: zhang
     * @Date:  17:58
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        RedisListenerFactory.put(RedisKeyPrefix.设备自动开机.getKey(),this);
    }

    /**
     * 功能描述: <br> 执行的动作
     * @Author: zhang
     * @Date: 2021/9/7 17:58
     */
    @Override
    public void execute(String keyInfo) {
        System.err.println("key信息:"+keyInfo);
        System.err.println("检测到设备需要关机了");
    }


}

 

package com.htjx.common.redismonitor.redisTask;

import com.htjx.common.enums.RedisKeyPrefix;
import com.htjx.common.redismonitor.RedisListenerFactory;
import com.htjx.common.redismonitor.RedisListenerStrategy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * 功能描述: <br> 设备手动启停
 * @Author: zhang
 * @Date: 2021/9/7 16:45
 */
@Component
public class DeviceSecRuningSwitch2 implements InitializingBean , RedisListenerStrategy {

    /**
     * 功能描述: <br> bean初始化完成后的操作
     * @Author: zhang
     * @Date:  17:58
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        RedisListenerFactory.put(RedisKeyPrefix.设备自动关机.getKey(),this);
    }

    /**
     * 功能描述: <br> 执行的动作
     * @Author: zhang
     * @Date: 2021/9/7 17:58
     */
    @Override
    public void execute(String keyInfo) {
        System.err.println("key信息:"+keyInfo);
        System.err.println("检测到设备需要开机了");
    }


}