在spring-amqp中读取兔子信息的最早进入点是什么?

时间:2018-01-18 09:53:24

标签: java spring rabbitmq spring-amqp spring-rabbit

我将线程本地兔子消息数据存储在MDC中。我想清除旧的并为传入的兔子消息添加新的上下文数据,例如从头部读取某些值或将兔子消息有效负载读取为byte[]。不幸的是,我经常看到在消息发出@RabbitHandler注释方法之前发生异常。是否有一个更早的入口点可以用来建立这个上下文?我不知道在反序列化发生之前会发生什么,但理想情况下我想在尝试反序列化之前访问该消息。也许在某个地方有一个onMessageReceived(byte[] message, Map headers)方法钩子。调用堆栈中的越早越好。

2 个答案:

答案 0 :(得分:2)

@RabbitHandler填充了AbstractRabbitListenerContainerFactoryMessageConverter可以提供自定义fromMessage()https://docs.spring.io/spring-amqp/docs/2.0.1.RELEASE/reference/html/_reference.html#message-converters。它的MessagingMessageListenerAdapter.toMessagingMessage()来自MessagingMessageListenerAdapter.onMessage()。这是在org.springframework.amqp.core.Message中完成的。这确实是你可以挂钩的最早的地方。而且你真的还有一个没有任何转换的原始/** * @param afterReceivePostProcessors the post processors. * @see AbstractMessageListenerContainer#setAfterReceivePostProcessors(MessagePostProcessor...) */ public void setAfterReceivePostProcessors(MessagePostProcessor... afterReceivePostProcessors) { 对象以及所有可用的标题和属性。

嗯,你也可以注射:

function get_messages($path, $array)
{
    $index = array_shift($path);

    if ($index !== NULL)
    {
        return get_message($path, $array[$index]->messages);
    }
    else
    {
        return $array;
    }
}

出于类似的原因,你要求。

答案 1 :(得分:0)

解决方案是使用SimpleMessageListenerContainer而不是@RabbitHandler注释,并使用自定义消息侦听器适配器。

示例:

@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
                                         MessageListenerAdapter listenerAdapter) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueueNames(queueName);
    container.setMessageListener(listenerAdapter); // custom listener
    container.setMessageConverter(null); // disable default conversion
    return container;
}

@Bean
MessageListenerAdapter listenerAdapter() {
    RawMessageDelegate delegate = new RawMessageDelegate();
    return new MessageListenerAdapter(delegate);
}

public class RawMessageDelegate {

    void handleMessage(Message message) {
        byte[] body = message.getBody();
        MessageProperties properties = message.getMessageProperties();
        Map<String, Object> headers = properties.getHeaders();
        // handle raw data
    }

}