此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1! |
Spring Integration 2.1 增加了对 Java 版本 6 中引入的 JSR223 Scripting for Java 规范的支持。 它允许您使用以任何受支持的语言(包括 Ruby、JRuby、Groovy 和 Kotlin)编写的脚本来为各种集成组件提供逻辑,类似于 Spring Integration 中使用 Spring 表达式语言 (SpEL) 的方式。 有关 JSR223 的更多信息,请参阅文档。
您需要将此依赖项包含在项目中:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-scripting</artifactId>
<version>6.2.7-SNAPSHOT</version>
</dependency>
compile "org.springframework.integration:spring-integration-scripting:6.2.7-SNAPSHOT"
此外,还需要添加脚本引擎实现,例如 JRuby、Jython。
从版本 5.2 开始,Spring Integration 提供了 Kotlin Jsr223 支持。 您需要将此依赖项添加到您的项目中才能使其正常工作:
-
Maven
-
Gradle
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-scripting-jsr223</artifactId>
<scope>runtime</scope>
</dependency>
runtime 'org.jetbrains.kotlin:kotlin-scripting-jsr223'
各种 JSR223 语言实现已由第三方开发。 特定实现与 Spring Integration 的兼容性取决于它与规范的一致性以及实现者对规范的解释。 |
如果您打算使用 Groovy 作为脚本语言,我们建议您使用 Spring-Integration 的 Groovy 支持,因为它提供了特定于 Groovy 的附加功能。 但是,本节也是相关的。 |
各种 JSR223 语言实现已由第三方开发。 特定实现与 Spring Integration 的兼容性取决于它与规范的一致性以及实现者对规范的解释。 |
如果您打算使用 Groovy 作为脚本语言,我们建议您使用 Spring-Integration 的 Groovy 支持,因为它提供了特定于 Groovy 的附加功能。 但是,本节也是相关的。 |
脚本配置
根据集成要求的复杂性,脚本可以在 XML 配置中以 CDATA 形式内联提供,也可以作为对包含脚本的 Spring 资源的引用提供。
为了启用脚本支持,Spring Integration定义了一个 ,它将消息有效负载绑定到一个名为的变量,并将消息标头绑定到一个变量,两者都可以在脚本执行上下文中访问。
您需要做的就是编写一个使用这些变量的脚本。
以下一对示例显示了创建筛选器的示例配置:ScriptExecutingMessageProcessor
payload
headers
-
Java DSL
-
XML
@Bean
public IntegrationFlow scriptFilter() {
return f -> f.filter(Scripts.processor("some/path/to/ruby/script/RubyFilterTests.rb"));
}
...
@Bean
public Resource scriptResource() {
return new ByteArrayResource("headers.type == 'good'".getBytes());
}
@Bean
public IntegrationFlow scriptFilter() {
return f -> f.filter(Scripts.processor(scriptResource()).lang("groovy"));
}
<int:filter input-channel="referencedScriptInput">
<int-script:script location="some/path/to/ruby/script/RubyFilterTests.rb"/>
</int:filter>
<int:filter input-channel="inlineScriptInput">
<int-script:script lang="groovy">
<![CDATA[
return payload == 'good'
]]>
</int-script:script>
</int:filter>
如前面的示例所示,脚本可以内联包含,也可以通过引用资源位置(通过使用属性)来包含。
此外,该属性对应于语言名称(或其 JSR223 别名)。location
lang
其他支持脚本编写的 Spring Integration 端点元素包括 、 、 和 。
每种情况下的脚本配置都与上述相同(除了 endpoint 元素)。router
service-activator
transformer
splitter
脚本支持的另一个有用功能是能够更新(重新加载)脚本,而无需重新启动应用程序上下文。
为此,请指定元素的属性,如以下示例所示:refresh-check-delay
script
-
Java DSL
-
XML
Scripts.processor(...).refreshCheckDelay(5000)
}
<int-script:script location="..." refresh-check-delay="5000"/>
在前面的示例中,每 5 秒检查一次脚本位置的更新。 如果脚本已更新,则自更新以来 5 秒内发生的任何调用都会导致运行新脚本。
请看以下示例:
-
Java DSL
-
XML
Scripts.processor(...).refreshCheckDelay(0)
}
<int-script:script location="..." refresh-check-delay="0"/>
在前面的示例中,一旦发生任何脚本修改,上下文就会立即更新,从而为“实时”配置提供了一种简单的机制。 任何负值都表示在初始化应用程序上下文后不会重新加载脚本。 这是默认行为。 以下示例显示了一个永不更新的脚本:
-
Java DSL
-
XML
Scripts.processor(...).refreshCheckDelay(-1)
}
<int-script:script location="..." refresh-check-delay="-1"/>
无法重新加载内联脚本。 |
脚本变量绑定
需要变量绑定才能使脚本能够引用外部提供给脚本执行上下文的变量。
默认情况下,和 用作绑定变量。
可以使用元素(或选项)将其他变量绑定到脚本,如以下示例所示:payload
headers
<variable>
ScriptSpec.variables()
-
Java DSL
-
XML
Scripts.processor("foo/bar/MyScript.py")
.variables(Map.of("var1", "thing1", "var2", "thing2", "date", date))
}
<script:script lang="py" location="foo/bar/MyScript.py">
<script:variable name="var1" value="thing1"/>
<script:variable name="var2" value="thing2"/>
<script:variable name="date" ref="date"/>
</script:script>
如前面的示例所示,您可以将脚本变量绑定到标量值或 Spring Bean 引用。
请注意,和 仍作为绑定变量包含在内。payload
headers
在 Spring Integration 3.0 中,除了元素之外,还引入了属性。
此属性和元素不是互斥的,您可以将它们组合在一个组件中。
但是,变量必须是唯一的,无论它们在哪里定义。
此外,从 Spring Integration 3.0 开始,内联脚本也允许变量绑定,如以下示例所示:variable
variables
variable
script
<service-activator input-channel="input">
<script:script lang="ruby" variables="thing1=THING1, date-ref=dateBean">
<script:variable name="thing2" ref="thing2Bean"/>
<script:variable name="thing3" value="thing2"/>
<![CDATA[
payload.foo = thing1
payload.date = date
payload.bar = thing2
payload.baz = thing3
payload
]]>
</script:script>
</service-activator>
前面的示例显示了内联脚本、元素和属性的组合。
该属性包含一个逗号分隔值,其中每个段都包含变量及其值的“=”分隔对。
变量名称可以用 作为后缀,如前面示例中的变量所示。
这意味着绑定变量的名称为 ,但该值是从应用程序上下文中对 Bean 的引用。
这在使用属性占位符配置或命令行参数时可能很有用。variable
variables
variables
-ref
date-ref
date
dateBean
如果需要更好地控制变量的生成方式,可以实现自己的 Java 类,该类使用该策略,该策略由以下接口定义:ScriptVariableGenerator
public interface ScriptVariableGenerator {
Map<String, Object> generateScriptVariables(Message<?> message);
}
此接口要求您实现该方法。
message 参数允许您访问消息负载和标头中的任何可用数据,返回值是绑定变量。
每次为消息执行脚本时,都会调用此方法。
下面的示例演示如何提供该属性的实现并引用该实现:generateScriptVariables(Message)
Map
ScriptVariableGenerator
script-variable-generator
-
Java DSL
-
XML
Scripts.processor("foo/bar/MyScript.groovy")
.variableGenerator(new foo.bar.MyScriptVariableGenerator())
}
<int-script:script location="foo/bar/MyScript.groovy"
script-variable-generator="variableGenerator"/>
<bean id="variableGenerator" class="foo.bar.MyScriptVariableGenerator"/>
如果未提供 a,则脚本组件使用 ,它将任何提供的元素与 in its 方法中的变量合并。script-variable-generator
DefaultScriptVariableGenerator
<variable>
payload
headers
Message
generateScriptVariables(Message)
不能同时提供属性和元素。
它们是相互排斥的。script-variable-generator <variable> |
GraalVM 多语言
从版本 6.0 开始,该框架提供了一个基于 GraalVM Polyglot API 的 API。
JavaScript 的 JSR223 引擎实现(从 Java 中删除)已被使用这个新的脚本执行器所取代。
请参阅有关在 GraalVM 中启用 JavaScript 支持以及哪些配置选项可以通过脚本变量传播的详细信息。
默认情况下,框架设置为在共享的 Polyglot 上,这支持与主机 JVM 的这种交互:PolyglotScriptExecutor
allowAllAccess
true
Context
-
新线程的创建和使用。
-
对公共主机类的访问。
-
通过向类路径添加条目来加载新的主机类。
-
将新成员导出到多语言绑定中。
-
主机系统上不受限制的 IO 操作。
-
传递实验选项。
-
创建和使用新的子流程。
-
对进程环境变量的访问。
这可以通过重载构造函数进行自定义,该构造函数接受 .PolyglotScriptExecutor
org.graalvm.polyglot.Context.Builder
要启用此 JavaScript 支持,必须使用安装了组件的 GraalVM,或者在使用常规 JVM 时,必须包含 和 依赖项。js
org.graalvm.sdk:graal-sdk
org.graalvm.js:js
无法重新加载内联脚本。 |
不能同时提供属性和元素。
它们是相互排斥的。script-variable-generator <variable> |