Spring Integration 2.0 发布候选版本 1

工程 | Mark Fisher | 2010年10月29日 | ...

我们很高兴地宣布 Spring Integration 2.0 的第一个发布候选版本!下载 | 参考手册 | JavaDoc

我想借此机会提供一个关于“新增功能”的概述。实际上,新增的功能和改进太多了,无法在一篇文章中全部涵盖,但我将重点介绍一些亮点。随着我们越来越接近 2.0 GA 版本的发布,我们将发布更多博客文章。目前,这篇文章大致基于 Oleg 和我上周在 SpringOne 上做的一个演讲。该演讲主要是演示驱动的,代码可在我们的Git 仓库中找到。

为了提供一些结构,我将按多个类别介绍这些功能……

Spring 3.0 启用的增强功能

Spring Integration 2.0 直接基于 Spring 3.0 构建。事实上,RC1 版本构建于上周发布的 Spring 3.0.5 之上。在这里,我们将了解一下底层框架的重大升级所带来的几个最显著的功能。

Spring 表达式语言

您现在可以在 Spring Integration 核心命名空间的转换器、路由器、过滤器、分割器、聚合器、服务激活器以及许多其他元素中使用 SpEL 表达式。例如,如果您想根据有效负载对象中的简单属性评估过滤器规则,只需执行以下操作:


<filter input-channel="numbers" expression="payload > 0" output-channel="positives"/>

在许多情况下,“expression”属性可以替换“ref”和“method”的使用,以及该 ref 指向的 POJO。另一方面,即使您确实需要在 Spring 上下文中执行 bean 上的方法,简单的“method”属性可能也不够。例如,您可能需要控制传递给方法的多个参数。虽然方法参数上的 @Payload 和 @Header 注解提供了一种选择,但有时最好将此类细节保留在配置中,而不是代码中。这是一个使用 SpEL BeanResolver 策略而不是“ref”的示例:


<router input-channel="accounts"
    expression="@accountService.getAccountType(payload.accountId, payload.address.country)"/>
ConversionService 和 Converter

您可以定义一个名为“integrationConversionService”的 ConversionService bean,然后注册任何您想要的Converter(如有必要,包括您自己的自定义实现)。Spring Integration 中有两个地方使用了该 ConversionService。对于提前转换,您可以向 元素添加“datatype”属性,并提供要在该通道上允许的类的全限定名称。这是一个示例:


<channel id="datatypeChannel" datatype="example.Foo"/>

<beans:bean id="integrationConversionService"
            class="org.springframework.context.support.ConversionServiceFactoryBean">
    <beans:property name="converters">
        <beans:bean class="conversion.StringToFooConverter"/>
    </beans:property>
</beans:bean>

“integrationConversionService”在 SpEL 表达式的评估过程中起着重要作用。每个表达式都针对 EvaluationContext 进行评估,并且该上下文知道“integrationConversionService”。在 Spring Integration 中,我们依赖于 SpEL 来进行所有方法调用(不仅在使用“expression”属性时,即使对于“ref”和“method”配置也是如此)。这意味着您可以利用从 Message 实例绑定到方法调用的值的运行时类型转换。例如,如果您正在调用 FooService 但在 Message 有效负载中传递 Bar 对象,那么您只需要使用“integrationConversionService”注册一个 BarToFooConverter。此示例还显示了一种更简洁的注册 Converter 的方法。通过使用新的“converter”元素的命名空间支持,您甚至不需要显式定义“integrationConversionService”bean。


<!-- FooService.process(Foo) will be invoked, even though the Message payload is a Bar instance -->
<service-activator input-channel="in" ref="fooService" method="process" output-channel="out"/>

<converter>
    <beans:bean class="example.BarToFooConverter"/>
</converter>
TaskScheduler 和 Trigger

Spring Integration 1.0 有自己实现的 TaskScheduler 以及基于间隔和 cron 的 Trigger 实现。现在 Spring 3.0 提供了 TaskScheduler 和 Trigger,我们可以依赖它们。事实上,我们能够从 Spring Integration 端删除大量代码,同时将其中一些代码贡献回底层框架(例如,轻量级 CronTrigger 实现)。任何轮询使用者都可以使用显式的 子元素进行配置(否则,它将依赖于单个默认轮询器配置)。这些轮询器元素接受以下属性之一:“fixed-delay”、“fixed-rate”或“cron”。事实上,您甚至可以提供 Spring 的 Trigger 接口的自定义实现,然后使用“trigger”属性作为引用。这是一个使用 cron 表达式的轮询器的示例:


