DefaultMessageHandlerAdapter now supports methods expecting a Message-typed parameter.

This commit is contained in:
Mark Fisher
2008-01-09 15:49:50 +00:00
parent 1e872b82eb
commit 9acd5bf089
5 changed files with 252 additions and 9 deletions

View File

@@ -16,25 +16,41 @@
package org.springframework.integration.handler;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.Ordered;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageMapper;
import org.springframework.integration.util.SimpleMethodInvoker;
/**
* An implementation of {@link MessageHandler} that invokes the specified method
* on the provided target object. It then uses a {@link MessageMapper} strategy
* for converting the object to a {@link Message}. If the method has a non-null
* return value, a reply message will be generated by the mapper.
* on the provided target object. If {@link #shouldUseMapperOnInvocation} is set
* to <code>true</code> (the default), it will use the provided
* {@link org.springframework.integration.message.MessageMapper} strategy to
* convert the inbound {@link Message} to an object that will be passed as the
* method parameter. If the method has a non-null return value, a reply message
* will be generated by the mapper.
*
* @author Mark Fisher
*/
public class DefaultMessageHandlerAdapter<T> extends AbstractMessageHandlerAdapter<T>
implements Ordered, InitializingBean {
public class DefaultMessageHandlerAdapter<T> extends AbstractMessageHandlerAdapter<T> implements Ordered {
private boolean shouldUseMapperOnInvocation = true;
/**
* Specify whether the handler method should use the
* {@link org.springframework.integration.message.MessageMapper} when
* invoking the target method. Default is <code>true</code>. To force
* passing the {@link Message} directly, set this to <code>false</code>.
*/
public void setShouldUseMapperOnInvocation(boolean shouldUseMapperOnInvocation) {
this.shouldUseMapperOnInvocation = shouldUseMapperOnInvocation;
}
public Object doHandle(Message message, SimpleMethodInvoker invoker) {
return invoker.invokeMethod(this.getMapper().fromMessage(message));
if (this.shouldUseMapperOnInvocation) {
return invoker.invokeMethod(this.getMapper().fromMessage(message));
}
return invoker.invokeMethod(message);
}
}

View File

@@ -19,8 +19,10 @@ package org.springframework.integration.handler.config;
import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.integration.MessagingConfigurationException;
import org.springframework.integration.handler.AbstractMessageHandlerAdapter;
import org.springframework.integration.handler.MessageHandler;
@@ -43,6 +45,14 @@ public abstract class AbstractMessageHandlerCreator implements MessageHandlerCre
adapter.setOrder(orderAnnotation.value());
}
}
if (handler instanceof InitializingBean) {
try {
((InitializingBean) handler).afterPropertiesSet();
}
catch (Exception e) {
throw new MessagingConfigurationException("failed to initialize handler", e);
}
}
return handler;
}

View File

@@ -20,8 +20,10 @@ import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.core.annotation.Order;
import org.springframework.integration.MessagingConfigurationException;
import org.springframework.integration.handler.DefaultMessageHandlerAdapter;
import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.message.Message;
/**
* Default implementation of the handler creator strategy that creates a
@@ -34,7 +36,14 @@ import org.springframework.integration.handler.MessageHandler;
public class DefaultMessageHandlerCreator extends AbstractMessageHandlerCreator {
public MessageHandler doCreateHandler(Object object, Method method, Map<String, ?> attributes) {
return new DefaultMessageHandlerAdapter<Object>();
Class<?>[] types = method.getParameterTypes();
if (types.length != 1) {
throw new MessagingConfigurationException("exactly one method parameter is required");
}
DefaultMessageHandlerAdapter<Object> adapter = new DefaultMessageHandlerAdapter<Object>();
boolean expectsMessage = (Message.class.isAssignableFrom(types[0]));
adapter.setShouldUseMapperOnInvocation(!expectsMessage);
return adapter;
}
}

View File

@@ -0,0 +1,108 @@
/*
* 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.integration.handler;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.StringMessage;
/**
* @author Mark Fisher
*/
public class DefaultMessageHandlerAdapterTests {
@Test
public void testPayloadAsMethodParameterAndObjectAsReturnValue() {
DefaultMessageHandlerAdapter<TestHandler> adapter = new DefaultMessageHandlerAdapter<TestHandler>();
adapter.setObject(new TestHandler());
adapter.setMethodName("acceptPayloadAndReturnObject");
adapter.afterPropertiesSet();
Message<?> result = adapter.handle(new StringMessage("testing"));
assertEquals("testing-1", result.getPayload());
}
@Test
public void testPayloadAsMethodParameterAndMessageAsReturnValue() {
DefaultMessageHandlerAdapter<TestHandler> adapter = new DefaultMessageHandlerAdapter<TestHandler>();
adapter.setObject(new TestHandler());
adapter.setMethodName("acceptPayloadAndReturnMessage");
adapter.afterPropertiesSet();
Message<?> result = adapter.handle(new StringMessage("testing"));
assertEquals("testing-2", result.getPayload());
}
@Test
public void testMessageAsMethodParameterAndObjectAsReturnValue() {
DefaultMessageHandlerAdapter<TestHandler> adapter = new DefaultMessageHandlerAdapter<TestHandler>();
adapter.setShouldUseMapperOnInvocation(false);
adapter.setObject(new TestHandler());
adapter.setMethodName("acceptMessageAndReturnObject");
adapter.afterPropertiesSet();
Message<?> result = adapter.handle(new StringMessage("testing"));
assertEquals("testing-3", result.getPayload());
}
@Test
public void testMessageAsMethodParameterAndMessageAsReturnValue() {
DefaultMessageHandlerAdapter<TestHandler> adapter = new DefaultMessageHandlerAdapter<TestHandler>();
adapter.setShouldUseMapperOnInvocation(false);
adapter.setObject(new TestHandler());
adapter.setMethodName("acceptMessageAndReturnMessage");
adapter.afterPropertiesSet();
Message<?> result = adapter.handle(new StringMessage("testing"));
assertEquals("testing-4", result.getPayload());
}
@Test
public void testMessageSubclassAsMethodParameterAndMessageAsReturnValue() {
DefaultMessageHandlerAdapter<TestHandler> adapter = new DefaultMessageHandlerAdapter<TestHandler>();
adapter.setShouldUseMapperOnInvocation(false);
adapter.setObject(new TestHandler());
adapter.setMethodName("acceptMessageSubclassAndReturnMessage");
adapter.afterPropertiesSet();
Message<?> result = adapter.handle(new StringMessage("testing"));
assertEquals("testing-5", result.getPayload());
}
private static class TestHandler {
public String acceptPayloadAndReturnObject(String s) {
return s + "-1";
}
public Message<?> acceptPayloadAndReturnMessage(String s) {
return new StringMessage(s + "-2");
}
public String acceptMessageAndReturnObject(Message<?> m) {
return m.getPayload() + "-3";
}
public Message<?> acceptMessageAndReturnMessage(Message<?> m) {
return new StringMessage(m.getPayload() + "-4");
}
public Message<?> acceptMessageSubclassAndReturnMessage(StringMessage m) {
return new StringMessage(m.getPayload() + "-5");
}
}
}

