Spring Integration 2.0 Release Candidate 1

平山
2023-12-01

Engineering
Mark Fisher
October 29, 2010

We are pleased to announce the first release candidate of Spring Integration 2.0!
Download | Reference Manual | JavaDoc

I thought I would take the opportunity to provide a general “what’s new?” guide. There are actually too many new features and improvements to cover them all in a single post, but I will focus on some of the highlights. We will be posting more blogs as we get closer to the 2.0 GA release. For now, this post is roughly based on a session that Oleg and I presented last week at SpringOne. That presentation was mostly demo-driven, and the code is available in our Git repository.

In order to provide some structure here, I’ll walk through the features across a number of categories…
Enhancements Enabled by Spring 3.0

Spring Integration 2.0 builds directly on Spring 3.0. In fact, the RC1 version builds upon Spring 3.0.5, which was released just last week. Here we’ll look at a few of the most notable features enabled by that significant upgrade to the underlying framework.
Spring Expression Language

You can now use SpEL expressions within the transformer, router, filter, splitter, aggregator, service-activator, and many more elements of the Spring Integration core namespace. For example if you can evaluate a Filter rule based on a simple property within your payload object, just do the following:

In many cases, the ‘expression’ attribute can replace the use of ‘ref’ and ‘method’ as well as the POJO to which that ref points. On the other hand, even if you do need to execute a method on a bean within your Spring context, the simple ‘method’ attribute might not be sufficient. For example, you might need to control more than one parameter being passed to the method. While the @Payload and @Header annotations on method parameters provide one option, sometimes it’s preferable to keep such details in the configuration rather than the code. Here’s an example using the SpEL BeanResolver strategy instead of a ‘ref’:

ConversionService and Converter

You can define a ConversionService bean named “integrationConversionService” and then register any Converters you’d like (including your own custom implementations if necessary). There are two places where that ConversionService is used within Spring Integration. For eager conversion, you can add a “datatype” attribute to a element and provide the fully-qualified name of the Class you want to allow on that channel. Here’s an example:

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

The “integrationConversionService” contributes in a significant way during the evaluation of SpEL expressions. Every expression is evaluated against an EvaluationContext, and that context is aware of the “integrationConversionService”. Within Spring Integration, we rely upon SpEL for all of the method invocation (not only when using ‘expression’ attributes but even for ‘ref’ and ‘method’ configuration). That means that you can take advantage of runtime type conversion of the values being bound to a method invocation from a Message instance. For example, if you are calling the FooService but passing a Bar object within a Message payload, then you only need to register a BarToFooConverter with the “integrationConversionService”. This example also shows a much more concise way to register Converters. By using the namespace support via a new ‘converter’ element, you don’t even need to explicitly define the “integrationConversionService” bean:

TaskScheduler and Trigger

Spring Integration 1.0 had its own implementation of a TaskScheduler as well as both interval and cron-based Trigger implementations. Now that Spring 3.0 provides a TaskScheduler and Trigger, we are able to depend on those. In fact, we were able to remove a significant amount of code from the Spring Integration side while contributing some of that back to the underlying framework (e.g. the lightweight CronTrigger implementation). Any Polling Consumer can be configured with an explicit sub-element (otherwise, it would rely upon the single default poller configuration). Those poller elements accept one of the following attributes: ‘fixed-delay’, ‘fixed-rate’ or ‘cron’. In fact, you can even provide a custom implementation of Spring’s Trigger interface, and then use the ‘trigger’ attribute as a reference instead. Here’s an example of a poller with a cron expression:

<file:inbound-channel-adapter directory="/some/path">

</file:inbound-channel-adapter>

RestTemplate and HttpMessageConverter

Our outbound HTTP adapters now delegate to Spring’s RestTemplate for executing the HTTP request and handling its response. This means that the HttpMessageConverter strategy plays a central role. We have several converters enabled by default, but you can fully customize the list and/or add your own implementations. We are actually using the same HttpMessageConverter strategy within the HTTP inbound adapters as well. Another nice feature where we take advantage of RestTemplate is the use of URI placeholders. The following example of an HTTP outbound Messaging Gateway demonstrates both a custom HttpMessageConverter and the use of a URI placeholder. In fact, the value that is replaced in the URI is the result of SpEL evaluation against the Message payload at runtime:

<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>

Enterprise Integration Pattern Additions

Also in 2.0 we have added support for even more of the patterns described in Hohpe and Woolf’s Enterprise Integration Patterns book.
Message History

By enabling Message History within the Application Context, a header will be added to each Message. That header keeps track of all traversed components, including the name of each channel and endpoint as well as the timestamp of that traversal. For messaging applications where asynchronous interaction and flows that may span multiple threads are common, monitoring and auditing can be a major challenge. This simple header is incredibly useful for addressing that challenge, even if only enabled at development time. It’s trivial to toggle the feature; simply add or remove the element in the configuration. By default it will track history for every channel and endpoint, but that can be fine-tuned with simple name patterns:

Message Store

The Message Store provides a way to persist messages for any process that might take too long to happen in a single transaction. For example, by using the new MessageStore-backed Message Channel, you can have buffering and transactional behavior without having to rely on additional middleware. You would need to use a MessageStore implementation that supports transactional persistence, but there’s a lot of flexibility. We provide a JDBC implementation as well as DDL for a number of common RDBMSs, and we have already prototyped a GemFire-based implementation. This is an area where you can expect to see a huge increase in the options as the Spring Data projects continue to evolve. Another nice benefit of using shared storage is that multiple processes may be running with the same components. In other words, you might distribute a Scatter Gather configuration (using Splitters, Aggregators, and some components in between), but as long as those Aggregators are each sharing the same MessageStore, the workload can be distributed.

