@RabbitListener — определение очередей из свойств

Можно ли использовать свойство, разделенное запятыми, для определения очередей для прослушивания? Цель состоит в том, чтобы иметь возможность изменять имена очередей и количество очередей без изменения кода.

Я определил очереди в моем application.properties следующим образом:

my.aggregate.queues=/some/queue,/some/other/queue

Я могу включить имена очередей в виде списков, используя SpEL так:

@Value("#{'${my.aggregate.queues}'.split(',')}")

Однако, когда я пытаюсь прослушивать очереди с помощью аннотации @RabbitListener, я обнаруживаю, что должен определять очереди по отдельности. С использованием

@RabbitListener(queues = { "#{'${my.aggregate.queues}'.split(',')}" })

приводит к тому, что имена очередей разрешаются в массив строк, но не в тот, который можно использовать:

@RabbitListener can't resolve '[Ljava.lang.String;@5396eeb1' as either a String or a Queue

Я безуспешно пробовал разные комбинации SpEL. Есть ли способ использовать SpEL для динамического определения очередей?


person Burt Alexander    schedule 03.09.2015    source источник


Ответы (3)


Ага; что SpEL поместит массив имен очередей в первый элемент массива queues.

Если вы откроете проблему JIRA, есть шанс, что мы сможем получить исправление в выпуске 1.5, который должен появиться в следующем неделю.

Я думаю, нам нужно принять выражение, которое оценивается как строка с разделителями-запятыми, а затем выполнить разделение при обработке аннотации.

ИЗМЕНИТЬ:

Однако я только что понял, что RabbitMQ позволяет создавать очереди с запятыми в них, поэтому, возможно, нам следует просто обработать первый элемент массива, который сам является массивом.

person Gary Russell    schedule 04.09.2015
comment
Спасибо Гэри, я открою вопрос. Я работал вокруг этого на данный момент программно. Способ указания массива в аннотации @RabbitListener, безусловно, был бы предпочтительнее, и я согласен с вашим выводом в вашем редактировании. - person Burt Alexander; 07.09.2015

Вот программный обходной путь для этой проблемы:

private MethodRabbitListenerEndpoint createEndpoint() {
  MethodRabbitListenerEndpoint endpoint = new MethodRabbitListenerEndpoint();

  endpoint.setQueueNames(queues.toArray(new String[] {})); // auto wired in
  endpoint.setAdmin(admin);
  endpoint.setBean(interceptor);
  endpoint.setId(ENDPOINT_ID);

  endpoint.setMessageHandlerMethodFactory(createMethodFactory());

  endpoint.setMethod(ReflectionUtils.findMethod(MyInterceptor.class, “myMethod”,
      MyAbstractJsonSuperclass.class, Channel.class));

  SimpleMessageListenerContainer container = listenerFactory.createListenerContainer(endpoint);
  container.setupMessageListener(admin.getRabbitTemplate());

  return endpoint;
}

private MessageHandlerMethodFactory createMethodFactory() {
  DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();

  messageHandlerMethodFactory.setMessageConverter(converter); // custom json converter
  messageHandlerMethodFactory.afterPropertiesSet();

  return messageHandlerMethodFactory;
}
person Burt Alexander    schedule 06.09.2015

Если вы используете имя очереди в системной переменной «cluster.name» и вам нужно настроить значение имени с помощью условий, вы можете использовать Spel:

@RabbitListener(queues = "#{'${cluster.name}' != null?'batch.queue-${cluster.name}':'batch.queue'}", containerFactory = "listenerContainerFactory")
person dmotta    schedule 09.06.2017