Groovy 支持
在 Spring Integration 2.0 中,我们添加了 Groovy 支持,让你可以使用 Groovy 脚本语言为各种集成组件提供逻辑——类似于 Spring 表达式语言 (SpEL) 支持路由、转换和其他集成问题的方式。有关 Groovy 的更多信息,请参阅 Groovy 文档,你可以在 项目网站 上找到它。
你需要将此依赖项包含到你的项目中
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-groovy</artifactId>
<version>6.3.0</version>
</dependency>
compile "org.springframework.integration:spring-integration-groovy:6.3.0"
此外,从 6.0 版本开始,提供了一个 Groovy DSL 用于集成流配置。
Groovy 配置
在 Spring Integration 2.1 中,Groovy 支持的配置命名空间是 Spring Integration 脚本支持的扩展,并且共享在 脚本支持 部分中详细描述的核心配置和行为。即使通用脚本支持很好地支持 Groovy 脚本,Groovy 支持也提供了 Groovy
配置命名空间,该命名空间由 Spring Framework 的 org.springframework.scripting.groovy.GroovyScriptFactory
和相关组件支持,为使用 Groovy 提供了扩展功能。以下清单显示了两个示例配置
<int:filter input-channel="referencedScriptInput">
<int-groovy:script location="some/path/to/groovy/file/GroovyFilterTests.groovy"/>
</int:filter>
<int:filter input-channel="inlineScriptInput">
<int-groovy:script><![CDATA[
return payload == 'good'
]]></int-groovy:script>
</int:filter>
如前面的示例所示,配置看起来与通用脚本支持配置相同。唯一的区别是使用 Groovy 命名空间,如 int-groovy
命名空间前缀所示。另请注意,在此命名空间中 <script>
标记上的 lang
属性无效。
Groovy 对象自定义
如果您需要自定义 Groovy 对象本身(超出设置变量),您可以通过使用 customizer
属性引用实现 GroovyObjectCustomizer
的 bean。例如,如果您想通过修改 MetaClass
并注册可在脚本中使用的函数来实现特定于领域的语言 (DSL),这可能很有用。以下示例演示了如何执行此操作
<int:service-activator input-channel="groovyChannel">
<int-groovy:script location="somewhere/SomeScript.groovy" customizer="groovyCustomizer"/>
</int:service-activator>
<beans:bean id="groovyCustomizer" class="org.something.MyGroovyObjectCustomizer"/>
设置自定义 GroovyObjectCustomizer
与 <variable>
元素或 script-variable-generator
属性并不相互排斥。在定义内联脚本时也可以提供它。
Spring Integration 3.0 引入了 variables
属性,该属性与 variable
元素结合使用。此外,如果未提供具有名称的绑定变量,则 groovy 脚本能够将变量解析为 BeanFactory
中的 bean。以下示例演示了如何使用变量 (entityManager
)
<int-groovy:script>
<![CDATA[
entityManager.persist(payload)
payload
]]>
</int-groovy:script>
entityManager
必须是应用程序上下文中适当的 bean。
有关 <variable>
元素、variables
属性和 script-variable-generator
属性的更多信息,请参阅 脚本变量绑定。
Groovy 脚本编译器自定义
@CompileStatic
提示是最流行的 Groovy 编译器自定义选项。它可以在类或方法级别使用。有关更多信息,请参阅 Groovy 参考手册,具体来说,请参阅 @CompileStatic。要将此功能用于短脚本(在集成场景中),我们被迫将简单的脚本更改为更类似 Java 的代码。考虑以下 <filter>
脚本
headers.type == 'good'
前面的脚本在 Spring Integration 中变为以下方法
@groovy.transform.CompileStatic
String filter(Map headers) {
headers.type == 'good'
}
filter(headers)
这样,filter()
方法就会被转换并编译为静态 Java 代码,绕过 Groovy 的动态调用阶段,如 getProperty()
工厂和 CallSite
代理。
从 4.3 版本开始,您可以使用 compile-static
boolean
选项配置 Spring Integration Groovy 组件,指定应将 @CompileStatic
的 ASTTransformationCustomizer
添加到内部 CompilerConfiguration
。有了它,您就可以在脚本代码中省略带有 @CompileStatic
的方法声明,仍然可以获取已编译的纯 Java 代码。在这种情况下,前面的脚本可以很短,但仍然需要比解释脚本更冗长,如下例所示
binding.variables.headers.type == 'good'
您必须通过 groovy.lang.Script
binding
属性访问 headers
和 payload
(或任何其他)变量,因为使用 @CompileStatic
时,我们没有动态 GroovyObject.getProperty()
功能。
此外,我们还引入了 compiler-configuration
bean 引用。使用此属性,您可以提供任何其他必需的 Groovy 编译器自定义项,如 ImportCustomizer
。有关此功能的更多信息,请参阅 Groovy 文档,了解 高级编译器配置。
使用 compilerConfiguration 不会自动为 @CompileStatic 注解添加 ASTTransformationCustomizer ,并且它会覆盖 compileStatic 选项。如果您仍然需要 CompileStatic ,则应手动将 new ASTTransformationCustomizer(CompileStatic.class) 添加到该自定义 compilerConfiguration 的 CompilationCustomizers 中。
|
Groovy 编译器自定义对 refresh-check-delay 选项没有任何影响,并且可重新加载的脚本也可以静态编译。
|
控制总线
如 (企业集成模式) 中所述,控制总线背后的理念是,您可以使用与“应用程序级”消息传递相同的邮件系统来监视和管理框架内的组件。在 Spring Integration 中,我们基于前面描述的适配器构建,以便您可以发送消息作为调用公开操作的一种方式。这些操作的一个选项是 Groovy 脚本。以下示例为控制总线配置了一个 Groovy 脚本
<int-groovy:control-bus input-channel="operationChannel"/>
控制总线有一个输入通道,可通过该通道访问应用程序上下文中 bean 上的操作。
Groovy 控制总线将输入通道上的消息作为 Groovy 脚本运行。它接收一条消息,将正文编译为脚本,使用 `GroovyObjectCustomizer` 对其进行自定义,然后运行它。控制总线的 `MessageProcessor` 公开了应用程序上下文中所有使用 `@ManagedResource` 注释并实现了 Spring 的 `Lifecycle` 接口或扩展了 Spring 的 `CustomizableThreadCreator` 基类(例如,一些 `TaskExecutor` 和 `TaskScheduler` 实现)的 bean。
在控制总线的命令脚本中使用具有自定义范围(例如“请求”)的受管 bean 时要小心,尤其是在异步消息流中。如果控制总线的 `MessageProcessor` 无法公开应用程序上下文中的 bean,则在命令脚本运行期间可能会遇到一些 `BeansException`。例如,如果未建立自定义范围的上下文,则尝试获取该范围内的 bean 会触发 `BeanCreationException`。 |
如果您需要进一步自定义 Groovy 对象,还可以提供对实现 `GroovyObjectCustomizer` 的 bean 的引用,方法是通过 `customizer` 属性,如下例所示
<int-groovy:control-bus input-channel="input"
output-channel="output"
customizer="groovyCustomizer"/>
<beans:bean id="groovyCustomizer" class="org.foo.MyGroovyObjectCustomizer"/>