领先一步
VMware 提供培训和认证,以加快您的进度。
了解更多Spring Integration 的脚本支持在 2.1 版本中可用,它基于 2.0 版本中引入的 Groovy 脚本支持。如果您熟悉 Spring Integration,可以将脚本支持视为工具箱中的另一个工具,您会在某些情况下发现它很有用。如果您有使用 Groovy、Python、Ruby 或 Javascript 等语言编写的现有代码,并且需要将它们彼此集成或集成到 Java 应用程序中,Spring Integration 提供了一种简单的方法来实现这一点。无论哪种情况,这篇文章都介绍了使用您最喜欢的脚本语言与 Spring Integration 入门的基础知识。
<int:transformer input-channel="inChannel"
output-channel="outChannel"
expression="payload.toUpperCase() + '- [' + T(java.lang.System).currentTimeMillis() + ']'"/>
这是 Spring Integration 中的常见模式。许多开箱即用的端点都包含expression 属性,其内容被解释为对 Message 进行操作的 SpEL 表达式。
可以使用内联脚本(例如,用 Ruby 编写的脚本)完成相同的事情
<int:transformer input-channel="inChannel"
output-channel="outChannel">
<int-script:script lang="ruby">
"#{payload.upcase} -[#{Time.now.to_i}]"
</int-script:script>
</int:transformer>
请注意,脚本的主体包含在 Spring Integration 2.1 中引入的脚本命名空间中定义的script 标记内。lang 属性指定脚本语言(稍后将详细介绍)。与 SpEL 类似,消息有效负载和标头会自动绑定为脚本变量。
如果端点实现只需要一个表达式,如上例所示,大多数人会发现 SpEL 比内联脚本更方便。但是,正如我们将看到的,脚本在需要时提供了额外的功能和灵活性。
<router input-channel="inlineScriptInput">
<int-script:script lang="javascript"><![CDATA[
(function(){
return payload.length > 5 ? "longStrings" : "shortStrings";
})();
]]>
</int-script:script>
</router>
对于 Python 等语言,换行符和缩进是语法的一部分,这一点尤其重要。但是,您也可以使用location 属性引用外部脚本
<script:script lang="groovy" location="file:scripts/groovy/myscript.groovy">
与任何 Spring 资源一样,您可以在类路径、文件系统或 Web 应用程序上下文中指定位置。使用外部脚本可以打开一些额外的功能。首先,您可以提供自定义变量绑定以向脚本提供其他输入。这些可以是原始类型或 Spring bean
<int:service-activator ...>
<int-script:script language="python" location="authorizeCredit.py" refresh-check-delay="60">
<int-script:variable name="creditService" ref="creditService"/>
<int-script:variable name="maximumAmount" value="1000.00"/>
</int:script:script>
</int:service-activator>
<bean id="creditService" class="com.example.CreditService">
...
</bean>
外部脚本提供的另一个选项是能够在运行时定期更新脚本内容。例如,如果文件系统上的脚本已更新,应用程序上下文可以近乎实时地刷新脚本。要启用此功能,只需提供如上所示的可选refresh-check-delay 属性,并以秒为单位指定一个值。如果值为 0,则立即刷新。小于零的值将禁用刷新。
同样,Spring Integration 也不强制要求或认可任何特定的脚本语言。我们已经成功地使用上述语言测试了 spring-integration-scripting 模块,但是根据实现的细微差别,您的里程可能会有所不同。与其他 JSR 规范一样,合规性也存在解释上的差异。此外,每种语言实现都必须提供一种方法来从脚本环境导入和访问 Java 类。如何做到这一点不是 JSR223 规范的一部分。
例如,在将 Python 与 Spring Integration 一起使用时出现的一个小限制。执行脚本时,预期返回值将是脚本主体中最后执行表达式的值。许多面向对象的脚本语言支持“裸”脚本中的 return 语句。并且返回可能是隐式的或显式的('return'关键字是可选的)。让我们再来看一下第一个例子
<int:transformer input-channel="inChannel"
output-channel="outChannel">
<int-script:script lang="ruby">
"#{payload.upcase} -[#{Time.now.to_i}]"
</int-script:script>
</int:transformer>
脚本的主体是一个具有隐式返回的单个表达式。我们也可以使用显式返回
<int:transformer input-channel="inChannel"
output-channel="outChannel">
<int-script:script lang="ruby">
return "#{payload.upcase} -[#{Time.now.to_i}]"
</int-script:script>
</int:transformer>
或者将变量分配给表达式并返回变量
<int:transformer input-channel="inChannel"
output-channel="outChannel">
<int-script:script lang="ruby">
val = "#{payload.upcase} -[#{Time.now.to_i}]";
val
</int-script:script>
</int:transformer>
Python 的工作方式略有不同。首先,不支持隐式返回。此外,不允许在函数或方法之外使用 return 语句。裸表达式在 Python 中是有效的,但是该语言在表达式和语句之间做了一个细微的区分,这会影响 JSR233 实现。例如,如果您使用 engine.eval() 使用 JSR223 评估以下脚本,则会得到一个 null 返回值
def multiply(x,y):
return x*y
multiply(5,7)
相反,您必须将结果分配给一个变量,例如“answer”,并在 eval() 调用之后调用 engine.get("answer") 以获得预期的结果 35。
def multiply(x,y):
return x*y
answer = multiply(5,7)
Spring Integration 包含一个解决此限制的变通方法。如果脚本中的最后一条语句是变量赋值,它将解析变量名称并返回值 engine.get()。
在这方面的讨论中,我故意避免使用POJO 一词,而使用更通用的Spring bean。这指的是,即使没有任何 Spring 框架的帮助,也可以使用 Groovy 和 Scala 等语言实现 Spring bean。此外,核心 Spring 已经提供了动态语言支持,允许您例如在 JRuby 或 BeanShell 中实现 Spring bean。因此,即使没有 Spring Integration 的脚本支持,任何遵循适当约定的 Spring bean 都可以实现 Spring Integration 端点。
<int-groovy:script location="myScript.groovy">
<int-groovy:variable name="foo" value="foo"/>
<int-groovy:variable name="bar" value="bar"/>
<int-groovy:variable name="date" ref="date"/>
</int-groovy:script>
<int-script:script lang="groovy" location="myScript.groovy">
<int-script:variable name="foo" value="foo"/>
<int-script:variable name="bar" value="bar"/>
<int-script:variable name="date" ref="date"/>
</int-script:script>
如果您只对 Groovy 感兴趣,则本机支持是更好的选择。此外,Spring Integration 的 Groovy 支持包括 Groovy 控制总线,允许您使用 Groovy 脚本在运行时管理应用程序。