public class JmsInvokerClientInterceptor extends java.lang.Object implements MethodInterceptor, InitializingBean
MethodInterceptor
for accessing a
JMS-based remote service.
Serializes remote invocation objects and deserializes remote invocation result objects. Uses Java serialization just like RMI, but with the JMS provider as communication infrastructure.
To be configured with a QueueConnectionFactory
and a
target queue (either as Queue
reference or as queue name).
Thanks to James Strachan for the original prototype that this JMS invoker mechanism was inspired by!
setConnectionFactory(javax.jms.ConnectionFactory)
,
setQueue(javax.jms.Queue)
,
setQueueName(java.lang.String)
,
JmsInvokerServiceExporter
,
JmsInvokerProxyFactoryBean
Constructor and Description |
---|
JmsInvokerClientInterceptor() |
Modifier and Type | Method and Description |
---|---|
void |
afterPropertiesSet()
Invoked by a BeanFactory after it has set all bean properties supplied
(and satisfied BeanFactoryAware and ApplicationContextAware).
|
protected RemoteAccessException |
convertJmsInvokerAccessException(JMSException ex)
Convert the given JMS invoker access exception to an appropriate
Spring RemoteAccessException.
|
protected Connection |
createConnection()
Create a new JMS Connection for this JMS invoker.
|
protected RemoteInvocation |
createRemoteInvocation(MethodInvocation methodInvocation)
Create a new RemoteInvocation object for the given AOP method invocation.
|
protected Message |
createRequestMessage(Session session,
RemoteInvocation invocation)
Create the invoker request message.
|
protected Session |
createSession(Connection con)
Create a new JMS Session for this JMS invoker.
|
protected Message |
doExecuteRequest(Session session,
Queue queue,
Message requestMessage)
Actually execute the given request, sending the invoker request message
to the specified target queue and waiting for a corresponding response.
|
protected RemoteInvocationResult |
executeRequest(RemoteInvocation invocation)
Execute the given remote invocation, sending an invoker request message
to this accessor's target queue and waiting for a corresponding response.
|
protected RemoteInvocationResult |
extractInvocationResult(Message responseMessage)
Extract the invocation result from the response message.
|
protected ConnectionFactory |
getConnectionFactory()
Return the QueueConnectionFactory to use for obtaining JMS QueueConnections.
|
protected long |
getReceiveTimeout()
Return the timeout to use for receiving the response message for a request
(in milliseconds).
|
java.lang.Object |
invoke(MethodInvocation methodInvocation) |
protected RemoteInvocationResult |
onInvalidResponse(Message responseMessage)
Callback that is invoked by
extractInvocationResult
when it encounters an invalid response message. |
protected java.lang.Object |
recreateRemoteInvocationResult(RemoteInvocationResult result)
Recreate the invocation result contained in the given RemoteInvocationResult
object.
|
protected Queue |
resolveQueue(Session session)
Resolve this accessor's target queue.
|
protected Queue |
resolveQueueName(Session session,
java.lang.String queueName)
Resolve the given queue name into a JMS
Queue ,
via this accessor's DestinationResolver . |
void |
setConnectionFactory(ConnectionFactory connectionFactory)
Set the QueueConnectionFactory to use for obtaining JMS QueueConnections.
|
void |
setDestinationResolver(DestinationResolver destinationResolver)
Set the DestinationResolver that is to be used to resolve Queue
references for this accessor.
|
void |
setMessageConverter(MessageConverter messageConverter)
Specify the MessageConverter to use for turning
RemoteInvocation
objects into request messages, as well as response messages into
RemoteInvocationResult objects. |
void |
setQueue(Queue queue)
Set the target Queue to send invoker requests to.
|
void |
setQueueName(java.lang.String queueName)
Set the name of target queue to send invoker requests to.
|
void |
setReceiveTimeout(long receiveTimeout)
Set the timeout to use for receiving the response message for a request
(in milliseconds).
|
void |
setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory)
Set the RemoteInvocationFactory to use for this accessor.
|
public void setConnectionFactory(ConnectionFactory connectionFactory)
protected ConnectionFactory getConnectionFactory()
public void setQueue(Queue queue)
public void setQueueName(java.lang.String queueName)
DestinationResolver
.public void setDestinationResolver(DestinationResolver destinationResolver)
The default resolver is a DynamicDestinationResolver. Specify a JndiDestinationResolver for resolving destination names as JNDI locations.
public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory)
DefaultRemoteInvocationFactory
.
A custom invocation factory can add further context information to the invocation, for example user credentials.
public void setMessageConverter(MessageConverter messageConverter)
RemoteInvocation
objects into request messages, as well as response messages into
RemoteInvocationResult
objects.
Default is a SimpleMessageConverter
,
using a standard JMS ObjectMessage
for each invocation /
invocation result object.
Custom implementations may generally adapt Serializables into special kinds of messages, or might be specifically tailored for translating RemoteInvocation(Result)s into specific kinds of messages.
public void setReceiveTimeout(long receiveTimeout)
The default is 0, which indicates a blocking receive without timeout.
protected long getReceiveTimeout()
public void afterPropertiesSet()
InitializingBean
This method allows the bean instance to perform initialization only possible when all bean properties have been set and to throw an exception in the event of misconfiguration.
afterPropertiesSet
in interface InitializingBean
public java.lang.Object invoke(MethodInvocation methodInvocation) throws java.lang.Throwable
invoke
in interface MethodInterceptor
java.lang.Throwable
protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation)
Can be overridden in subclasses to provide custom RemoteInvocation subclasses, containing additional invocation parameters like user credentials. Note that it is preferable to use a custom RemoteInvocationFactory which is a reusable strategy.
methodInvocation
- the current AOP method invocationRemoteInvocationFactory.createRemoteInvocation(org.aopalliance.intercept.MethodInvocation)
protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException
invocation
- the RemoteInvocation to executeJMSException
- in case of JMS failuredoExecuteRequest(javax.jms.Session, javax.jms.Queue, javax.jms.Message)
protected Connection createConnection() throws JMSException
JMSException
protected Session createSession(Connection con) throws JMSException
JMSException
protected Queue resolveQueue(Session session) throws JMSException
session
- the current JMS SessionJMSException
- if resolution failedprotected Queue resolveQueueName(Session session, java.lang.String queueName) throws JMSException
Queue
,
via this accessor's DestinationResolver
.session
- the current JMS SessionqueueName
- the name of the queueJMSException
- if resolution failedsetDestinationResolver(org.springframework.jms.support.destination.DestinationResolver)
protected Message createRequestMessage(Session session, RemoteInvocation invocation) throws JMSException
The default implementation creates a JMS ObjectMessage for the given RemoteInvocation object.
session
- the current JMS Sessioninvocation
- the remote invocation to sendJMSException
- if the message could not be createdprotected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException
The default implementation is based on standard JMS send/receive,
using a TemporaryQueue
for receiving the response.
session
- the JMS Session to usequeue
- the resolved target Queue to send torequestMessage
- the JMS Message to sendJMSException
- in case of JMS failureprotected RemoteInvocationResult extractInvocationResult(Message responseMessage) throws JMSException
The default implementation expects a JMS ObjectMessage carrying
a RemoteInvocationResult object. If an invalid response message is
encountered, the onInvalidResponse
callback gets invoked.
responseMessage
- the response messageJMSException
- is thrown if a JMS exception occursonInvalidResponse(javax.jms.Message)
protected RemoteInvocationResult onInvalidResponse(Message responseMessage) throws JMSException
extractInvocationResult
when it encounters an invalid response message.
The default implementation throws a MessageFormatException.
responseMessage
- the invalid response messageJMSException
- if the invalid response should lead
to an infrastructure exception propagated to the callerextractInvocationResult(javax.jms.Message)
protected java.lang.Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws java.lang.Throwable
Can be overridden in subclass to provide custom recreation, potentially processing the returned result object.
result
- the RemoteInvocationResult to recreatejava.lang.Throwable
- if the invocation result is an exceptionRemoteInvocationResult.recreate()
protected RemoteAccessException convertJmsInvokerAccessException(JMSException ex)
ex
- the exception to convert