Spring 表达式语言 (SpEL)
Spring 表达式语言 (SpEL)
您可以使用以 Spring 表达式语言编写的表达式来配置许多 Spring 集成组件。
在大多数情况下,#root
object 是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
通过使用 key 和ReflectivePropertyAccessor
,它允许访问字段和符合 JavaBean 的属性(通过使用 getter 和 setter)。
这是您访问Message
headers 和 payload 属性。
SPEL 评估上下文自定义
从 Spring Integration 3.0 开始,您可以添加额外的PropertyAccessor
实例添加到框架使用的 SPEL 评估上下文中。
框架提供 (只读)JsonPropertyAccessor
,可用于访问JsonNode
或 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 集成为属性访问器和函数提供了名称空间支持,如以下各节所述。 框架将代表您自动配置工厂 Bean。
此工厂 Bean 定义将覆盖默认值integrationEvaluationContext
bean 定义。
它将自定义访问器和一个自定义函数添加到列表中(其中还包括前面提到的标准访问器)。
请注意,自定义函数是静态方法。
在前面的示例中,自定义函数是一个名为calc
在名为MyFunctions
并采用MyThing
.
假设您有一个Message
的有效负载类型为MyThing
.
此外,假设您需要执行一些作来创建一个名为MyObject
从MyThing
然后调用一个名为calc
在该对象上。
标准属性访问器不知道如何获取MyObject
从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 集成提供了名称空间支持,让您创建 SPEL 自定义函数。
您可以指定<spel-function/>
组件向EvaluationContext
在整个框架中使用。
你可以添加一个或多个这些组件,而不是配置前面显示的工厂 Bean,框架会自动将它们添加到默认组件中integrationEvaluationContext
工厂 Bean 的 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
ID 为integrationEvaluationContext
已注册到 Application Context。 -
这
<spel-function/>
被解析并添加到functions
Map
之integrationEvaluationContext
作为映射条目,其id
作为 key 和 staticMethod
作为值。 -
这
integrationEvaluationContext
Factory Bean 会创建一个新的StandardEvaluationContext
实例,并且它配置了默认的PropertyAccessor
实例、BeanResolver
和自定义函数。 -
那
EvaluationContext
实例被注入到ExpressionEvaluatingTransformer
豆。
要使用 Java 配置提供 SPEL 函数,您可以声明SpelFunctionFactoryBean
bean 的 bean 来获取。
以下示例显示如何创建自定义函数:
@Bean
public SpelFunctionFactoryBean xpath() {
return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
}
在父上下文中声明的 SPEL 函数也可以在任何子上下文中使用。
每个上下文都有自己的integrationEvaluationContext Factory Bean 中,因为每个 bean 都需要一个不同的BeanResolver ,但函数声明是继承的,可以通过声明具有相同名称的 SPEL 函数来覆盖。 |
内置 SPEL 函数
Spring 集成提供了以下标准函数,这些函数在启动时自动注册到应用程序上下文中:
-
#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
) 添加到 Classpath 上。 否则,#jsonPath
未注册 SPEL 函数。有关 JSON 的更多信息,请参阅 Transformer 中的“JSON 转换器”。
-
#xpath
:在某个提供的对象上评估 'xpath'。 有关 XML 和 XPath 的更多信息,请参见 XML 支持 - 处理 XML 负载。
属性访问器
Spring 集成提供名称空间支持,让您创建 SPEL 自定义PropertyAccessor
实现。
您可以使用<spel-property-accessors/>
组件来提供自定义PropertyAccessor
实例复制到EvaluationContext
在整个框架中使用。
你可以添加一个或多个组件,而不是配置前面显示的工厂 Bean,框架会自动将访问器添加到默认的integrationEvaluationContext
工厂 Bean 的 Bean 中。
以下示例显示了如何执行此作:
<int:spel-property-accessors>
<bean id="jsonPA" class="org.springframework.integration.json.JsonPropertyAccessor"/>
<ref bean="fooPropertyAccessor"/>
</int:spel-property-accessors>
在前面的示例中,两个自定义PropertyAccessor
实例被注入到EvaluationContext
(按声明的顺序)。
提供PropertyAccessor
实例,您应该声明一个SpelPropertyAccessorRegistrar
名称为spelPropertyAccessorRegistrar
(由IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME
常量)。
以下示例显示如何配置两个自定义PropertyAccessor
Java 实例:
@Bean
public SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
return new SpelPropertyAccessorRegistrar(new JsonPropertyAccessor())
.add(fooPropertyAccessor());
}
习惯
|