Spring Integration Java DSL示例
现在已经为Spring Integration引入了新的 基于Java的DSL,这使得可以使用基于纯Java的配置而不是基于Spring XML的配置来定义Spring Integration消息流。
我尝试使用DSL来获得一个示例集成流-我称其为 Rube Goldberg流,因为它在尝试大写作为输入传递的字符串时遵循复杂的路径。该流程如下所示,并做了一些疯狂的事情来执行简单的任务:
- 它接收这种类型的消息-“来自spring integ的问候”
- 将其拆分为单个词(您好,来自,春天,完整)
- 将每个单词发送到ActiveMQ队列
- 从队列中,单词片段由浓缩器拾取以大写每个单词
- 将响应放回响应队列
- 根据单词的原始顺序对其进行拾取,重新排序
- 聚合成一个句子(“ HELLO FROM SPRING INTEG”),
- 返回到应用程序。
从Spring Integration Java DSL开始,一个简单的基于Xml的配置将大写的String变为:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333"><channel id =“ requestChannel” />
<gateway id =“ echoGateway” service-interface =“ rube.simple.EchoGateway” default-request-channel =“ requestChannel” />
<transformer input-channel =“ requestChannel” expression =“ payload.toUpperCase()” /> </span></span></span>
这里没有什么大不了的事,消息传递网关接收从应用程序传递来的消息,在转换器中将其大写,然后将其返回给应用程序。
在Spring Integration Java DSL中表达这一点:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333">@组态
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
公共类EchoFlow {
@豆
公共DirectChannel requestChannel(){
返回新的DirectChannel();
}
@豆
公共IntegrationFlow simpleEchoFlow(){
返回IntegrationFlows.from(requestChannel())
.transform((String s)-> s.toUpperCase())
。得到();
}
}
@MessagingGateway
公共接口EchoGateway {
@Gateway(requestChannel =“ requestChannel”)
字符串回显(字符串消息);
}</span></span></span>
请注意,@MessagingGateway批注不是Spring Integration Java DSL的一部分,它是Spring Integration中的现有组件,其作用与基于XML的配置中的网关组件相同。我喜欢这样的事实,即可以使用类型安全的Java 8 lambda表达式而不是Spring-EL表达式来表示转换。请注意,转换表达式可以用很少的其他方式进行编码:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333">??。transform((String s)-> s.toUpperCase())</span></span></span>
要么:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333"><String,String> transform(s-> s.toUpperCase())</span></span></span>
或使用方法引用:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333"><String,String> transform(String :: toUpperCase)</span></span></span>
再次从基于XML的配置开始,移至更复杂的Rube Goldberg流以完成相同的任务。有两种配置来表达此流程:
rube-1.xml:此配置负责步骤1、2、3、6、7、8:
- 它接收这种类型的消息-“来自spring integ的问候”
- 将其拆分为单个词(您好,来自,春天,完整)
- 将每个单词发送到ActiveMQ队列
- 从队列中,单词片段由浓缩器拾取以大写每个单词
- 将响应放回响应队列
- 根据单词的原始顺序对其进行拾取,重新排序
- 聚合成一个句子(“ HELLO FROM SPRING INTEG”),
- 返回到应用程序。
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333"><channel id =“ requestChannel” />
<!-步骤1,8->
<gateway id =“ echoGateway” service-interface =“ rube.complicated.EchoGateway” default-request-channel =“ requestChannel”
default-reply-timeout =“ 5000” />
<channel id =“ toJmsOutbound” />
<!-步骤2->
<splitter input-channel =“ requestChannel” output-channel =“ toJmsOutbound” expression =“ payload.split('\ s')”
apply-sequence =“ true” />
<channel id =“ sequenceChannel” />
<!-步骤3->
<int-jms:outbound-gateway request-channel =“ toJmsOutbound” Reply-channel =“ sequenceChannel”
request-destination =“ amq.outbound” extract-request-payload =“ true” />
<!-从队列返回的路上->
<channel id =“ aggregateChannel” />
<!-步骤6->
<resequencer input-channel =“ sequenceChannel” output-channel =“ aggregateChannel” release-partial-sequences =“ false” />
<!-步骤7->
<aggregator input-channel =“ aggregateChannel”
expression =“ T(com.google.common.base.Joiner).on('').join(![有效载荷])” /></span></span></span>
和rube-2.xml用于步骤4、5:
- 它接收这种类型的消息-“来自spring integ的问候”
- 将其拆分为单个词(您好,来自,春天,完整)
- 将每个单词发送到ActiveMQ队列
- 从队列中,单词片段由浓缩器拾取以大写每个单词
- 将响应放回响应队列
- 根据单词的原始顺序对其进行拾取,重新排序
- 聚合成一个句子(“ HELLO FROM SPRING INTEG”),
- 返回到应用程序。
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333"><channel id =“ enhanceMessageChannel” />
<int-jms:inbound-gateway request-channel =“ enhanceMessageChannel” request-destination =“ amq.outbound” />
<transformer input-channel =“ enhanceMessageChannel” expression =“(payload +'').toUpperCase()” /></span></span></span>
现在,使用Spring Integration Java DSL表示此Rube Goldberg流,其配置看起来又分为两部分:
EchoFlowOutbound.java:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333">@豆
公共DirectChannel sequenceChannel(){
返回新的DirectChannel();
}
@豆
公共DirectChannel requestChannel(){
返回新的DirectChannel();
}
@豆
public IntegrationFlow toOutboundQueueFlow(){
返回IntegrationFlows.from(requestChannel())
.split(s-> s.applySequence(true).get()。getT2()。setDelimiters(“ \\ s”))
.handle(jmsOutboundGateway())
。得到();
}
@豆
公共IntegrationFlow flowOnReturnOfMessage(){
返回IntegrationFlows.from(sequenceChannel())
.resequence()
.aggregate(聚合->
Aggregate.outputProcessor(g->
Joiner.on(“”).join(g.getMessages()
。流()
.map(m->(String)m.getPayload())。collect(toList())))
, 空值)
。得到();
}</span></span></span>
和EchoFlowInbound.java:
<span style="color:#333333"><span style="color:#222635"><span style="color:#333333">@豆
公共JmsMessageDrivenEndpoint jmsInbound(){
返回新的JmsMessageDrivenEndpoint(listenerContainer(),messageListener());
}
@豆
公共IntegrationFlow inboundFlow(){
返回IntegrationFlows.from(enhanceMessageChannel())
.transform((String s)-> s.toUpperCase())
。得到();
}</span></span></span>
同样,这里的代码是完全类型安全的,并且在开发时而不是在运行时(如基于XML的配置)检查任何错误。我再次喜欢这样一个事实,即转换,聚合语句可以使用Java 8 lamda表达式而不是Spring-EL表达式来简洁地表达。
我在这里未显示的是一些支持代码,用于设置 activemq测试基础结构,该配置继续保留为xml,我已将此代码包含在示例github项目中。
总而言之,我很高兴看到这种使用纯Java来表达Spring Integration消息流的新方式,并且我期待看到它的持续发展,甚至可能尝试以小方式参与其发展。
这是github存储库中的整个工作代码 :https : //github.com/bijukunjummen/rg-si
参考和确认:
- Spring集成的Java DSL 推出博客文章 由 阿尔乔姆比兰:https://spring.io/blog/2014/05/08/spring-integration-java-dsl-milestone-1-released
- Spring Integration Java DSL 网站和Wiki:https : //github.com/spring-projects/spring-integration-extensions/wiki/Spring-Integration-Java-DSL-Reference。我从这个Wiki无耻地复制了很多代码:-)。另外,非常感谢 Artem 对我提出的问题的指导
- Gary Russell 在Spring Integration 4.0上的网络研讨会 ,其中详细介绍了Spring Integration Java DSL。