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