可以使用逗号分隔属性来定义要侦听的队列吗?目的是能够在不更改代码的情况下更改队列名称和队列数。
我已在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动态定义队列?
答案 0 :(得分:1)
呀; SpEL会将一组队列名称放在queues
数组的第一个元素中。
如果您打开JIRA issue,我们就有可能在下周到期的1.5版本中修复。
我认为我们需要接受一个表达式,该表达式求值为逗号分隔的字符串,然后在处理注释时进行拆分。
修改强>
但是,我刚才意识到RabbitMQ允许你用逗号创建队列,所以也许我们应该把第一个数组元素本身作为一个数组来处理。
答案 1 :(得分:0)
以下是该问题的程序化解决方法:
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;
}
答案 2 :(得分:0)
如果在系统变量“cluster.name”中使用队列名称,并且需要使用条件自定义名称值,则可以使用Spel:
@RabbitListener(queues = "#{'${cluster.name}' != null?'batch.queue-${cluster.name}':'batch.queue'}", containerFactory = "listenerContainerFactory")