Rabbitmq Spring AMQP-MessageListenerAdapter-传递其他参数

Rabbitmq Spring AMQP-MessageListenerAdapter-传递其他参数,rabbitmq,spring-rabbit,Rabbitmq,Spring Rabbit,为了创建一个SimpleMessageListenerContainer,我做了如下操作 SimpleMessageConsumer simpleMessageConsumer = new SimpleMessageConsumer(); MessageListenerAdapter adapter = new CustomMessageListenerAdapater(simpleMessageConsumer); adapter.setDefaultListenerMethod("

为了创建一个SimpleMessageListenerContainer,我做了如下操作

SimpleMessageConsumer simpleMessageConsumer = new SimpleMessageConsumer();

MessageListenerAdapter adapter =
    new CustomMessageListenerAdapater(simpleMessageConsumer);
adapter.setDefaultListenerMethod("consume");
adapter.setMessageConverter(new SimpleMessageConverter());

SimpleMessageListenerContainer
    container =
    new SimpleMessageListenerContainer(connectionFactory);

container.setMessageListener(adapter);
我的SimpleMessageConsumer

  public void consume(String message){
      log.info(message);
}
我注意到在spring amqp引用中,“注释 listener endpoint infrastructure“允许您方便地将其他消息属性传递给消费者,如下所示:

@RabbitListener(queues = "myQueue")
public void processOrder(Order order, @Header("order_type") String orderType) {
...
}

这可以通过我上面提到的消费者创造方法来实现吗?我想访问Message对象的一些头。我知道我可以让我的消费者实现MessageListener或ChannelAwareMessageListener,并可以访问整个Message对象。但是,我不想要整个Message对象,因为我喜欢在触发消费者委托方法之前,将ContentTypeDelegatingMessageConverter与Jackson2JsonMessageConverter一起使用,方便地转换为我想要的类型(在我的真实应用程序中)

您需要将
MessagingMessageConverter
payloadConverter
一起使用,就像前面提到的
Jackson2JsonMessageConverter
一样,然后在
CustomMessageListenerAdapter
中覆盖:

/**
 * Build an array of arguments to be passed into the target listener method. Allows for multiple method arguments to
 * be built from a single message object.
 * <p>
 * The default implementation builds an array with the given message object as sole element. This means that the
 * extracted message will always be passed into a <i>single</i> method argument, even if it is an array, with the
 * target method having a corresponding single argument of the array's type declared.
 * <p>
 * This can be overridden to treat special message content such as arrays differently, for example passing in each
 * element of the message array as distinct method argument.
 * @param extractedMessage the content of the message
 * @return the array of arguments to be passed into the listener method (each element of the array corresponding to
 * a distinct method argument)
 */
protected Object[] buildListenerArguments(Object extractedMessage) {
/**
*构建要传递到目标侦听器方法的参数数组。允许使用多个方法参数
*可以从单个消息对象构建。
*
*默认实现以给定的消息对象作为唯一元素构建数组。这意味着
*提取的消息将始终传递到单个方法参数中,即使它是一个数组,但
*具有声明的数组类型的对应单个参数的目标方法。
*
*这可以被重写,以便以不同的方式处理特殊消息内容,例如数组,例如传入每个数组
*消息数组的元素作为不同的方法参数。
*@param extractedMessage消息的内容
*@返回要传递到侦听器方法的参数数组(数组中的每个元素对应于
*一个不同的方法(参数)
*/
受保护对象[]buildListenerArguments(对象提取消息){
extractedMessage
强制转换为
消息
,并提取所需的标题(如果有)

public class CustomMessageListenerAdapter extends MessageListenerAdapter {



 public CustomMessageListenerAdapter(Object delegate) {
    super(delegate);
  }

  @Override
  protected Object invokeListenerMethod(String methodName, Object[] arguments,
      Message originalMessage) throws Exception {


    Object[] modifiedArguments = new Object[arguments.length+1];
    System.arraycopy(arguments, 0, modifiedArguments,
                     0, arguments.length);

    //add the original message with headers
    modifiedArguments[arguments.length] = originalMessage;

    return super.invokeListenerMethod(methodName, modifiedArguments, originalMessage);
  }

}
我的消息消费者现在有一个额外的参数-原始消息

public class SimpleMessageConsumer {


  private static final Logger log = LoggerFactory.getLogger(SimpleMessageConsumer.class);


  public void consume(String messageConverted, Message originalMessage){
    log.info(originalMessage.toString());
  }

}
我的Bean配置如下所示:

SimpleMessageConsumer simpleMessageConsumer = new SimpleMessageConsumer();

    MessageListenerAdapter adapter =
        new CustomMessageListenerAdapter(simpleMessageConsumer);
    adapter.setDefaultListenerMethod("consume");
    adapter.setMessageConverter(messageConverter());

//container
    SimpleMessageListenerContainer
        container =
        new SimpleMessageListenerContainer(connectionFactory);

    container.setMessageListener(adapter);

感谢@Artem,因为您建议MessagingMessageConverter MessagingMessageConverter=new MessagingMessageConverter(new SimpleMessageConverter(),new SimpleMapQHeaderMapper());以及我的CustomMessageListenerAdapter受保护对象[]buildListenerArguments(Object extractedMessage)的内部{MessageProperties MessageProperties=((Message)extractedMessage).getMessageProperties();返回新对象[]{extractedMessage,MessageProperties};}好的。那也很好。不,那不是。
MessagingMessageConverter
返回一个
org.springframework.messaging.Message
实例。因此,您的
buildListenerArguments()
应该改为处理这种类型。感谢您为我指明了正确的方向。感谢您快速而周到的回复!我在下面发布了我的最终解决方案。请确保下一次timesetMessageListener(对象)从2020年起不再推荐