如何实现Spring AMQP Listener Container中的并发性?

时间:2014-04-28 12:58:46

标签: java spring rabbitmq amqp spring-amqp

我的容器XML配置:

<rabbit:listener-container
        connection-factory="myConnectionFactory"
        acknowledge="none"
        concurrency="10"
        requeue-rejected="false">
    <rabbit:listener ref="myListener" queues="myQueue"/>
</rabbit:listener-container>

myListener只是一个类

@Component("myListener")
public class MyListener implements MessageListener {
    @Autowired
    SomeDependency dependency;
    ....
}

我在XML中指定了concurrency="10"。这意味着什么完全


我找到了some docs。他们没有那么有用的陈述:

  

指定要创建的并发使用者数。默认值为1。


我感兴趣的是MyListener是否必须是线程安全的,即

  • 是否创建了许多实例或许多线程使用了单个实例?
  • 我可以访问没有同步的实例字段吗?
  • SomeDependency dependency实例化一次还是每个线程/实例?
  • dependency需要线程安全吗?

1 个答案:

答案 0 :(得分:15)

是的,要使用并发性,您的侦听器必须是线程安全的。每个容器有一个侦听器实例。但是,<rabbit:listener-container/>命名空间元素实际上只是添加&#34; shared&#34;属性,每个侦听器元素都有自己的容器。

通常最好使用无状态对象(没有写入的字段),但这并不总是可行。

如果您的侦听器不是线程安全的,则可以使用...

<rabbit:listener-container
    connection-factory="myConnectionFactory"
    acknowledge="none"
    requeue-rejected="false">
    <rabbit:listener ref="myListener" queues="myQueue"/>
    <rabbit:listener ref="myListener" queues="myQueue"/>
    <rabbit:listener ref="myListener" queues="myQueue"/>
    <rabbit:listener ref="myListener" queues="myQueue"/>
    ...
</rabbit:listener-container>

...并添加@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)。然后,您将为每个侦听器获取一个容器,并且将为每个侦听器注入不同的侦听器实例。

对于注入侦听器的任何非线程安全依赖项,您还需要原型范围。