refactoring request/reply gateway code

This commit is contained in:
Mark Fisher
2010-04-30 01:38:04 +00:00
parent 2feb6bf81c
commit 486742f64f
6 changed files with 33 additions and 74 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -27,7 +27,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.gateway.GatewayInvokingMessageHandler;
/**
* Parser for the <chain> element.
@@ -49,12 +48,13 @@ public class ChainParser extends AbstractConsumerEndpointParser {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE && !"poller".equals(child.getLocalName())) {
String childBeanName = this.parseChild((Element) child, parserContext, builder.getBeanDefinition());
// INT-911 will create Gateway invoking MessageHandler, allowing 'gateway' to be included in the chain
if ("gateway".equals(child.getLocalName())){
BeanDefinitionBuilder gwBuilder = BeanDefinitionBuilder.genericBeanDefinition(GatewayInvokingMessageHandler.class);
BeanDefinitionBuilder gwBuilder = BeanDefinitionBuilder.genericBeanDefinition(
IntegrationNamespaceUtils.BASE_PACKAGE + ".gateway.RequestReplyMessageHandlerAdapter");
gwBuilder.addConstructorArgValue(new RuntimeBeanReference(childBeanName));
handlerList.add(gwBuilder.getBeanDefinition());
} else {
}
else {
handlerList.add(new RuntimeBeanReference(childBeanName));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2010 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.
@@ -40,7 +40,7 @@ import org.springframework.util.Assert;
*
* @author Mark Fisher
*/
public abstract class AbstractMessagingGateway extends AbstractEndpoint implements MessagingGateway {
public abstract class AbstractMessagingGateway extends AbstractEndpoint {
private volatile MessageChannel requestChannel;

View File

@@ -65,7 +65,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
private volatile Object serviceProxy;
private final Map<Method, MessagingGateway> gatewayMap = new HashMap<Method, MessagingGateway>();
private final Map<Method, SimpleMessagingGateway> gatewayMap = new HashMap<Method, SimpleMessagingGateway>();
private volatile boolean initialized;
@@ -77,7 +77,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
/**
* Create a Factory whose service interface type can be configured by setter injection.
* If none is set, it will fall back to the default service interface type,
* {@link GenericSendAndRecieveGateway}, upon initialization.
* {@link RequestReplyExchanger}, upon initialization.
*/
public GatewayProxyFactoryBean() {
// serviceInterface will be determined on demand later
@@ -159,7 +159,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
Class<?> proxyInterface = this.determineServiceInterface();
Method[] methods = proxyInterface.getDeclaredMethods();
for (Method method : methods) {
MessagingGateway gateway = this.createGatewayForMethod(method);
SimpleMessagingGateway gateway = this.createGatewayForMethod(method);
this.gatewayMap.put(method, gateway);
}
this.serviceProxy = new ProxyFactory(proxyInterface, this).getProxy(this.beanClassLoader);
@@ -170,7 +170,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
private Class<?> determineServiceInterface() {
if (this.serviceInterface == null) {
this.serviceInterface = GenericSendAndReceiveGateway.class;
this.serviceInterface = RequestReplyExchanger.class;
}
return this.serviceInterface;
}
@@ -212,7 +212,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
this.afterPropertiesSet();
}
Method method = invocation.getMethod();
MessagingGateway gateway = this.gatewayMap.get(method);
SimpleMessagingGateway gateway = this.gatewayMap.get(method);
Class<?> returnType = method.getReturnType();
boolean isReturnTypeMessage = Message.class.isAssignableFrom(returnType);
boolean shouldReply = returnType != void.class;
@@ -251,7 +251,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
throw originalException;
}
private MessagingGateway createGatewayForMethod(Method method) {
private SimpleMessagingGateway createGatewayForMethod(Method method) {
SimpleMessagingGateway gateway = new SimpleMessagingGateway(
new ArgumentArrayMessageMapper(method, this.getBeanName()), new SimpleMessageMapper());
if (this.getTaskScheduler() != null) {
@@ -270,10 +270,11 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
replyChannel = this.resolveChannel(replyChannel, replyChannelName);
requestTimeout = gatewayAnnotation.requestTimeout();
replyTimeout = gatewayAnnotation.replyTimeout();
} else if (methodToChannelMap != null && methodToChannelMap.size() > 0) {
}
else if (methodToChannelMap != null && methodToChannelMap.size() > 0) {
Assert.state(this.getChannelResolver() != null, "ChannelResolver is required");
GatewayMethodDefinition gatewayDefinition = methodToChannelMap.get(method.getName());
if (gatewayDefinition != null){
if (gatewayDefinition != null) {
String requestChannelName = gatewayDefinition.getRequestChannelName();
requestChannel = this.resolveChannel(requestChannel, requestChannelName);
String replyChannelName = gatewayDefinition.getReplyChannelName();
@@ -310,7 +311,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
@Override // guarded by super#lifecycleLock
protected void doStart() {
for (MessagingGateway gateway : this.gatewayMap.values()) {
for (SimpleMessagingGateway gateway : this.gatewayMap.values()) {
if (gateway instanceof Lifecycle) {
((Lifecycle) gateway).start();
}
@@ -319,7 +320,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
@Override // guarded by super#lifecycleLock
protected void doStop() {
for (MessagingGateway gateway : this.gatewayMap.values()) {
for (SimpleMessagingGateway gateway : this.gatewayMap.values()) {
if (gateway instanceof Lifecycle) {
((Lifecycle) gateway).stop();
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2002-2008 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.integration.gateway;
import org.springframework.integration.core.Message;
/**
* Base interface for gateway adapters. In Spring Integration, a "gateway" is a
* component that sends messages to and/or receives messages from message channels
* so that application code does not need to be aware of channels or even messages.
*
* @author Mark Fisher
*/
public interface MessagingGateway {
void send(Object object);
Object receive();
Object sendAndReceive(Object object);
Message<?> sendAndReceiveMessage(Object object);
}

View File

@@ -19,14 +19,15 @@ package org.springframework.integration.gateway;
import org.springframework.integration.core.Message;
/**
* Generic definition of the 'gateway' which will be used by {@link GatewayProxyFactoryBean}
* if 'service-interface' property is not provided
* Interface for a request/reply Message exchange. This will be used as a default
* by {@link GatewayProxyFactoryBean} if no 'service-interface' property has been provided.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.0
*/
interface GenericSendAndReceiveGateway {
interface RequestReplyExchanger {
public Message<?> sendAndReceive(Message<?> message);
public Message<?> exchange(Message<?> request);
}

View File

@@ -19,37 +19,32 @@ package org.springframework.integration.gateway;
import org.springframework.integration.core.Message;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
* Will decorate 'gateway' as {@link MessageHandler} so it could be included in the chain.
* Adapts a {@link RequestReplyExchanger} to the {@link MessageHandler} interface.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.0
*/
public class GatewayInvokingMessageHandler extends AbstractReplyProducingMessageHandler {
class RequestReplyMessageHandlerAdapter extends AbstractReplyProducingMessageHandler {
private GenericSendAndReceiveGateway gateway;
private RequestReplyExchanger exchanger;
/**
* @param gateway
* @param exchanger
*/
public GatewayInvokingMessageHandler(GenericSendAndReceiveGateway gateway) {
Assert.notNull(gateway, "gateway must not be null");
this.gateway = gateway;
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("gateway");
public RequestReplyMessageHandlerAdapter(RequestReplyExchanger exchanger) {
Assert.notNull(exchanger, "exchanger must not be null");
this.exchanger = exchanger;
}
/**
* Will simply delegate to the original gateway
* Delegates to the exchanger.
*/
protected Object handleRequestMessage(Message<?> requestMessage) {
return gateway.sendAndReceive(requestMessage);
return exchanger.exchange(requestMessage);
}
}