此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Integration 6.5.1spring-doc.cadn.net.cn

Spring 表达式语言 (SpEL)

您可以使用用 Spring Expression Language 编写的表达式来配置许多 Spring Integration 组件。spring-doc.cadn.net.cn

在大多数情况下,#rootobject 是Message,它有两个属性 (headerspayload),允许payload,payload.thing,headers['my.header'],依此类推。spring-doc.cadn.net.cn

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

对于所有 SpEL 表达式,一个BeanResolver可用于启用对应用程序上下文中任何 bean 的引用(例如,@myBean.foo(payload)). 此外,两个PropertyAccessors可用。 一个MapAccessor允许访问Map通过使用键和ReflectivePropertyAccessor,它允许访问字段和 JavaBean 兼容的属性(通过使用 getter 和 setter)。 这是访问Message标头和有效负载属性。spring-doc.cadn.net.cn

SpEL 评估上下文定制

从 Spring Integration 3.0 开始,您可以添加其他PropertyAccessor实例添加到框架使用的 SpEL 评估上下文。 该框架提供(只读)JsonPropertyAccessor,您可以使用它从JsonNode或 JSON 中的String. 您也可以创建自己的PropertyAccessor如果您有特定需求。spring-doc.cadn.net.cn

此外,您还可以添加自定义函数。 自定义函数是static在类上声明的方法。 函数和属性访问器在整个框架中使用的任何 SpEL 表达式中都可用。spring-doc.cadn.net.cn

以下配置展示了如何直接配置IntegrationEvaluationContextFactoryBean使用自定义属性访问器和函数: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为属性访问器和函数提供了命名空间支持,如以下部分所述。 该框架会代表您自动配置工厂 Bean。spring-doc.cadn.net.cn

此工厂 bean 定义将覆盖默认值integrationEvaluationContextbean 定义。 它将自定义访问器和一个自定义函数添加到列表中(其中还包括前面提到的标准访问器)。spring-doc.cadn.net.cn

请注意,自定义函数是静态方法。 在前面的示例中,自定义函数是一个名为calc在名为MyFunctions并采用 type 的单个参数MyThing.spring-doc.cadn.net.cn

假设你有一个Message有效负载类型为MyThing. 此外,假设您需要执行一些作来创建一个名为MyObjectMyThing,然后调用一个名为calc在该对象上。spring-doc.cadn.net.cn

标准属性访问器不知道如何获取MyObjectMyThing,因此您可以编写和配置自定义属性访问器来执行此作。 因此,您的最终表达式可能是"#barcalc(payload.myObject)".spring-doc.cadn.net.cn

工厂 bean 还有另一个属性 (typeLocator),它允许您自定义TypeLocator在 SpEL 评估期间使用。 您可能需要在某些使用非标准的环境中运行ClassLoader. 在以下示例中,SpEL 表达式始终使用 bean 工厂的类加载器: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/>组件,为EvaluationContext在整个框架中使用。 您可以添加一个或多个这些组件,而不是配置前面显示的工厂 Bean,框架会自动将它们添加到缺省值integrationEvaluationContext工厂豆。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

  • 默认值IntegrationEvaluationContextFactoryBeanID 为integrationEvaluationContext已向应用程序上下文注册。spring-doc.cadn.net.cn

  • <spel-function/>被解析并添加到functions MapintegrationEvaluationContext作为地图条目,其id作为关键和静态Method作为值。spring-doc.cadn.net.cn

  • integrationEvaluationContext工厂 bean 创建一个新的StandardEvaluationContext实例,并且它配置为默认的PropertyAccessor实例,一个BeanResolver和自定义函数。spring-doc.cadn.net.cn

  • EvaluationContext实例被注入到ExpressionEvaluatingTransformer豆。spring-doc.cadn.net.cn

要使用 Java 配置提供 SpEL 函数,您可以声明SpelFunctionFactoryBeanbean 的 bean 。 以下示例演示如何创建自定义函数:spring-doc.cadn.net.cn

@Bean
public SpelFunctionFactoryBean xpath() {
    return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
}
在父上下文中声明的 SpEL 函数也可用于任何子上下文。 每个上下文都有自己的integrationEvaluationContext工厂 bean,因为每个都需要不同的BeanResolver,但函数声明是继承的,可以通过声明具有相同名称的 SpEL 函数来覆盖。

内置 SpEL 函数

Spring Integration 提供了以下标准函数,这些函数在启动时自动注册到应用程序上下文中: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,可以通过对 bean 或 bean 方法的引用(例如)来提供。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 提供命名空间支持,允许您创建 SpEL 自定义PropertyAccessor实现。 您可以使用<spel-property-accessors/>组件以提供自定义列表PropertyAccessorinstances 添加到EvaluationContext在整个框架中使用。 您可以添加一个或多个这些组件,而不是配置前面显示的工厂 Bean,框架会自动将访问器添加到默认的integrationEvaluationContext工厂豆。 以下示例显示了如何执行此作: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实例被注入到EvaluationContext(按声明的顺序)。spring-doc.cadn.net.cn

提供PropertyAccessor实例,您应该声明一个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). 如果您声明PropertyAccessor在子上下文中具有相同的 bean ID,则它会覆盖父访问器。 在<spel-property-accessors/>必须具有“id”属性。 最终使用顺序如下:spring-doc.cadn.net.cn