Make Message type pluggable

To improve compatibility between Spring's messaging classes and
Spring Integration, the type of Message that is created has been made
pluggable through the introduction of a factory abstraction;
MessageFactory.

By default a MessageFactory is provided that will create
org.springframework.messaging.GenericMessage instances, however this
can be replaced with an alternative implementation. For example,
Spring Integration can provide an implementation that creates
org.springframework.integration.message.GenericMessage instances.

This control over the type of Message that's created allows messages
to flow from Spring messaging code into Spring Integration code without
any need for conversion. In further support of this goal,
MessageChannel, MessageHandler, and SubscribableChannel have been
genericized to make the Message type that they deal with more
flexible.
This commit is contained in:
Andy Wilkinson
2013-06-14 12:34:12 +01:00
parent 641aaf4b6a
commit 3022f5e34f
16 changed files with 188 additions and 51 deletions

View File

@@ -44,7 +44,7 @@ public class GenericMessage<T> implements Message<T>, Serializable {
*
* @param payload the message payload
*/
public GenericMessage(T payload) {
protected GenericMessage(T payload) {
this(payload, null);
}
@@ -56,7 +56,7 @@ public class GenericMessage<T> implements Message<T>, Serializable {
* @param headers message headers
* @see MessageHeaders
*/
public GenericMessage(T payload, Map<String, Object> headers) {
protected GenericMessage(T payload, Map<String, Object> headers) {
Assert.notNull(payload, "payload must not be null");
if (headers == null) {
headers = new HashMap<String, Object>();

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2002-2013 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.messaging;
import java.util.Map;
/**
* A {@link MessageFactory} that creates {@link GenericMessage GenericMessages}.
*
* @author Andy Wilkinson
*/
public class GenericMessageFactory implements MessageFactory<GenericMessage<?>> {
@Override
public <P> GenericMessage<?> createMessage(P payload, Map<String, Object> headers) {
return new GenericMessage<P>(payload, headers);
}
}

View File

@@ -23,7 +23,7 @@ package org.springframework.messaging;
* @author Mark Fisher
* @since 4.0
*/
public interface MessageChannel {
public interface MessageChannel<M extends Message> {
/**
* Send a {@link Message} to this channel. May throw a RuntimeException for
@@ -38,7 +38,7 @@ public interface MessageChannel {
*
* @return whether or not the Message has been sent successfully
*/
boolean send(Message<?> message);
boolean send(M message);
/**
* Send a message, blocking until either the message is accepted or the
@@ -51,6 +51,6 @@ public interface MessageChannel {
* <code>false</code> if the specified timeout period elapses or
* the send is interrupted
*/
boolean send(Message<?> message, long timeout);
boolean send(M message, long timeout);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2002-2013 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.messaging;
import java.util.Map;
/**
* A factory for creating messages, allowing for control of the concrete type of the message.
*
*
*
* @author Andy Wilkinson
*/
public interface MessageFactory<M extends Message<?>> {
/**
* Creates a new message with the given payload and headers
*
* @param payload The message payload
* @param headers The message headers
* @param <P> The payload's type
*
* @return the message
*/
<P> M createMessage(P payload, Map<String, Object> headers);
}

View File

@@ -24,7 +24,7 @@ package org.springframework.messaging;
* @author Iwein Fuld
* @since 4.0
*/
public interface MessageHandler {
public interface MessageHandler<M extends Message> {
/**
* TODO: support exceptions?
@@ -46,6 +46,6 @@ public interface MessageHandler {
* @throws org.springframework.integration.MessageDeliveryException when this handler failed to deliver the
* reply related to the handling of the message
*/
void handleMessage(Message<?> message) throws MessagingException;
void handleMessage(M message) throws MessagingException;
}

View File

@@ -25,16 +25,16 @@ package org.springframework.messaging;
* @author Mark Fisher
* @since 4.0
*/
public interface SubscribableChannel extends MessageChannel {
public interface SubscribableChannel<M extends Message, H extends MessageHandler<M>> extends MessageChannel<M> {
/**
* Register a {@link MessageHandler} as a subscriber to this channel.
*/
boolean subscribe(MessageHandler handler);
boolean subscribe(H handler);
/**
* Remove a {@link MessageHandler} from the subscribers of this channel.
*/
boolean unsubscribe(MessageHandler handler);
boolean unsubscribe(H handler);
}