2010-8-27
kimmking@163.com
2. 消息结构
Spring Integration中的Message是一个通用的数据容器,可以提供任何对象作为负载(payload),任何Message也可以包含一些带有用户扩展属性键值对的头部。
2.1 消息接口
下面是Message的接口定义:
public interface Message<T> {
T getPayload();
MessageHeaders getHeaders();
}
很明显,Message是一个非常重要的API。通过一个通用的包装封装数据,消息系统可以传递它到各处,而无需知道数据的类型。为一个新应用解决了添加各种新类型,或者当类型可以修改或(和)扩展,消息系统将不会被这些更改影响。另一方面,当消息系统中的一些组件需要访问Message中的信息,一些元数据可以从Message头中存取。
2.2 消息头
正如Spring Integration允许任何对象作为Message的负载,它也支持任何对象类型作为消息头值。事实上,MessageHeaders类实现了java.util.Map接口:
public final class MessageHeaders implements Map<String, Object>, Serializable {
...
}
注意:
尽管MessageHeaders实现了Map,它却是一个只读的实现。任何试图put一个值到Map的操作都会抛出一个UnsupportedOperationException异常。remove和clear操作也是一样的。因为Message可以被传递给多个消费者,所以Map的结构不能被修改。并且,Message负载对象在创建以后不能被set。However, the mutability of the header values themselves (or the payload Object) is intentionally left as a decision for the framework user.
作为Map的一个实现,通过调用get方法,传递消息头的名称作为参数,即可以获取相应的消息头。另外,可以提供一个Class类型的第二个参数。更甚至于,对于获取预定义的值,可以使用非常方便的getter。如下是上面三种情形的示例:
Object someValue = message.getHeaders().get("someKey");
CustomerId customerId = message.getHeaders().get("customerId", CustomerId.class);
Long timestamp = message.getHeaders().getTimestamp();
如下是预定义的消息头:
Table 2.1. Pre-defined Message Headers
Header Name
|
Header Type
|
ID
|
java.util.UUID
|
TIMESTAMP
|
java.lang.Long
|
EXPIRATION_DATE
|
java.lang.Long
|
CORRELATION_ID
|
java.lang.Object
|
REPLY_CHANNEL
|
java.lang.Object (can be a String or MessageChannel)
|
ERROR_CHANNEL
|
java.lang.Object (can be a String or MessageChannel)
|
SEQUENCE_NUMBER
|
java.lang.Integer
|
SEQUENCE_SIZE
|
java.lang.Integer
|
PRIORITY
|
MessagePriority (an enum)
|
很多inbound和outbound的adapter实现也提供或(和)期望适当的消息头,当然也可以配置额外的用户自定义消息头。
2.3 消息实现
Message接口的基本实现是GenericMessage<T>,他提供了两个构造器:
new GenericMessage<T>(T payload);
new GenericMessage<T>(T payload, Map<String, Object> headers)
创建一个Message时,会同时生成一个随即的唯一ID。构造器可以接受一个消息头的Map,然后复制其中的消息头到新创建的Message。
还有两个方便的子类可用:StringMessage和ErrorMessage。前者接受一个String作为负载:
StringMessage message = new StringMessage("hello world");
String s = message.getPayload();
后者接受任何Throwable对象作为负载:
ErrorMessage message = new ErrorMessage(someThrowable);
Throwable t = message.getPayload();
注意到这些实现得益于GenericMessage类是参数化的。因此,正如上面的示例,从消息中获取负载对象不需要显示的转换类型。
2.4 MessageBuilderHelper类
你可以注意到Message接口只定义了获取消息负载和消息头的方法,却没有setter。这是因为消息创建后就不能被修改。因此,当一个消息的实例发送给多个消费者(例如通过一个发布订阅通道),如果消费者之一需要使用不同的负载类型发送一个响应,它应该创建一个新的Message。所以,这些变动不会影响其他消费者。记住,多个消费者可以访问同样的消息负载实例和消息头,这样的一个实例是否不可修改取决于开发者。换句话说,Message的契约就像是一个不可修改的集合(unmodifiable Collection),而MessageHeaders的map进一步展示了这一点。虽然MessageHeaders类实现了java.util.Map,但是MessageHeaders上任何一个put(或是remove、clear)操作的调用都会产生一个UnsupportedOperationException异常。
相对于需要创建并填充一个Map然后传递给GenericMessage的构造函数来创建消息,Spring Integration提供了一个更方便的方式:MessageBuilder。MessageBuilder提供了两个工厂方法从一个已经存在的消息或是一个负载对象来构造消息实例。当从一个已经存在的消息构建时,
原有消息的负载和消息头都会被复制到新的消息:
Message<String> message1 = MessageBuilder.withPayload("test")
.setHeader("foo", "bar")
.build();
Message<String> message2 = MessageBuilder.fromMessage(message1).build();
assertEquals("test", message2.getPayload());
assertEquals("bar", message2.getHeaders().get("foo"));
如果需要使用一个新的负载来创建一个消息,但是仍然希望从已经存在的消息复制消息头,你可以使用MessageBuilder的copy方法之一。
Message<String> message3 = MessageBuilder.withPayload("test3")
.copyHeaders(message1.getHeaders())
.build();
Message<String> message4 = MessageBuilder.withPayload("test4")
.setHeader("foo", 123)
.copyHeadersIfAbsent(message1.getHeaders())
.build();
assertEquals("bar", message3.getHeaders().get("foo"));
assertEquals(123, message4.getHeaders().get("foo"));
注意copyHeadersIfAbsent不会覆盖现有的值。在上面的第二个例子中,你也可以看到如何使用setHeader设置用户自定义的消息头。最后,系统提供了一些方法来设置一些预定义的消息头,它们不会妨碍设置任何消息头(MessageHeaders类中也定义了这些预定义消息头名字的常量)。
Message<Integer> importantMessage = MessageBuilder.withPayload(99)
.setPriority(MessagePriority.HIGHEST)
.build();
assertEquals(MessagePriority.HIGHEST, importantMessage.getHeaders().getPriority());
Message<Integer> anotherMessage = MessageBuilder.fromMessage(importantMessage)
.setHeaderIfAbsent(MessageHeaders.PRIORITY, MessagePriority.LOW)
.build();
assertEquals(MessagePriority.HIGHEST, anotherMessage.getHeaders().getPriority());
MessagePrioity是仅仅在使用PrioityChannel时被考虑(将在下一章描述)。它被定义成一个包括5个可能的值的枚举量。
public enum MessagePriority {
HIGHEST,
HIGH,
NORMAL,
LOW,
LOWEST
}
分享到:
相关推荐
在 Spring Integration 中,`spring-integration-stream-2.1.5.RELEASE.zip` 文件代表的是该项目的一个特定版本,即2.1.5.RELEASE。这个版本包含了对流处理的支持,允许开发者利用流的概念来处理和传输消息,从而...
标题 "spring-integration-stream-4.0.2.RELEASE.zip" 暗示了这是一个关于Spring Integration框架的特定版本,4.0.2.RELEASE,其中聚焦于流处理的组件。Spring Integration是Spring框架的一个扩展,它提供了一种声明...
* spring-integration-ws:提供了 Spring Integration 的 Web 服务功能。 * spring-ws-core:提供了 Spring WS 的核心功能。 项目配置 在这个项目中,我们使用了以下配置: * application-context.xml:包含了...
org.springframework.integration-tests-3.0.0.M4.jar
包含翻译后的API文档:spring-webmvc-5.0.8.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework:spring-webmvc:5.0.8.RELEASE; 标签:springframework、spring、webmvc、中文文档、jar包...
Spring Integration。 官网 Spring Integration API。 Spring Integration 开发文档。
包含翻译后的API文档:spring-webmvc-5.2.15.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework:spring-webmvc:5.2.15.RELEASE; 标签:springframework、spring、webmvc、中文文档、jar...
使用Spring Boot 1.5.13的应用程序以及与spring-integration-sftp相关的maven依赖项 为了在本地使用该应用程序,我们需要设置两个远程SFTP服务器,可以使用下面的链接轻松下载该服务器 以下属性需要在application....
包含翻译后的API文档:spring-context-support-1.0.10-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.alibaba.spring:spring-context-support:1.0.10; 标签:spring、alibaba、context、support、jar包、java...
在这个"spring-integration-http-demo"项目中,我们将重点关注Spring Integration的HTTP模块,它是用于处理HTTP请求和响应的关键组件。 在Spring Integration中,HTTP模块允许我们构建客户端和服务端的应用,能够...
包含翻译后的API文档:spring-webmvc-5.3.7-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework:spring-webmvc:5.3.7; 标签:springframework、spring、webmvc、中文文档、jar包、java; 使用方法...
包含翻译后的API文档:spring-webmvc-5.3.15-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework:spring-webmvc:5.3.15; 标签:spring、webmvc、springframework、jar包、java、中文文档; 使用...
包含翻译后的API文档:spring-security-crypto-5.5.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-crypto:5.5.2; 标签:springframework、security、spring、...
包含翻译后的API文档:spring-cloud-gateway-server-3.1.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.cloud:spring-cloud-gateway-server:3.1.1; 标签:cloud、spring、server、spring...
包含翻译后的API文档:spring-security-crypto-5.6.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-crypto:5.6.1; 标签:spring、security、springframework、...
包含翻译后的API文档:spring-plugin-core-2.0.0.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE; 标签:spring、core、plugin、spring...
本示例项目"activityexample"便是将Activiti API与Spring进行集成的一个实例,通过解压缩文件"activiti-api-spring-integration-example.zip",我们可以深入学习如何在Spring环境中运用Activiti。 首先,让我们理解...
包含翻译后的API文档:spring-jdbc-5.3.15-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework:spring-jdbc:5.3.15; 标签:spring、springframework、jar包、java、中文文档; 使用方法:解压翻译...
#### 二、Spring Integration框架概览 ##### 2.1 背景 - Spring Integration是基于Spring框架的一个子项目,专注于为企业级应用程序提供集成解决方案。 ##### 2.2 目标与原则 - 目标是为Java EE应用提供一个轻量级...
包含翻译后的API文档:spring-plugin-core-1.2.0.RELEASE-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.springframework.plugin,artifactId:spring-plugin-core,version:1.2.0.RELEASE 使用...