<int-jdbc:message-store id=“messageStore” data-source=“dataSource”/>

Claim Check

The idea behind the Claim Check pattern is that you can exchange a Message payload for a “claim ticket” and vice-versa. This allows you to reduce bandwidth and/or avoid potential security issues when sending Messages across channels. You can think of this as “pass-by-reference” as opposed to the typical “pass-by-value” semantics. Our implementation is built directly upon the Message Store support that we just mentioned above. A pair of “claim-check-in” and “claim-check-out” transformers should share a reference to the same Message Store. For convenience, a single bean named “messageStore” will be considered first. You can provide an explicit reference via the ‘message-store’ attribute if necessary.

Control Bus

The Control Bus allows you to use messaging to manage and monitor endpoints and channels. In fact, this is a fairly general purpose mechanism where you can send a Message whose payload is actually a SpEL expression to be evaluated against some component within your integration application. For example, you could send a payload of “@somePoller.stop()” to the Control Bus’ input channel. In order to enable this, simply add the element:

New Channel Adapters and Messaging Gateways

We have added several new Channel Adapters and Messaging Gateways in Spring Integration 2.0. Rather than providing example configurations of each of these here, for those which are already covered well in the documentation, I’ll simply provide a link to the relevant section from the Spring Integration Reference Manual.

JDBC
JMX
TCP/UDP
XMPP

There are a few others which will be covered in the GA reference, but I will provide a brief description and/or relevant links here. The FTP and SFTP adapters are covered in great detail in this recent blog by Josh Long.

We also added RSS/Atom Feed reading support. Here’s an example:

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

And everyone’s favorite: the Twitter adapter. We support inbound and outbound status updates as well as direct messages. Here’s a simple example. As you can see it enables the configuration of an OAuth-enabled Twitter Connection instance:

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

<twitter:twitter-connection id=“twitterConnection”
consumer-key=" t w i t t e r . o a u t h . c o n s u m e r K e y " c o n s u m e r − s e c r e t = " {twitter.oauth.consumerKey}" consumer-secret=" twitter.oauth.consumerKey"consumersecret="{twitter.oauth.consumerSecret}"
access-token=" t w i t t e r . o a u t h . a c c e s s T o k e n " a c c e s s − t o k e n − s e c r e t = " {twitter.oauth.accessToken}" access-token-secret=" twitter.oauth.accessToken"accesstokensecret="{twitter.oauth.accessTokenSecret}"/>

Other Additions
Dynamic Groovy Scripts

As with the SpEL examples shown above, you can actually use Groovy scripts for any transformer, filter, router, splitter, etc. The scripts can be extremely simple and can take advantage of the ‘payload’ and ‘headers’ being bound to the Scripts execution context at runtime. For example, the following Groovy script could be defined as ‘LengthRouter.groovy’:

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

Then, you could reference this from within a router element (or any other core element type). You can provide a ‘refresh-check-delay’ so that changes in the script will be picked up at runtime:

Of course, you can do much more than that in the Groovy script. Generally, the Groovy script option provides a nice middle ground between SpEL and POJOs.
Map Transformers

These symmetrical transformers convert payload objects to/from a Map where the keys in the Map can hold “flat” property paths via SpEL (e.g. ‘customer.address.city’).

JSON Transformers

These symmetrical transformers convert payload objects to/from JSON. They use the Jackson library, and the ‘object-mapper’ may be referenced if you need to customize the behavior.

Serialization Transformers

These symmetrical transformers convert payload objects to/from byte arrays. While not entirely new in 2.0, these transformers do now delegate to a new pair of strategy interfaces. The default strategy is standard Java serialization. However, you can opt to provide a ‘serializer’ (or ‘deserializer’ for the deserializing transformer) attribute value to reference any Serializer (or Deserializer) implementation. Those are new strategy interfaces available in Spring 3.0.5. These same strategies are used within the JDBC MessageStore as well as the TCP/UDP adapters. Once again, you can expect to see a lot of new implementations as the Spring Data projects evolve.

SpringSource Tool Suite Visual Editor

Finally, I just want to point out that there is an amazing new visual editor for Spring Integration included within the latest version of SpringSource Tool Suite. If you are not already using STS 2.5.0, you really should download it now! Here’s a screenshot of our “Cafe” sample in the STS visual editor:
Conclusion

As usual for me, what started as a “brief” blog turned into a bit of an epic. The great thing is that even this seemingly long list of features is really only scratching the surface of what Spring Integration 2.0 has to offer. Please do download RC1 and take it for a spin. As always, we are very much looking forward to community feedback. We hope you enjoy RC1, and with your contributions in the forum and issue tracker, we can make sure 2.0 GA is even better.

Thanks!
-Mark
comments powered by Disqus

translate:
翻译:

我们很高兴宣布Spring Integration 2.0的第一个候选版本!
下载|参考手册| JavaDoc
我想我会借此机会提供一个一般的“什么是新的?“向导。实际上,有太多的新功能和改进,无法在一篇文章中全部介绍,但我将重点介绍其中的一些亮点。随着2.0ga的发布,我们将发布更多的博客。目前,这篇文章基本上是基于上周我和奥列格在SpringOne上发表的一篇文章。该演示主要是演示驱动的,代码可以在我们的Git存储库中找到。
为了在这里提供一些结构,我将遍历多个类别的特性…
Spring3.0支持的增强功能
SpringIntegration2.0直接构建在Spring3.0之上。事实上,RC1版本是建立在上周刚刚发布的Spring 3.0.5之上的。在这里,我们将看到一些最值得注意的特性,这些特性是通过对底层框架的重大升级而实现的。
春季表达语言

 类似资料:

相关阅读

相关文章

相关问答