私のコンテナ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"
を指定しました。これはどういう意味ですか正確に?
私は見つけました いくつかのドキュメント 。それらは、次のように述べるのにそれほど役立ちません。
作成する同時コンシューマーの数を指定します。デフォルトは1です。
私が興味を持っているのは、MyListener
がスレッドセーフである必要があるかどうかです。
SomeDependency dependency
は1回インスタンス化されますか、それともスレッド/インスタンスごとにインスタンス化されますか?dependency
はスレッドセーフである必要がありますか?はい、並行性を使用するには、リスナーがスレッドセーフである必要があります。コンテナごとに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)
を追加します。次に、リスナーごとにコンテナーを取得し、リスナーの異なるインスタンスがそれぞれに注入されます。
また、リスナーに挿入されたスレッドセーフではない依存関係のプロトタイプスコープも必要になります。