jmsinvokerclientinterceptor.java
来自「spring framework 2.5.4源代码」· Java 代码 · 共 443 行 · 第 1/2 页
JAVA
443 行
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.jms.remoting;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageFormatException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jms.connection.ConnectionFactoryUtils;
import org.springframework.jms.support.JmsUtils;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.SimpleMessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.jms.support.destination.DynamicDestinationResolver;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.remoting.RemoteInvocationFailureException;
import org.springframework.remoting.support.DefaultRemoteInvocationFactory;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationFactory;
import org.springframework.remoting.support.RemoteInvocationResult;
/**
* {@link org.aopalliance.intercept.MethodInterceptor} for accessing a
* JMS-based remote service.
*
* <p>Serializes remote invocation objects and deserializes remote invocation
* result objects. Uses Java serialization just like RMI, but with the JMS
* provider as communication infrastructure.
*
* <p>To be configured with a {@link javax.jms.QueueConnectionFactory} and a
* target queue (either as {@link javax.jms.Queue} reference or as queue name).
*
* <p>Thanks to James Strachan for the original prototype that this
* JMS invoker mechanism was inspired by!
*
* @author Juergen Hoeller
* @author James Strachan
* @since 2.0
* @see #setConnectionFactory
* @see #setQueue
* @see #setQueueName
* @see org.springframework.jms.remoting.JmsInvokerServiceExporter
* @see org.springframework.jms.remoting.JmsInvokerProxyFactoryBean
*/
public class JmsInvokerClientInterceptor implements MethodInterceptor, InitializingBean {
private ConnectionFactory connectionFactory;
private Object queue;
private DestinationResolver destinationResolver = new DynamicDestinationResolver();
private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory();
private MessageConverter messageConverter = new SimpleMessageConverter();
private long receiveTimeout = 0;
/**
* Set the QueueConnectionFactory to use for obtaining JMS QueueConnections.
*/
public void setConnectionFactory(ConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
/**
* Return the QueueConnectionFactory to use for obtaining JMS QueueConnections.
*/
protected ConnectionFactory getConnectionFactory() {
return this.connectionFactory;
}
/**
* Set the target Queue to send invoker requests to.
*/
public void setQueue(Queue queue) {
this.queue = queue;
}
/**
* Set the name of target queue to send invoker requests to.
* The specified name will be dynamically resolved via the
* {@link #setDestinationResolver DestinationResolver}.
*/
public void setQueueName(String queueName) {
this.queue = queueName;
}
/**
* Set the DestinationResolver that is to be used to resolve Queue
* references for this accessor.
* <p>The default resolver is a DynamicDestinationResolver. Specify a
* JndiDestinationResolver for resolving destination names as JNDI locations.
* @see org.springframework.jms.support.destination.DynamicDestinationResolver
* @see org.springframework.jms.support.destination.JndiDestinationResolver
*/
public void setDestinationResolver(DestinationResolver destinationResolver) {
this.destinationResolver =
(destinationResolver != null ? destinationResolver : new DynamicDestinationResolver());
}
/**
* Set the RemoteInvocationFactory to use for this accessor.
* Default is a {@link org.springframework.remoting.support.DefaultRemoteInvocationFactory}.
* <p>A custom invocation factory can add further context information
* to the invocation, for example user credentials.
*/
public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) {
this.remoteInvocationFactory =
(remoteInvocationFactory != null ? remoteInvocationFactory : new DefaultRemoteInvocationFactory());
}
/**
* Specify the MessageConverter to use for turning
* {@link org.springframework.remoting.support.RemoteInvocation}
* objects into request messages, as well as response messages into
* {@link org.springframework.remoting.support.RemoteInvocationResult} objects.
* <p>Default is a {@link org.springframework.jms.support.converter.SimpleMessageConverter},
* using a standard JMS {@link javax.jms.ObjectMessage} for each invocation /
* invocation result object.
* <p>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 setMessageConverter(MessageConverter messageConverter) {
this.messageConverter = (messageConverter != null ? messageConverter : new SimpleMessageConverter());
}
/**
* Set the timeout to use for receiving the response message for a request
* (in milliseconds).
* <p>The default is 0, which indicates a blocking receive without timeout.
* @see javax.jms.MessageConsumer#receive(long)
* @see javax.jms.MessageConsumer#receive()
*/
public void setReceiveTimeout(long receiveTimeout) {
this.receiveTimeout = receiveTimeout;
}
/**
* Return the timeout to use for receiving the response message for a request
* (in milliseconds).
*/
protected long getReceiveTimeout() {
return this.receiveTimeout;
}
public void afterPropertiesSet() {
if (getConnectionFactory() == null) {
throw new IllegalArgumentException("Property 'connectionFactory' is required");
}
if (this.queue == null) {
throw new IllegalArgumentException("'queue' or 'queueName' is required");
}
}
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
return "JMS invoker proxy for queue [" + this.queue + "]";
}
RemoteInvocation invocation = createRemoteInvocation(methodInvocation);
RemoteInvocationResult result = null;
try {
result = executeRequest(invocation);
}
catch (JMSException ex) {
throw convertJmsInvokerAccessException(ex);
}
try {
return recreateRemoteInvocationResult(result);
}
catch (Throwable ex) {
if (result.hasInvocationTargetException()) {
throw ex;
}
else {
throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() +
"] failed in JMS invoker remote service at queue [" + this.queue + "]", ex);
}
}
}
/**
* Create a new RemoteInvocation object for the given AOP method invocation.
* The default implementation delegates to the RemoteInvocationFactory.
* <p>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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?