From e73df5e33aa7b5680fd29198391fa0b588d0561c Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Wed, 15 Oct 2008 21:27:28 +0000 Subject: [PATCH] Updated channel descriptions in core-api.xml --- spring-integration-reference/src/core-api.xml | 149 +++++++----------- 1 file changed, 57 insertions(+), 92 deletions(-) diff --git a/spring-integration-reference/src/core-api.xml b/spring-integration-reference/src/core-api.xml index e316444796..63de737885 100644 --- a/spring-integration-reference/src/core-api.xml +++ b/spring-integration-reference/src/core-api.xml @@ -46,7 +46,7 @@ java.lang.Object - RETURN_ADDRESS + REPLY_CHANNEL java.lang.Object (can be a String or MessageChannel) @@ -73,6 +73,7 @@ The base implementation of the Message interface is GenericMessage<T>, and it provides two constructors: new GenericMessage<T>(T payload); + new GenericMessage<T>(T payload, Map<String, Object> headers) When a Message is created, a random unique id will be generated. The constructor that accepts a Map of headers will copy the provided headers to the newly created Message. There are also two convenient subclasses available: @@ -89,16 +90,16 @@ new GenericMessage<T>(T payload, Map<String, Object> headers)unmodifiable Collection, and the MessageHeaders' map further exemplifies that; even though the MessageHeaders class implements java.util.Map, any attempt to invoke a - put operation on the MessageHeaders will result in an + put operation (or 'remove' or 'clear') on the MessageHeaders will result in an UnsupportedOperationException. Rather than requiring the creation and population of a Map to pass into the GenericMessage constructor, Spring Integration does provide a far more convenient way to construct Messages: MessageBuilder. - The MessageBuilder provides two factory methods for creating Messages from either an existing Message or a + The MessageBuilder provides two factory methods for creating Messages from either an existing Message or with a payload Object. When building from an existing Message, the headers and payload of that Message will be copied to the new Message: - Message<String> message1 = MessageBuilder.fromPayload("test") + Message<String> message1 = MessageBuilder.withPayload("test") .setHeader("foo", "bar") .build(); @@ -159,58 +160,6 @@ assertEquals(MessagePriority.HIGHEST, anotherMessage.getHeaders().getPriority()) -
- MessageSource - - As alluded to in the overview, the MessageSource interface is itself a marker - interface for any "source" of Messages. The two sub-interfaces - PollableSource - and SubscribableSource - accommodate two types of source: those that must be - polled and those that send Messages on their own. An example of the first type would be a source that represents - a directory in the File-system, and an example of the second type would be an inbound RMI invocation. - - - The PollableSource interface defines a single method for receiving Message objects. - public interface PollableSource<T> extends MessageSource<T> { - Message<T> receive(); -} - The BlockingSource interface extends PollableSource - and adds a single method with a timeout: Message<T> receive(long timeout); - - - Spring Integration also provides a MethodInvokingSource implementation that serves as an - adapter for invoking any arbitrary method on a plain Object (i.e. there is no need to implement an interface). - To use the MethodInvokingSource, provide the Object reference and the method name. - MethodInvokingSource source = new MethodInvokingSource(); -source.setObject(new SourceObject()); -source.setMethodName("sourceMethod"); -Message<?> result = source.receive(); - It is also possible to configure a MethodInvokingSource in XML by providing a - bean reference in the "source" attribute of a <channel-adapter> element along with a "method" attribute. - ]]> - -
- -
- MessageTarget - - The MessageTarget interface defines a single method for sending - Message objects. - public interface MessageTarget { - boolean send(Message<?> message); -} - As with the MessageSource, Spring Integration also provides a - MethodInvokingTarget adapter class. - MethodInvokingTarget target = new MethodInvokingTarget(); -target.setObject(new TargetObject()); -target.setMethodName("targetMethod"); -target.afterPropertiesSet(); -target.send(new StringMessage("test")); - When creating a Channel Adapter for this target, the corresponding XML configuration - is very similar to that of MethodInvokingSource. - ]]> - -
-
MessageChannel @@ -218,41 +167,45 @@ target.send(new StringMessage("test")); MessageChannel that decouples message producers from message consumers. Spring Integration's top-level MessageChannel interface is defined as follows. - Because it extends BlockingTarget, it inherits the following methods: - boolean send(Message message); -boolean send(Message message, long timeout); + boolean send(Message message, long timeout); +}]]> When sending a message, the return value will be true if the message is sent successfully. If the send call times out or is interrupted, then it will return false. - Since Message Channels are also Message Sources, there are two sub-interfaces corresponding to the two source - types. Here is the definition of PollableChannel. - public interface PollableChannel extends MessageChannel, BlockingSource { + Since Message Channels may or may not buffer Messages (as discussed in the overview), there are two + sub-interfaces defining the buffering (pollable) and non-buffering (subscribable) channel behavior. Here is the + definition of PollableChannel. + public interface PollableChannel extends MessageChannel { + + Message<?> receive(); + + Message<?> receive(long timeout); List<Message<?>> clear(); List<Message<?>> purge(MessageSelector selector); } - Since the PollableChannel interface extends BlockingSource, it also inherits the following methods: - Message<T> receive(); - -Message<T> receive(long timeout); Similar to the send methods, when receiving a message, the return value will be null in the case of a timeout or interrupt. - The subscribable channels implement the SubscribableSource interface. Instead - of providing receive methods for polling, these channels will send messages directly to their subscribers. - The SubscribableSource interface defines the following two methods: - boolean subscribe(MessageTarget target); + The SubscribableChannel base interface is implemented by channels that send + Messages directly to their subscribed consumers. Therefore, they do not provide receive methods for polling, but + instead define methods for handling those subscribers: + public interface SubscribableChannel extends MessageChannel { -boolean unsubscribe(MessageTarget target); + boolean subscribe(MessageConsumer consumer); + + boolean unsubscribe(MessageConsumer consumer); + +} Spring Integration provides several different Message Channel implementations. Each is briefly described in the @@ -270,7 +223,7 @@ boolean unsubscribe(MessageTarget target); send(Message) method is invoked, consumers cannot poll for Messages (it does not implement PollableChannel and therefore has no receive() method). Instead, any subscriber - must be a MessageTarget itself, and the subscriber's + must be a MessageConsumer itself, and the subscriber's send(Message) method will be invoked in turn.
@@ -278,10 +231,10 @@ boolean unsubscribe(MessageTarget target); QueueChannel The QueueChannel implementation wraps a queue. Unlike, the - PublishSubscribeChannel, the QueueChannel has - point-to-point semantics. In other words, even if the channel has multiple consumers, only - one of them should receive any Message sent to that channel. It provides a no-argument constructor - (that uses a default capacity of 100) as well as a constructor that accepts the queue capacity: + PublishSubscribeChannel, the QueueChannel has point-to-point + semantics. In other words, even if the channel has multiple consumers, only one of them should receive any + Message sent to that channel. It provides a default no-argument constructor (providing an essentially unbounded + capacity of Integer.MAX_VALUE) as well as a constructor that accepts the queue capacity: public QueueChannel(int capacity) A channel that has not reached its capacity limit will store messages in its internal queue, and the send() method will return immediately even if no receiver is ready to handle the @@ -320,26 +273,38 @@ boolean unsubscribe(MessageTarget target); The RendezvousChannel is also useful for implementing request-reply operations. The sender can create a temporary, anonymous instance of RendezvousChannel - which it then sets as the 'returnAddress' on a Message. After sending that Message, the sender can immediately - call receive (optionally providing a timeout value) in order to block while waiting for a reply Message. + which it then sets as the 'replyChannel' header when building a Message. After sending that Message, the sender + can immediately call receive (optionally providing a timeout value) in order to block while waiting for a reply + Message.
DirectChannel - The DirectChannel has point-to-point semantics, but otherwise is more similar - to the PublishSubscribeChannel than any of the queue-based channel implementations - described above. In other words, it does not implement the PollableChannel - interface, but rather dispatches Messages directly to a subscriber. As a point-to-point channel, however, - it will only send each Message to a single subscribed MessageTarget. - Its primary purpose is to enable a single thread to perform the operations on "both sides" of the channel. For - example, if a receiving target is subscribed to a DirectChannel, then sending a - Message to that channel will trigger invocation of that target's send(Message) - method directly in the sender's thread. The key motivation for providing a channel - implementation with this behavior is to support transactions that must span across the channel while still - benefiting from the abstraction and loose coupling that the channel provides. If the send call is invoked - within the scope of a transaction, then the outcome of the target's invocation can play a role in determining - the ultimate result of that transaction (commit or rollback). + The DirectChannel has point-to-point semantics, but otherwise is more similar to the + PublishSubscribeChannel than any of the queue-based channel implementations described + above. It implements the SubscribableChannel interface instead of the + PollableChannel interface, so it dispatches Messages directly to a subscriber. + As a point-to-point channel, however, it differs from the PublishSubscribeChannel in + that it will only send each Message to a single subscribed + MessageConsumer. Its primary purpose is to enable a single thread to perform the + operations on "both sides" of the channel. For example, if a consumer is subscribed to a + DirectChannel, then sending a Message to that channel will trigger invocation of that + consumer's onMessage(Message) method directly in the sender's + thread. The key motivation for providing a channel implementation with this behavior is to support + transactions that must span across the channel while still benefiting from the abstraction and loose coupling + that the channel provides. If the send call is invoked within the scope of a transaction, then the outcome of + the consumer's invocation (e.g. updating a database record) can play a role in determining the ultimate result + of that transaction (commit or rollback). + + Since the DirectChannel is the simplest option and does not add any additional + overhead that would be required for scheduling and managing the threads of a poller, it is the default + channel type within Spring Integration. The general idea is to define the channels for an application and + then to consider which of those needs to provide buffering to throttle input, and to modify those to be + queue-based PollableChannels. Likewise, if a channel needs to broadcast + messages, it should not be a DirectChannel but rather a + PublishSubscribeChannel. Below you will see how these can be configured. +