同じ「メイン」スレッドで DefaultMessageListenerContainer を実行したい場合があります。現在、メッセージを受信するたびに新しいスレッドを生成する SimpleAsyncTaskExecutor を使用しています。
異なる分散システムに接続して処理を行うテスト ケースがあり、最終的にいくつかのことをアサートします。DefaultMessageListenerContainer は別のスレッドで実行されるため、メイン スレッドは返され、DefaultMessageListenerContainer が完了する前にアサーションの実行を開始します。これは、テスト ケースの失敗につながります。回避策として、メイン スレッドを数秒間スリープさせました。
サンプル構成
<int-jms:message-driven-channel-adapter
id="mq.txbus.publisher.channel.adapter"
container="defaultMessageListenerContainer"
channel="inbound.endpoint.publisher"
acknowledge="transacted"
extract-payload="true" />
<beans:bean id="defaultMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<beans:property name="connectionFactory" ref="mockConnectionFactory"/>
<beans:property name="destination" ref="publisherToTxmQueue"/>
<beans:property name="taskExecutor" ref="taskExecutor"/>
<beans:property name="maxMessagesPerTask" value="10"/>
<beans:property name="sessionTransacted" value="true"/>
</beans:bean>
<beans:bean id="taskExecutor" class="org.springframework.scheduling.timer.TimerTaskExecutor" />
シングルスレッドを作成するため、ここで TimerTaskExecutor を使用しようとしていますが、そのスレッドはメインスレッドとは別であるため、問題は解決されていません。SyncTaskExecutor を使用してみましたが、どちらも機能しません (または、正しいプロパティ値を提供していない可能性があります)。
回答:
SimpleMessageListenerContainer を使用してこの問題を解決しました。これが新しい構成です
<int-jms:message-driven-channel-adapter
id="mq.txbus.publisher.channel.adapter"
container="messageListenerContainer"
channel="inbound.endpoint.publisher"
acknowledge="transacted"
extract-payload="true" />
<beans:bean id="messageListenerContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<beans:property name="connectionFactory" ref="mockConnectionFactory"/>
<beans:property name="destination" ref="publisherToTxmQueue"/>
<beans:property name="sessionTransacted" value="true"/>
<beans:property name="exposeListenerSession" value="false"/>
</beans:bean>