Spring AMQP-MessageListenerAdapter-传递其他参数

时间:2018-10-16 18:33:16

标签: rabbitmq spring-rabbit spring-rabbitmq

要创建一个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-refrence中注意到“ 侦听器端点基础结构 ”,您可以像这样轻松地将其他Message属性传递给您的使用者:

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

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

2 个答案:

答案 0 :(得分:0)

您需要使用MessagingMessageConverterpayloadConverter并使用Jackson2JsonMessageConverter,然后在CustomMessageListenerAdapater中覆盖:

/**
 * 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) {

extractedMessage投射到Message<?>并提取所需的标头。

答案 1 :(得分:0)

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);
  }

}

我的Message使用者现在有了一个附加参数-原始消息

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);