此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.4spring-doc.cn

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.4spring-doc.cn

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

在大多数情况下,对象是 ,它有两个属性 ( 和 ),允许 、 、 等表达式。#rootMessageheaderspayloadpayloadpayload.thingheaders['my.header']spring-doc.cn

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

对于所有 SPEL 表达式, a 可用于启用对应用程序上下文中任何 bean 的引用(例如,)。 此外,还有两个可用。 A 允许使用键和 a 访问 a 中的值,后者允许访问字段和符合 JavaBean 的属性(通过使用 getter 和 setter)。 这是访问 headers 和 payload 属性的方法。BeanResolver@myBean.foo(payload)PropertyAccessorsMapAccessorMapReflectivePropertyAccessorMessagespring-doc.cn

SPEL 评估上下文自定义

从 Spring Integration 3.0 开始,你可以将其他实例添加到框架使用的 SPEL 评估上下文中。 框架提供 (只读) ,可用于访问中的字段 或 中的 JSON 。 如果您有特定需求,您也可以创建自己的。PropertyAccessorJsonPropertyAccessorJsonNodeStringPropertyAccessorspring-doc.cn

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

以下配置显示了如何直接配置 with custom property 访问器和函数:IntegrationEvaluationContextFactoryBeanspring-doc.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 集成为属性访问器和函数提供了名称空间支持,如以下各节所述。 框架将代表您自动配置工厂 Bean。spring-doc.cn

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

请注意,自定义函数是静态方法。 在前面的示例中,自定义函数是在名为 的类上调用的静态方法,并采用 类型为 .calcMyFunctionsMyThingspring-doc.cn

假设您有一个负载类型为 . 此外,假设您需要执行一些操作来创建名为 from 的对象,然后调用对该对象调用的自定义函数。MessageMyThingMyObjectMyThingcalcspring-doc.cn

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

工厂 Bean 具有另一个属性 (),该属性允许您自定义 SPEL 评估期间使用的 。 您可能需要在一些使用非标准 . 在下面的示例中,SPEL 表达式始终使用 Bean 工厂的类加载器:typeLocatorTypeLocatorClassLoaderspring-doc.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 集成提供了名称空间支持,让您创建 SPEL 自定义函数。 您可以指定组件,以便为整个框架中使用的 提供自定义 SPEL 函数。 您可以添加其中的一个或多个组件,而不是配置前面显示的工厂 Bean,框架会自动将它们添加到默认的工厂 Bean 中。<spel-function/>EvaluationContextintegrationEvaluationContextspring-doc.cn

例如,假设您有一个有用的静态方法来评估 XPath。 以下示例显示如何创建自定义函数以使用该方法:spring-doc.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.cn

  • ID 为 的默认 Bean 将注册到应用程序上下文中。IntegrationEvaluationContextFactoryBeanintegrationEvaluationContextspring-doc.cn

  • 解析 the 并将其作为 map 条目添加到 of 中,其中 its 作为键,static 作为值。<spel-function/>functionsMapintegrationEvaluationContextidMethodspring-doc.cn

  • 工厂 Bean 创建一个新实例,并使用默认实例 a 和自定义函数对其进行配置。integrationEvaluationContextStandardEvaluationContextPropertyAccessorBeanResolverspring-doc.cn

  • 该实例被注入到 Bean 中。EvaluationContextExpressionEvaluatingTransformerspring-doc.cn

要使用 Java 配置提供 SPEL 函数,可以为每个函数声明一个 Bean。 以下示例显示如何创建自定义函数:SpelFunctionFactoryBeanspring-doc.cn

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

内置 SPEL 函数

Spring 集成提供了以下标准函数,这些函数在启动时自动注册到应用程序上下文中:spring-doc.cn

  • #jsonPath:对指定对象计算 'jsonPath'。 此函数调用 ,该函数委托给 Jayway JsonPath 库。 下面的清单显示了一些使用示例:JsonPathUtils.evaluate(…​)spring-doc.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.cn

    使用此函数需要 Jayway JsonPath 库 () 位于类路径上。 否则,不会注册 SPEL 函数。json-path.jar#jsonPath

    有关 JSON 的更多信息,请参阅 Transformer 中的“JSON 转换器”。spring-doc.cn

  • #xpath:在提供的某个对象上评估 xpath。 有关 XML 和 XPath 的更多信息,请参见 XML 支持 - 处理 XML 负载spring-doc.cn

在父上下文中声明的 SPEL 函数也可以在任何子上下文中使用。 每个上下文都有自己的工厂 bean 实例,因为每个实例都需要不同的 ,但是函数声明是继承的,可以通过声明具有相同名称的 SPEL 函数来覆盖。integrationEvaluationContextBeanResolver
使用此函数需要 Jayway JsonPath 库 () 位于类路径上。 否则,不会注册 SPEL 函数。json-path.jar#jsonPath

属性访问器

Spring 集成提供了名称空间支持,以允许您创建 SPEL 自定义PropertyAccessor实现。 您可以使用该组件提供自定义实例列表,以供在整个框架中使用。 您可以添加其中的一个或多个组件,而不是配置前面所示的工厂 Bean,框架会自动将访问器添加到默认的工厂 Bean。 以下示例显示了如何执行此操作:<spel-property-accessors/>PropertyAccessorEvaluationContextintegrationEvaluationContextspring-doc.cn

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

在前面的示例中,两个自定义实例被注入到 (按照它们的声明顺序)。PropertyAccessorEvaluationContextspring-doc.cn

要使用 Java 配置提供实例,您应该声明一个名称为 (由常量决定) 的 bean。 以下示例演示如何使用 Java 配置两个自定义实例:PropertyAccessorSpelPropertyAccessorRegistrarspelPropertyAccessorRegistrarIntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAMEPropertyAccessorspring-doc.cn

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

在父上下文中声明的自定义实例也可以在任何子上下文中使用。 它们位于结果列表的末尾(但在默认 和 之前)。 如果在子上下文中声明具有相同 bean ID 的 a,它将覆盖父访问器。 在 中声明的 bean 必须具有 'id' 属性。 最终使用顺序如下:PropertyAccessororg.springframework.context.expression.MapAccessoro.s.expression.spel.support.ReflectivePropertyAccessorPropertyAccessor<spel-property-accessors/>spring-doc.cn

在父上下文中声明的自定义实例也可以在任何子上下文中使用。 它们位于结果列表的末尾(但在默认 和 之前)。 如果在子上下文中声明具有相同 bean ID 的 a,它将覆盖父访问器。 在 中声明的 bean 必须具有 'id' 属性。 最终使用顺序如下:PropertyAccessororg.springframework.context.expression.MapAccessoro.s.expression.spel.support.ReflectivePropertyAccessorPropertyAccessor<spel-property-accessors/>spring-doc.cn