RedisKey的失效監(jiān)聽器KeyExpirationEventMessageListener問題
RedisKey的失效監(jiān)聽器KeyExpirationEventMessageListener
利用KeyExpirationEventMessageListener實現(xiàn)redis的key失效監(jiān)聽。
在使用redis時,所有的key都要設(shè)置過期時間,過期之后,redis就會把對應(yīng)的key清除掉。
此方法可以監(jiān)聽redis的key失效,在失效時做一些邏輯處理。話不多說,上代碼。
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>實現(xiàn)
import com.upbim.twin.park.common.constans.Constants;
import com.upbim.twin.park.server.strategy.PushMessageStrategyContext;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;
import org.springframework.stereotype.Service;
import java.util.UUID;
import static com.upbim.twin.park.common.constans.Constants.TRACE_ID;
@Slf4j
@Service
public class AgentOrderRedisKeyExpiredListener extends KeyExpirationEventMessageListener {
@Autowired
private PushMessageStrategyContext pushMessageStrategyContext;
@Autowired
private RedisProperties redisProperties;
/**
* Creates new MessageListener for {@code __keyevent@*__:expired} messages.
*
* @param listenerContainer must not be {@literal null}.
*/
public AgentOrderRedisKeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
protected void doRegister(RedisMessageListenerContainer listenerContainer) {
// 只監(jiān)聽指定redis數(shù)據(jù)庫的key過期事件
Topic topic = new PatternTopic(String.format("__keyevent@%s__:expired", redisProperties.getDatabase()));
listenerContainer.addMessageListener(this, topic);
}
@Override
protected void doHandleMessage(Message message) {
// 訂閱的topic: new String(message.getChannel(), UTF_8) ---> "__keyevent@0__:expired"
// 觸發(fā)key失效發(fā)布的key:new String(message.getBody(), UTF_8) ---> "demoKey"
MDC.put(TRACE_ID, UUID.randomUUID().toString());
try {
log.info(String.format("Redis key expired event:%s", message.toString()));
String beanName = message.toString().split(Constants.COLON)[Constants.ONE];
pushMessageStrategyContext.handleRedisExpireKey(beanName, message.toString());
super.doHandleMessage(message);
} finally {
MDC.clear();
}
}
}監(jiān)聽處理類
package com.upbim.twin.park.server.strategy;
import com.google.common.collect.Maps;
import com.upbim.twin.park.server.strategy.nozzle.PushMessageStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class PushMessageStrategyContext {
/**
* 使用線程安全的ConcurrentHashMap存儲所有實現(xiàn)Strategy接口的Bean
* key:beanName
* value:實現(xiàn)Strategy接口Bean
*/
private final Map<String, PushMessageStrategy> strategyMap = Maps.newConcurrentMap();
/**
* 注入所有實現(xiàn)了Strategy接口的Bean
*
* @param strategyMap the strategy map
*/
@Autowired
public PushMessageStrategyContext(Map<String, PushMessageStrategy> strategyMap) {
strategyMap.forEach(this.strategyMap::put);
}
/**
* 策略監(jiān)聽redis所有過期key
*
* @param beanName the bean name
* @param redisInvalidKey the redis invalid key
* @return
*/
public void handleRedisExpireKey(String beanName, String redisInvalidKey) {
if (Objects.nonNull(strategyMap.get(beanName))) {
strategyMap.get(beanName).handleRedisExpireKey(redisInvalidKey);
} else {
log.warn("找不到對應(yīng)的策略:{}", strategyMap.get(beanName));
}
}
}public interface PushMessageStrategy {
void handleRedisExpireKey(String redisInvalidKey);
}大家在使用的時候,可以針對自己不同的場景,實現(xiàn)PushMessageStrategy 接口,重寫handleRedisExpireKey方法。
在方法中處理不同的邏輯。
首先,在redis’中有key失效過期時,AgentOrderRedisKeyExpiredListener 監(jiān)聽到redis實現(xiàn),會執(zhí)行doHandleMessage方法,方法中會調(diào)用PushMessageStrategyContext 的獲取不同策略的Bean,進(jìn)行業(yè)務(wù)操作。
至此,監(jiān)聽redis中key失效完成。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot整合RabbitMQ發(fā)送短信的實現(xiàn)
本文會和SpringBoot做整合,實現(xiàn)RabbitMQ發(fā)送短信,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
java輕量級規(guī)則引擎easy-rules使用介紹
這篇文章主要介紹了java輕量級規(guī)則引擎easy-rules使用介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
springboot vue組件開發(fā)實現(xiàn)接口斷言功能
這篇文章主要為大家介紹了springboot+vue組件開發(fā)實現(xiàn)接口斷言功能,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Java中讀寫鎖ReadWriteLock的原理與應(yīng)用詳解
Java并發(fā)編程提供了讀寫鎖,主要用于讀多寫少的場景,今天我們就重點來講解讀寫鎖ReadWriteLock的原理與應(yīng)用場景,感興趣的可以了解一下2022-09-09

