文章目录
前言
上一篇博文中,我们探讨了消费者拉取到消息后,将数据传递给对应的listener。现在我们将继续探讨,List对象如何通过listener传递给KafkaListener等注解所标记的方法。
一、消息转换处理
1.BatchMessagingMessageListenerAdapter
将接收的消息,转换成Message对象(可在方法上直接使用,代表接收到的消息),然后传递给HandlerAdapter,进行后续消息的传递处理。
当方法存在返回值时,配合特定的配置,将响应结果转发到对应的topic上,实现数据的流转。
public void onMessage(List<ConsumerRecord<K, V>> records, Acknowledgment acknowledgment, Consumer<?, ?> consumer) {
Message<?> message;
if (!isConsumerRecordList()) {
if (isMessageList()) {
List<Message<?>> messages = new ArrayList<>(records.size());
// 接收到的消息,通过MessagingMessageConverter,转换成Message对象。
for (ConsumerRecord<K, V> record : records) {
messages.add(toMessagingMessage(record, acknowledgment, consumer));
}
// 将批量消息对应的List<Message>作为Message.payload进行构建。
message = MessageBuilder.withPayload(messages).build();
}
else {
message = toMessagingMessage(records, acknowledgment, consumer);
}
}
else {
message = NULL_MESSAGE; // optimization since we won't need any conversion to invoke
}
if (logger.isDebugEnabled()) {
logger.debug("Processing [" + message + "]");
}
// 消息处理
invoke(records, acknowledgment, consumer, message);
}
protected void invoke(Object records, Acknowledgment acknowledgment, Consumer<?, ?> consumer,
final Message<?> messageArg) {
Message<?> message = messageArg;
try {
// 消息传递给HandlerAdapter进行处理。
// invokeHandler内部,通过HandlerAdapter进行处理。
Object result = invokeHandler(records, acknowledgment, message, consumer);
if (result != null) {
// 当KafkaListener等注解标记的方法,存在返回值时,对返回值进行处理。
handleResult(result, records, message);
}
}
catch (ListenerExecutionFailedException e) {
// NOSONAR ex flow control
// 配置errorHandler时,使用errorHandler,进行异常信息处理。
if (this.errorHandler != null) {
try {
if (message.equals(NULL_MESSAGE)) {
message = new GenericMessage<>(records);
}
Object result = this.errorHandler.handleError(message, e, consumer);
if (result != null) {
handleResult(result, records, message);
}
}
catch (Exception ex) {
throw new ListenerExecutionFailedException(createMessagingErrorMessage(// NOSONAR stack trace loss
"Listener error handler threw an exception for the incoming message",
message.getPayload()), ex);
}
}
else {
throw e;
}
}
}
2.HandlerAdapter
为InvocableHandlerMethod和DelegatingInvocableHandler包装类,处理消息的invoke方法,最终将消息委托这两个Handler中的一个,进行处理。
public Object invoke(Message<