View File

@@ -0,0 +1,100 @@
/*
* 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.integration.handler.config;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.StringMessage;
/**
* @author Mark Fisher
*/
public class DefaultMessageHandlerCreatorTests {
@Test
public void testPayloadAsMethodParameterAndObjectAsReturnValue() throws Exception {
DefaultMessageHandlerCreator creator = new DefaultMessageHandlerCreator();
MessageHandler handler = creator.createHandler(new TestHandler(),
TestHandler.class.getMethod("acceptPayloadAndReturnObject", String.class), null);
Message<?> result = handler.handle(new StringMessage("testing"));
assertEquals("testing-1", result.getPayload());
}
@Test
public void testPayloadAsMethodParameterAndMessageAsReturnValue() throws Exception {
DefaultMessageHandlerCreator creator = new DefaultMessageHandlerCreator();
MessageHandler handler = creator.createHandler(new TestHandler(),
TestHandler.class.getMethod("acceptPayloadAndReturnMessage", String.class), null);
Message<?> result = handler.handle(new StringMessage("testing"));
assertEquals("testing-2", result.getPayload());
}
@Test
public void testMessageAsMethodParameterAndObjectAsReturnValue() throws Exception {
DefaultMessageHandlerCreator creator = new DefaultMessageHandlerCreator();
MessageHandler handler = creator.createHandler(new TestHandler(),
TestHandler.class.getMethod("acceptMessageAndReturnObject", Message.class), null);
Message<?> result = handler.handle(new StringMessage("testing"));
assertEquals("testing-3", result.getPayload());
}
@Test
public void testMessageAsMethodParameterAndMessageAsReturnValue() throws Exception {
DefaultMessageHandlerCreator creator = new DefaultMessageHandlerCreator();
MessageHandler handler = creator.createHandler(new TestHandler(),
TestHandler.class.getMethod("acceptMessageAndReturnMessage", Message.class), null);
Message<?> result = handler.handle(new StringMessage("testing"));
assertEquals("testing-4", result.getPayload());
}
@Test
public void testMessageSubclassAsMethodParameterAndMessageAsReturnValue() throws Exception {
DefaultMessageHandlerCreator creator = new DefaultMessageHandlerCreator();
MessageHandler handler = creator.createHandler(new TestHandler(),
TestHandler.class.getMethod("acceptMessageSubclassAndReturnMessage", StringMessage.class), null);
Message<?> result = handler.handle(new StringMessage("testing"));
assertEquals("testing-5", result.getPayload());
}
private static class TestHandler {
public String acceptPayloadAndReturnObject(String s) {
return s + "-1";
}
public Message<?> acceptPayloadAndReturnMessage(String s) {
return new StringMessage(s + "-2");
}
public String acceptMessageAndReturnObject(Message<?> m) {
return m.getPayload() + "-3";
}
public Message<?> acceptMessageAndReturnMessage(Message<?> m) {
return new StringMessage(m.getPayload() + "-4");
}
public Message<?> acceptMessageSubclassAndReturnMessage(StringMessage m) {
return new StringMessage(m.getPayload() + "-5");
}
}
}