Spring 表达式语言 (SpEL)

春季表达式语言(SpEL)

您可以通过使用 Spring 表达式语言编写的表达式来配置许多 Spring 集成组件。spring-doc.cadn.net.cn

在大多数情况下,#root对象是消息,具有两个性质(有效载荷)允许以下表达式有效载荷,payload.thing,头['my.header'],依此类推。spring-doc.cadn.net.cn

在某些情况下,还会提供额外的变量。 例如<int-http:inbound-gateway/>提供#requestParams(来自HTTP请求的参数)和#pathVariables(来自URI路径占位符的值)。spring-doc.cadn.net.cn

对于所有 SpEL 表达式,a豆解决器可用来在应用上下文中引用任意豆子(例如,@myBean.foo(有效载荷)). 此外,还有两个PropertyAccessors是可用的。 一个地图访问器使访问 A 中的值成为可能地图通过使用密钥和ReflectivePropertyAccessor,允许访问字段和符合 JavaBean 的属性(通过使用获取器和设置器)。 这就是你如何访问消息负责任务的报头和有效载荷属性。spring-doc.cadn.net.cn

SpEL 评估上下文定制

从 Spring Integration 3.0 开始,你可以添加更多PropertyAccessor这些实例被框架使用的 SpEL 评估上下文。 该框架提供(只读)JsonPropertyAccessor你可以用它从一个JsonNode或 JSON 中的字符串. 你也可以自己创建PropertyAccessor如果你有具体需求。spring-doc.cadn.net.cn

此外,你还可以添加自定义函数。 自定义函数包括静态的方法在类上宣告。 函数和属性访问器可在框架中使用的任何 SpEL 表达式中提供。spring-doc.cadn.net.cn

以下配置展示了如何直接配置集成评估上下文工厂豆使用自定义属性访问器和函数:spring-doc.cadn.net.cn

<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 为属性访问器和函数提供命名空间支持,具体内容见以下章节。 该框架会自动代表你配置工厂豆。spring-doc.cadn.net.cn

该工厂豆定义覆盖默认integration评估上下文豆子的定义。 它将自定义访问器和一个自定义功能添加到列表中(该函数还包括前面提到的标准访问器)。spring-doc.cadn.net.cn

注意自定义函数是静态方法。 在前面的例子中,自定义函数是一个静态方法,称为微积分在一个名为我的功能并取一个类型的单一参数我的事.spring-doc.cadn.net.cn

假设你有一个消息其中有效载荷具有我的事. 此外,假设你需要执行某个动作来创建一个名为我的对象我的事然后调用一个名为微积分在那个物体上。spring-doc.cadn.net.cn

标准的房产配件不知道如何获得我的对象来自我的事所以你可以写一个自定义属性访问器来实现这一点。 因此,你的最终表达可能是“#barcalc(payload.myObject)”.spring-doc.cadn.net.cn

工厂豆还有另一个性质(typeLocator),这可以让你自定义TypeLocator用于SpEL评估。 你可能需要在某些使用非标准环境下运行时进行ClassLoader. 在以下示例中,SpEL 表达式始终使用豆子工厂的类加载器:spring-doc.cadn.net.cn

<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/>组件为评价背景整个框架都被使用。 你不必配置之前显示的出厂豆,而是添加一个或多个这些组件,框架会自动将它们添加到默认状态integration评估上下文工厂豆。spring-doc.cadn.net.cn

例如,假设你有一个有用的静态方法来评估XPath。 以下示例展示了如何创建自定义函数来使用该方法:spring-doc.cadn.net.cn

<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)" />

给定上述例子:spring-doc.cadn.net.cn

  • 默认集成评估上下文工厂豆具有 ID 的豆子integration评估上下文注册在应用上下文中。spring-doc.cadn.net.cn

  • <spel-function/>被解析并添加到功能 地图integration评估上下文作为一个映射条目,其身份证作为钥匙和静电方法作为价值。spring-doc.cadn.net.cn

  • integration评估上下文工厂豆子创造了新的标准评估上下文实例,并且它配置为默认PropertyAccessor实例,a豆解决器, 以及自定义函数。spring-doc.cadn.net.cn

  • 评价背景实例被注入到ExpressionEvaluatingTransformer豆。spring-doc.cadn.net.cn

要通过 Java 配置提供 SpEL 函数,你可以声明SpelFunctionFactoryBean每个功能都有豆子。 以下示例展示了如何创建自定义函数:spring-doc.cadn.net.cn

@Bean
public SpelFunctionFactoryBean xpath() {
    return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
}
在父上下文中声明的 SpEL 函数也可在任何子上下文中使用。 每个上下文都有其独特的实例integration评估上下文工厂豆,因为每种豆子需要的都不一样豆解决器但函数声明是继承的,可以通过声明同名的 SpEL 函数来覆盖。

内置的 SpEL 函数

Spring Integration 提供了 follolng 标准功能,这些功能在启动时会自动注册到应用上下文中:spring-doc.cadn.net.cn

  • #jsonPath: 对指定对象进行“jsonPath”的评估。 该函数调用JsonPathUtils.evaluate(...),该库委托给Jayway JsonPath库。 以下列表展示了一些使用示例:spring-doc.cadn.net.cn

    <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,可以通过引用豆子或豆子方法(例如)来提供。spring-doc.cadn.net.cn

    使用此函数需要使用 Jayway JsonPath 库 (json-path.jar)进入阶级路径。 否则,#jsonPathSpEL函数未被注册。

    有关 JSON 的更多信息,请参见 Transformer 中的“JSON Transformers”。spring-doc.cadn.net.cn

  • #xpath: 以评估某个给定对象上的“xpath”。 有关XML和XPath的更多信息,请参见XML支持——处理XML有效载荷spring-doc.cadn.net.cn

财产配件

Spring Integration 提供命名空间支持,让你可以自定义创建 SpELPropertyAccessor实现。 你可以使用<spel-property-accessors/>组件以提供自定义列表PropertyAccessor实例评价背景整个框架都被使用。 你可以不用配置之前展示的出厂豆,而是添加一个或多个这些组件,框架会自动将这些访问器添加到默认状态integration评估上下文工厂豆。 以下示例展示了如何实现:spring-doc.cadn.net.cn

<int:spel-property-accessors>
	<bean id="jsonPA" class="org.springframework.integration.json.JsonPropertyAccessor"/>
	<ref bean="fooPropertyAccessor"/>
</int:spel-property-accessors>

在前面的例子中,两个自定义PropertyAccessor实例被注入到评价背景(按它们被宣布的顺序)。spring-doc.cadn.net.cn

提供PropertyAccessor通过使用 Java 配置,你应该声明一个SpelPropertyAccessorRegistrar名为spelPropertyAccessorRegistrar(由IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME恒定)。 以下示例展示了如何配置两个自定义PropertyAccessor使用 Java 的实例:spring-doc.cadn.net.cn

@Bean
public SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
    return new SpelPropertyAccessorRegistrar(new JsonPropertyAccessor())
                    .add(fooPropertyAccessor());
}

习惯PropertyAccessor在父上下文中声明的实例也会在任何子上下文中提供。 它们被放在结果列表的末尾(但在默认结果之前)org.springframework.context.expression.MapAccessoro.s.expression.spel.support.ReflectivePropertyAccessor). 如果你声明 aPropertyAccessor在子节点上下文中使用相同的 BEAN ID,它会覆盖父访问器。 豆子在<spel-property-accessors/>必须有“id”属性。 最终的使用顺序如下:spring-doc.cadn.net.cn