<file:inbound-channel-adapter directory="/some/path">
    <poller cron="*/10 * 9-17 * * MON-FRI"/>
</file:inbound-channel-adapter>
RestTemplate 和 HttpMessageConverter

我们的传出 HTTP 适配器现在委托给 Spring 的 RestTemplate 来执行 HTTP 请求和处理其响应。这意味着 HttpMessageConverter 策略起着核心作用。我们默认启用了多个转换器,但您可以完全自定义列表和/或添加您自己的实现。我们实际上也在 HTTP 入站适配器中使用了相同的 HttpMessageConverter 策略。我们利用 RestTemplate 的另一个好特性是使用 URI 占位符。以下 HTTP 传出消息网关示例演示了自定义 HttpMessageConverter 和 URI 占位符的使用。事实上,在 URI 中替换的值是在运行时针对 Message 有效负载评估 SpEL 表达式的结果。


<http:outbound-gateway id="trafficService" 
        url="http://example/traffic/{zipCode}" 
        request-channel="requestChannel"
        reply-channel="responseChannel" 
        http-method="GET"
        message-converters="trafficConverter"
        expected-response-type="example.Traffic">
    <http:uri-variable name="zipCode" expression="payload.address.zipcode"/>
</http:outbound-gateway>

企业集成模式的补充

同样在 2.0 中,我们还增加了对 Hohpe 和 Woolf 的企业集成模式书中描述的更多模式的支持。

消息历史记录

通过在 Application Context 中启用消息历史记录,将向每条消息添加一个标头。该标头会跟踪所有遍历的组件,包括每个通道和端点的名称以及该遍历的时间戳。对于异步交互和可能跨越多个线程的流很常见的消息传递应用程序而言,监控和审核可能是一个重大挑战。即使仅在开发时启用,这个简单的标头对于解决这一挑战也极其有用。切换此功能非常简单;只需在配置中添加或删除 元素即可。默认情况下,它将跟踪每个通道和端点的历史记录,但这可以通过简单的名称模式进行微调。


<message-history tracked-components="*Service, foo*"/>
消息存储

消息存储提供了一种持久化消息的方法,适用于任何可能需要很长时间才能在一个事务中完成的进程。例如,通过使用新的基于 MessageStore 的 Message Channel,您可以拥有缓冲区事务行为,而无需依赖额外的中间件。您需要使用支持事务持久化的 MessageStore 实现,但这具有很大的灵活性。我们提供了一个 JDBC 实现以及许多常用 RDBMS 的 DDL,并且我们已经制作了一个基于 GemFire 的实现的原型。随着 Spring Data 项目的不断发展,您可以预期在这个领域看到选项的大幅增加。使用共享存储的另一个好处是,多个进程可以使用相同的组件运行。换句话说,您可以分发一个分散收集配置(使用分割器、聚合器和一些中间组件),但是只要这些聚合器都共享同一个 MessageStore,就可以分发工作负载。


<aggregator input-channel="in" ref="aggregator"
    message-store="messageStore" output-channel="out"/>

<int-jdbc:message-store id="messageStore" data-source="dataSource"/>
凭证检查

凭证检查模式背后的思想是,您可以将 Message 有效负载交换为“凭证票据”,反之亦然。这允许您减少带宽和/或避免在通道之间发送消息时的潜在安全问题。您可以将其视为“按引用传递”,而不是典型的“按值传递”语义。我们的实现直接构建在我们刚才提到的 Message Store 支持之上。“claim-check-in”和“claim-check-out”转换器对应该引用同一个 Message Store。为方便起见,将首先考虑名为“messageStore”的单个 bean。如有必要,您可以通过“message-store”属性提供显式引用。


<claim-check-in input-channel="payloadsIn" output-channel="ticketsOut"/>

<claim-check-out input-channel="ticketsIn" output-channel="payloadsOut"/>
控制总线

控制总线允许您使用消息传递来管理和监控端点和通道。事实上,这是一个相当通用的机制,您可以在其中发送一条消息,其有效负载实际上是要针对集成应用程序中某个组件进行评估的 SpEL 表达式。例如,您可以向控制总线的输入通道发送“@somePoller.stop()”的有效负载。要启用此功能,只需添加元素:


<control-bus input-channel="controlChannel"/>

新的通道适配器和消息网关

我们在 Spring Integration 2.0 中添加了一些新的通道适配器和消息网关。这里没有提供每个适配器的示例配置,对于那些已经在文档中很好地涵盖的适配器,我将简单地提供指向 Spring Integration 参考手册中相关部分的链接。

