前提
- spring-data-redis-2.3.4.RELEASE.jar
简单示例
自定义消息监听接口类
public interface AppSubscriber {
/**
* 处理消息过程
* 该方法名称与{@link org.springframework.data.redis.listener.adapter.MessageListenerAdapter.MethodInvoker#defaultListenerMethod}保持一致
*
* @param message 已经反序列化后的消息
*
*/
void onMessage(Object message);
}
实例化一个监听器,完成注册
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Bean
public AppSubscriber printSubscriber(){
new AppSubscriber(){
void onMessage(Object message){
System.out.println("接收到消息 {}", message);
}
}
}
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(){
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisTemplate.getConnectionFactory());
// 异常日志
redisMessageListenerContainer.setErrorHandler(throwable -> containerlog.error("Redis监听器接收到订阅消息处理失败, {}", throwable.getMessage(), throwable));
// 和自定义监听器方法名保持一致 onMessage
MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(printSubscriber(), "onMessage");
// 手动调用初始化(如果MessageListenerAdapter是使用@Bean/@Service等方式注册,不需要手动调用)
messageListenerAdapter.afterPropertiesSet();
// 订阅反序列化和发布时序列化保持一致
messageListenerAdapter.setSerializer(redisTemplate.getValueSerializer());
String channel = "{订阅的渠道名称}";
redisMessageListenerContainer.addMessageListener(messageListenerAdapter, () -> channel);
}
监听器方法有何规则呢?
可行1:
public interface AppSubscriber {
void onMessage(Object message);
}
可行2:
public interface AppSubscriber {
void onMessage(Object convertedMessage, String convertedChannel);
}
原因看源码:
/** 片段1 构建参数时有两个 **/
// Regular case: find a handler method reflectively.
Object convertedMessage = extractMessage(message);
String convertedChannel = stringSerializer.deserialize(pattern);
// Invoke the handler method with appropriate arguments.
Object[] listenerArguments = new Object[] { convertedMessage, convertedChannel };
invokeListenerMethod(invoker.getMethodName(), listenerArguments);
/** 片段2 如果类型匹配一致,就是两个参数都用上。匹配失败,参数只有message **/
Object[] args = //
types.length == 2 //
&& types[0].isInstance(arguments[0]) //
&& types[1].isInstance(arguments[1]) ? arguments : message;