小编典典

Spring AMQP侦听器容器中的并发如何实现?

java

我的容器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;
    ....
}

我已经concurrency="10"在XML中指定了。这是什么意思 完全相同


我找到了一些文档。他们没有那么有帮助的陈述:

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


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

  • 是否创建了许多实例或许多线程使用了单个实例?
  • 如何访问不同步的实例字段?
  • SomeDependency dependency 实例化一次或为每个线程/实例?
  • 确实dependency需要是线程安全的?

阅读 217

收藏
2020-10-12

共1个答案

小编典典

是的,要使用并发,您的侦听器必须是线程安全的。每个容器有一个侦听器实例。但是,<rabbit:listener- container/>名称空间元素实际上只是添加“共享”属性的便利,每个侦听器元素都有自己的容器。

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

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

<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)。然后,您将为每个侦听器得到一个容器,并且侦听器的不同实例将被注入到每个侦听器中。

对于注入到侦听器中的任何非线程安全的依赖项,您还将需要原型作用域。

2020-10-12