Spring 表达式语言 (SpEL)
您可以使用用Spring Expression Language编写的表达式来配置许多 Spring Integration 组件。
在大多数情况下,#root对象是Message,它有两个属性 (headers和),允许使用、、payload等表达式。payloadpayload.thingheaders['my.header']
在某些情况下,会提供额外的变量。例如,<int-http:inbound-gateway/>提供#requestParams(来自 HTTP 请求的参数)和#pathVariables(来自 URI 中路径占位符的值)。
对于所有 SpEL 表达式,aBeanResolver可用于启用对应用程序上下文中任何 bean 的引用(例如,@myBean.foo(payload))。此外,还有两个PropertyAccessors可用。AMapAccessor允许Map通过使用键和 a 来访问 a 中的值ReflectivePropertyAccessor,这允许访问字段和符合 JavaBean 的属性(通过使用 getter 和 setter)。这是您可以访问Message标头和有效负载属性的方式。
SpEL 评估上下文定制
从 Spring Integration 3.0 开始,您可以PropertyAccessor向框架使用的 SpEL 评估上下文添加其他实例。该框架提供 (read-only) JsonPropertyAccessor,您可以使用它来访问来自 aJsonNode或 JSON 中的字段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 定义覆盖了默认的integrationEvaluationContextbean 定义。它将自定义访问器和一个自定义函数添加到列表中(其中还包括前面提到的标准访问器)。
请注意,自定义函数是静态方法。在前面的示例中,自定义函数是在一个被调用calc的类上调用的静态方法,MyFunctions并接受一个类型为 的参数MyThing。
假设您有一个Message带有类型为MyThing. 进一步假设您需要执行一些操作来创建一个调用MyObjectfrom的对象MyThing,然后调用calc对该对象调用的自定义函数。
标准属性访问器不知道如何MyObject从 a 中获取 a MyThing,因此您可以编写和配置自定义属性访问器来执行此操作。因此,您的最终表达式可能是"#barcalc(payload.myObject)".
工厂 bean 有另一个属性 ( typeLocator),它允许您自定义TypeLocator在 SpEL 评估期间使用的。您可能需要在某些使用非标准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 函数
Spring Integration 提供命名空间支持,让您创建 SpEL 自定义函数。您可以指定<spel-function/>组件以向整个框架中使用的用户提供自定义 SpEL 功能。EvaluationContext您可以添加一个或多个这些组件,而不是配置前面显示的工厂 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)" />
鉴于前面的例子:
-
ID 为的默认
IntegrationEvaluationContextFactoryBeanbeanintegrationEvaluationContext在应用程序上下文中注册。 -
<spel-function/>解析并添加到functionsMapofintegrationEvaluationContext作为映射条目,其作为id键,静态Method作为值。 -
integrationEvaluationContext工厂 bean 创建一个新实例,并使用StandardEvaluationContext默认PropertyAccessor实例 aBeanResolver和自定义函数对其进行配置。 -
该
EvaluationContext实例被注入到ExpressionEvaluatingTransformerbean 中。
要使用 Java 配置提供 SpEL 函数,您可以SpelFunctionFactoryBean为每个函数声明一个 bean。以下示例显示了如何创建自定义函数:
@Bean
public SpelFunctionFactoryBean xpath() {
return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
}
在父上下文中声明的 SpEL 函数也可以在任何子上下文中使用。每个上下文都有自己的integrationEvaluationContext工厂 bean 实例,因为每个都需要不同的BeanResolver,但是函数声明是继承的,并且可以通过声明具有相同名称的 SpEL 函数来覆盖。
|
内置 SpEL 函数
Spring Integration 提供了以下标准函数,这些函数在启动时自动注册到应用程序上下文中:
-
#jsonPath:评估指定对象上的“jsonPath”。这个函数调用JsonPathUtils.evaluate(…),它委托给Jayway JsonPath 库。以下清单显示了一些使用示例:<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还支持第三个(可选)参数:一个数组com.jayway.jsonpath.Filter,可以通过对 bean 或 bean 方法的引用来提供(例如)。使用此函数需要 Jayway JsonPath 库 ( json-path.jar) 位于类路径中。否则,#jsonPathSpEL 函数未注册。有关 JSON 的更多信息,请参阅 Transformer 中的“JSON 转换器”。
-
#xpath:评估某个提供的对象上的“xpath”。有关 XML 和 XPath 的更多信息,请参阅XML 支持 - 处理 XML 有效负载。
属性访问器
Spring Integration 提供命名空间支持,让您创建 SpEL 自定义PropertyAccessor实现。您可以使用该组件为整个框架中使用的自定义实例<spel-property-accessors/>提供一个列表。您可以添加一个或多个这些组件,而不是配置前面显示的工厂 bean,框架会自动将访问器添加到默认工厂 bean。以下示例显示了如何执行此操作:PropertyAccessorEvaluationContextintegrationEvaluationContext
<int:spel-property-accessors>
<bean id="jsonPA" class="org.springframework.integration.json.JsonPropertyAccessor"/>
<ref bean="fooPropertyAccessor"/>
</int:spel-property-accessors>
在前面的示例中,将两个自定义PropertyAccessor实例注入EvaluationContext(按照它们的声明顺序)。
PropertyAccessor要使用 Java Configuration提供实例,您应该声明一个名称为(由常量决定)的SpelPropertyAccessorRegistrarbean 。以下示例显示了如何使用 Java 配置两个自定义实例:spelPropertyAccessorRegistrarIntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAMEPropertyAccessor
@Bean
public SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
return new SpelPropertyAccessorRegistrar(new JsonPropertyAccessor())
.add(fooPropertyAccessor());
}
|
在父上下文中声明的自定义
|