Spring Expression Language (SpEL)
您可以使用以 Spring Expression Language 编写的表达式来配置许多 Spring Integration 组件。
在大多数情况下,#root
对象是 Message
,它具有两个属性(headers
和 payload
),允许使用类似于 payload
、payload.thing
、headers['my.header']
等表达式的表达式。
在某些情况下会提供附加变量。例如,<int-http:inbound-gateway/>
提供 #requestParams
(来自 HTTP 请求的参数)和 #pathVariables
(URI 中路径占位符中的值)。
对于所有 SpEL 表达式,BeanResolver
都可用于启用对应用程序上下文中任何 bean 的引用(例如,@myBean.foo(payload)
)。此外,还可以使用两个 PropertyAccessors
。MapAccessor
可以使用键来访问 Map
中的值,而 ReflectivePropertyAccessor
则允许访问字段和 JavaBean 兼容属性(通过使用 getter 和 setter)。以下是访问 Message
标头和 payload 属性的方式。
SpEL Evaluation Context Customization
从 Spring Integration 3.0 开始,您可以将附加的 PropertyAccessor
实例添加到框架使用的 SpEL 求值上下文中。该框架提供了(只读)JsonPropertyAccessor
,您可以使用它来访问 JsonNode
或 String
中的字段。您还可以在有特定需求时创建自己的 PropertyAccessor
。
此外,您还可以添加自定义函数。自定义函数是声明在一个类上的 static
方法。函数和属性访问器在整个框架中使用的任何 SpEL 表达式中都可用。
以下配置显示了如何使用自定义属性访问器和函数直接配置 IntegrationEvaluationContextFactoryBean
:
<bean id="integrationEvaluationContext"
class="org.springframework.integration.config.IntegrationEvaluationContextFactoryBean">
<property name="propertyAccessors">
<util:map>
<entry key="things">
<bean class="things.MyCustomPropertyAccessor"/>
</entry>
</util:map>
</property>
<property name="functions">
<map>
<entry key="barcalc" value="#{T(things.MyFunctions).getMethod('calc', T(things.MyThing))}"/>
</map>
</property>
</bean>
为了方便起见,Spring Integration 为属性访问器和函数提供命名空间支持,如以下部分中所述。该框架会自动为您配置工厂 bean。
此工厂 Bean 定义将覆盖默认的“@44”Bean 定义。它将在列表中添加自定义访问器和一个自定义函数(包括标准访问器“@45”)。
请注意,自定义函数是静态方法。在前面的示例中,自定义函数是一个名为 calc
的静态方法,位于名为 MyFunctions
的类上,并接受一个类型为 MyThing
的参数。
假设您有一个 payload 类型为 MyThing
的 Message
。此外,假设您需要执行一些操作来从 MyThing
创建一个名为 MyObject
的对象,然后调用该对象上的一个名为 calc
的自定义函数。
标准属性访问器不知道如何从 MyThing
中获取 MyObject
,因此您可以编写并配置一个自定义属性访问器来执行此操作。因此,您的最终表达式可能是 "#barcalc(payload.myObject)"
。
工厂 bean 有另一个属性 (typeLocator
),它允许您自定义在 SpEL 求值期间使用的 TypeLocator
。您可能需要在使用非标准 ClassLoader
的某些环境中运行时进行此操作。在以下示例中,SpEL 表达式始终使用 bean 工厂的类加载器:
<bean id="integrationEvaluationContext"
class="org.springframework.integration.config.IntegrationEvaluationContextFactoryBean">
<property name="typeLocator">
<bean class="org.springframework.expression.spel.support.StandardTypeLocator">
<constructor-arg value="#{beanFactory.beanClassLoader}"/>
</bean>
</property>
</bean>
SpEL Functions
Spring Integration 提供命名空间支持,以便你可以创建 SpEL 自定义函数。你可以指定 <spel-function/>
组件,以便向整个框架中使用的 EvaluationContext
提供 custom SpEL functions 。你可以添加一个或多个此类组件,而不是配置之前所示的工厂 bean,且框架会自动将它们添加到默认 integrationEvaluationContext
工厂 bean 中。
例如,假设您有一个有用的静态方法来评估 XPath。以下示例显示了如何创建一个自定义函数来使用该方法:
<int:spel-function id="xpath"
class="com.something.test.XPathUtils" method="evaluate(java.lang.String, java.lang.Object)"/>
<int:transformer input-channel="in" output-channel="out"
expression="#xpath('//things/@mythings', payload)" />
给定前面的示例:
-
默认 “
IntegrationEvaluationContextFactoryBean
” bean(ID 为 “integrationEvaluationContext
”)将使用应用程序上下文注册。 -
解析 “
<spel-function/>
” 并在作为映射输入项,并将它的 “id
” 作为键,静态 “Method
” 作为值,添加到 “functions
” “Map
” 的 “integrationEvaluationContext
” 中。 -
“
integrationEvaluationContext
” 工厂 Bean 创建一个新的 “StandardEvaluationContext
” 实例,使用默认 “PropertyAccessor
” 实例、“BeanResolver
” 和自定义函数对其进行配置。 -
该 “
EvaluationContext
” 将注入到 “ExpressionEvaluatingTransformer
” bean 中。
要使用 Java 配置提供 SpEL 函数,您可以为每个函数声明一个 SpelFunctionFactoryBean
bean。以下示例显示了如何创建一个自定义函数:
@Bean
public SpelFunctionFactoryBean xpath() {
return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
}
在父上下文中声明的 SpEL 函数也可在任何子上下文中使用。每个上下文都有其自己的 |
Built-in SpEL Functions
Spring Integration 提供了以下标准函数,这些函数会在启动时自动注册到应用程序上下文中:
-
“
#jsonPath
”:在指定对象上评估一个 “jsonPath”。此函数调用 “JsonPathUtils.evaluate(…​)
”,它委托给 “ Jayway JsonPath library”。以下清单显示一些用法示例:[source, xml]
<transformer expression="#jsonPath(payload, '$.store.book[0].author')"/> <filter expression="#jsonPath(payload,'$..book[2].isbn') matches '\d-\d{3}-\d{5}-\d'"/> <splitter expression="#jsonPath(payload, '$.store.book')"/> <router expression="#jsonPath(payload, headers.jsonPath)"> <mapping channel="output1" value="reference"/> <mapping channel="output2" value="fiction"/> </router>
#jsonPath
还支持第三个(可选)参数:由对 bean 或 bean 方法(例如)引用提供的 com.jayway.jsonpath.Filter
数组。
使用此函数需要类路径上有 Jayway JsonPath 库 ( |
有关 JSON 的更多信息,请参阅 Transformer 中的“JSON Transformer”,
* “#xpath
”:在提供的对象上评估一个 xpath。有关 XML 和 XPath 的详细信息,请参阅 “XML Support - Dealing with XML Payloads”。
Property Accessors
Spring Integration 提供命名空间支持,以便你可以创建 SpEL 自定义 PropertyAccessor
实现。你可以使用 <spel-property-accessors/>
组件,以便向整个框架中使用的 EvaluationContext
提供自定义 PropertyAccessor
实例列表。你可以添加一个或多个此类组件,而不是配置之前所示的工厂 bean,且框架会自动将访问器添加到默认 integrationEvaluationContext
工厂 bean 中。以下示例演示如何执行此操作:
<int:spel-property-accessors>
<bean id="jsonPA" class="org.springframework.integration.json.JsonPropertyAccessor"/>
<ref bean="fooPropertyAccessor"/>
</int:spel-property-accessors>
在前面的示例中,将两个自定义 PropertyAccessor
实例注入到 EvaluationContext
中(按声明的顺序)。
要使用 Java 配置来提供 PropertyAccessor
实例,你应声明一个 SpelPropertyAccessorRegistrar
Bean,名称为 spelPropertyAccessorRegistrar
(由 IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME
常量决定)。以下示例展示了如何使用 Java 配置两个自定义 PropertyAccessor
实例:
@Bean
public SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
return new SpelPropertyAccessorRegistrar(new JsonPropertyAccessor())
.add(fooPropertyAccessor());
}
在父上下文中声明的自定义
|