First of all, I am a newbie in terms of Spring Integration and Spring JMS, so maybe the solution I try to adopt is not the correct one for my requirements.
I will try to explain what I am required to implement: basically, I need to place a message in a queue and asynchronously wait for an answer in another queue.
1. Place a message in a queue:
My solution:
<int-jms:outbound-gateway id="sendMessageOutboundGW"
connection-factory="jmsGatewayConnectionFactory"
request-channel="marshaledSendMessageJmsRequestChannel"
request-destination="sendMessageRequestQueue"
requires-reply="false"
reply-destination="sendMessageResponseQueue"
correlation-key="JMSCorrelationID">
</int-jms:outbound-gateway>
--> this works fine, I can see the messages being placed in the queue
2. Asynchronously listen for a reply message from another queue:
My solution 1:
<bean id="messageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsGatewayConnectionFactory" />
<property name="destination" ref="sendMessageResponseQueue" />
<property name="messageListener" ref="messageListener" />
<property name="errorHandler" ref="sendMessageResponseErrorHandler" />
</bean>
<int-jms:message-driven-channel-adapter id="sendMessageInboundGW"
container="messageListenerContainer"
channel="sendMessageJmsResponseChannel" />
The custom MessageListener implements javax.jms.MessageListener.
However, it looks that the message listener I set for the messageListenerContainer is being overridden and a org.springframework.integration.jms.ChannelPublishingJmsMessageListener is being used instead. I can see in the logs that the messages received are being picked up by the messageListenerContainer.
Also, with this solution I can see in the logs the following WARN message The provided listener container already has a MessageListener implementation, but it will be overridden by the provided ChannelPublishingJmsMessageListener.
My solution 2:
<bean id="messageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsGatewayConnectionFactory" />
<property name="destination" ref="sendMessageResponseQueue" />
<property name="messageListener" ref="messageListener" />
<property name="errorHandler" ref="sendMessageResponseErrorHandler" />
</bean>
<int-jms:inbound-gateway id="sendMessageInboundGW"
container="messageListenerContainer"
request-channel="sendMessageJmsResponseChannel"
request-destination="sendMessageResponseQueue"
correlation-key="JMSCorrelationID" />
I have the same issue with this solution -- the custom MessageListener is being overridden.
Not using the custom MessageListener, I get the following error:
org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
What am I doing wrong?
Any help would be much appreciated.
答案 0 :(得分:0)
When using Spring Integration, the message listener is the inbound gateway. That's why your listener bean is being overridden.
There are several solutions
instead of wiring your listener into the container, configure a <service-activator/>
to invoke your POJO. The reply will be routed to the gateway and sent as a reply to the inbound gateway.
eliminate the inbound gateway altogether and handle the message yourself - use a MessageListenerAdapter
, make your class a POJO and the adapter will route the reply.
if you don't want to use a MessageListenerAdapter
, your MessageListener
is responsible for routing the reply, but I recommend the first solution above.