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 the containing
BeanFactory after it has set all bean properties
and satisfied BeanFactoryAware , ApplicationContextAware etc. |
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)
Implement this method to perform extra treatments before and
after the invocation.
|
protected RemoteInvocationResult |
onInvalidResponse(Message responseMessage)
Callback that is invoked by
extractInvocationResult(javax.jms.Message) when
it encounters an invalid response message. |
protected RemoteInvocationResult |
onReceiveTimeout(RemoteInvocation invocation)
Callback that is invoked by
executeRequest(org.springframework.remoting.support.RemoteInvocation) when the receive
timeout has expired for the specified RemoteInvocation . |
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(@Nullable ConnectionFactory connectionFactory)
@Nullable protected ConnectionFactory getConnectionFactory()
public void setQueue(Queue queue)
public void setQueueName(java.lang.String queueName)
The specified name will be dynamically resolved via the
DestinationResolver
.
public void setDestinationResolver(@Nullable DestinationResolver destinationResolver)
The default resolver is a DynamicDestinationResolver
. Specify a
JndiDestinationResolver
for resolving destination names as JNDI locations.
public void setRemoteInvocationFactory(@Nullable RemoteInvocationFactory remoteInvocationFactory)
RemoteInvocationFactory
to use for this accessor.
Default is a DefaultRemoteInvocationFactory
.
A custom invocation factory can add further context information to the invocation, for example user credentials.
public void setMessageConverter(@Nullable MessageConverter messageConverter)
MessageConverter
to use for turning
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 Serializable
objects 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
BeanFactory
after it has set all bean properties
and satisfied BeanFactoryAware
, ApplicationContextAware
etc.
This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.
afterPropertiesSet
in interface InitializingBean
@Nullable public java.lang.Object invoke(MethodInvocation methodInvocation) throws java.lang.Throwable
MethodInterceptor
Joinpoint.proceed()
.invoke
in interface MethodInterceptor
methodInvocation
- the method invocation joinpointJoinpoint.proceed()
;
might be intercepted by the interceptorjava.lang.Throwable
- if the interceptors or the target object
throws an exceptionprotected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation)
RemoteInvocation
object for the given AOP method invocation.
The default implementation delegates to the RemoteInvocationFactory
.
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 created@Nullable protected 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 onReceiveTimeout(RemoteInvocation invocation)
executeRequest(org.springframework.remoting.support.RemoteInvocation)
when the receive
timeout has expired for the specified RemoteInvocation
.
By default, an RemoteTimeoutException
is thrown. Sub-classes
can choose to either throw a more dedicated exception or even return
a default RemoteInvocationResult
as a fallback.
invocation
- the invocationprotected RemoteInvocationResult onInvalidResponse(Message responseMessage) throws JMSException
extractInvocationResult(javax.jms.Message)
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)
@Nullable protected java.lang.Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws java.lang.Throwable
RemoteInvocationResult
object.
The default implementation calls the default recreate()
method.
Can be overridden in subclasses 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)
RemoteAccessException
.ex
- the exception to convert