还有一些其他内容将在 GA 参考中介绍,但我将在此处提供简短的描述和/或相关链接。Josh Long 在这篇最近的博客中详细介绍了 FTP 和 SFTP 适配器。

我们还添加了 RSS/Atom Feed 读取支持。这是一个示例:


<feed:inbound-channel-adapter channel="newsChannel" url="http://example/news/rss.xml"/>

以及大家最喜欢的:Twitter 适配器。我们支持传入和传出的状态更新以及直接消息。这是一个简单的示例。正如您所看到的,它支持 OAuth 启用的 Twitter 连接实例的配置:


<twitter:outbound-update-channel-adapter channel="tweets"
            twitter-connection="twitterConnection"/>

<twitter:twitter-connection id="twitterConnection"
            consumer-key="${twitter.oauth.consumerKey}"
            consumer-secret="${twitter.oauth.consumerSecret}"            
            access-token="${twitter.oauth.accessToken}"
            access-token-secret="${twitter.oauth.accessTokenSecret}"/>

其他补充

动态 Groovy 脚本

与上面显示的 SpEL 示例一样,您实际上可以使用 Groovy 脚本作为任何转换器、过滤器、路由器、分割器等。脚本可以非常简单,并且可以利用在运行时绑定到脚本执行上下文的“payload”和“headers”。例如,以下 Groovy 脚本可以定义为“LengthRouter.groovy”:


return payload.length() > 100 ? 'long' : 'short'

然后,您可以从路由器元素(或任何其他核心元素类型)中引用它。您可以提供“refresh-check-delay”,以便在运行时拾取脚本中的更改。


<router input-channel="strings">
    <int-groovy:script location="example/LengthRouter.groovy" refresh-check-delay="10000"/>
</router>

当然,您可以在 Groovy 脚本中执行更多操作。通常,Groovy 脚本选项在 SpEL 和 POJO 之间提供了一个不错的中间地带。

映射转换器

这些对称转换器将有效负载对象转换为/从 Map,其中 Map 中的键可以通过 SpEL 保持“扁平”属性路径(例如,“customer.address.city”)。


<object-to-map-transformer input-channel="objectsIn" output-channel="mapsOut"/>

<map-to-object-transformer input-channel="mapsIn" output-channel="objectsOut"/>
JSON 转换器

这些对称转换器将有效负载对象转换为/从 JSON。它们使用 Jackson 库,“object-mapper”如果需要自定义行为,可以被引用。


<object-to-json-transformer input-channel="objectsIn" output-channel="jsonOut"/>

<json-to-object-transformer input-channel="jsonIn" output-channel="objectsOut"/>
序列化转换器

这些对称的转换器用于在有效负载对象和字节数组之间进行转换。虽然在2.0版本中并非完全全新,但这些转换器现在委托给一对新的策略接口。默认策略是标准的Java序列化。但是,您可以选择提供一个“序列化器”(或对于反序列化转换器则为“反序列化器”)属性值来引用任何序列化器(或反序列化器)实现。这些是Spring 3.0.5中提供的新策略接口。这些相同的策略也用于JDBC MessageStore以及TCP/UDP适配器中。同样,随着Spring Data项目的演进,您可以期待看到许多新的实现。


<payload-serializing-transformer input-channel="objectsIn" output-channel="bytesOut"
            serializer="someCustomSerializer"/>

<payload-deserializing-transformer input-channel="bytesIn" output-channel="objectsOut"
            deserializer="someCustomDeserializer">
SpringSource工具套件可视化编辑器

最后,我想指出的是,最新版本的SpringSource工具套件中包含一个令人惊叹的用于Spring Integration的新可视化编辑器。如果您尚未使用STS 2.5.0,您真的应该立即下载!这是我们的“Cafe”示例在STS可视化编辑器中的屏幕截图:

结论

像往常一样,我原本打算写一篇“简短的”博文,结果却变成了一篇有点冗长的文章。好消息是,即使是这个看似很长的功能列表,也仅仅触及了Spring Integration 2.0所提供的功能的表面。请下载RC1 并试用一下。一如既往,我们非常期待社区的反馈。我们希望您喜欢RC1,并且通过您在论坛问题跟踪器中的贡献,我们可以确保2.0 GA版本更好。

谢谢!-Mark

获取Spring新闻

通过Spring新闻保持联系

订阅

领先一步

VMware提供培训和认证,以快速提升您的进度。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看Spring社区中所有即将举行的活动。

查看全部