Spring 運算式語言 (SpEL)
您可以使用以 Spring 運算式語言撰寫的運算式,來設定許多 Spring Integration 元件。
在大多數情況下,#root
物件是 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
中的值,而 ReflectivePropertyAccessor
允許存取欄位和符合 JavaBean 標準的屬性 (透過使用 getter 和 setter)。這就是您如何存取 Message
標頭和有效負載屬性的方式。
SpEL 評估內容自訂
從 Spring Integration 3.0 開始,您可以將額外的 PropertyAccessor
實例新增至框架使用的 SpEL 評估內容。框架提供 (唯讀) JsonPropertyAccessor
,您可以使用它從 JsonNode
或 String
中的 JSON 存取欄位。如果您有特定需求,也可以建立自己的 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 為屬性存取器和函數提供命名空間支援,如下節所述。框架會自動為您設定 factory bean。
此 factory bean 定義會覆寫預設的 integrationEvaluationContext
bean 定義。它將自訂存取器和一個自訂函數新增至清單 (其中也包括 先前提及 的標準存取器)。
請注意,自訂函數是靜態方法。在前面的範例中,自訂函數是在名為 MyFunctions
的類別上呼叫的靜態方法 calc
,並採用 MyThing
類型的單一參數。
假設您有一個 Message
,其有效負載類型為 MyThing
。此外,假設您需要執行某些動作,以從 MyThing
建立名為 MyObject
的物件,然後在該物件上叫用名為 calc
的自訂函數。
標準屬性存取器不知道如何從 MyThing
取得 MyObject
,因此您可以撰寫和設定自訂屬性存取器來執行此操作。因此,您的最終運算式可能是 "#barcalc(payload.myObject)"
。
factory bean 還有另一個屬性 (typeLocator
),可讓您自訂 SpEL 評估期間使用的 TypeLocator
。您可能需要在某些使用非標準 ClassLoader
的環境中執行此操作。在以下範例中,SpEL 運算式始終使用 bean factory 的類別載入器
<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
。您可以新增一或多個這些元件,而不是設定先前顯示的 factory bean,框架會自動將它們新增至預設的 integrationEvaluationContext
factory 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 為
integrationEvaluationContext
的預設IntegrationEvaluationContextFactoryBean
bean 已向應用程式內容註冊。 -
<spel-function/>
已剖析並新增至integrationEvaluationContext
的functions
Map
,作為地圖項目,其id
作為鍵,靜態Method
作為值。 -
integrationEvaluationContext
factory bean 建立新的StandardEvaluationContext
實例,並使用預設的PropertyAccessor
實例、BeanResolver
和自訂函數進行設定。 -
該
EvaluationContext
實例會注入到ExpressionEvaluatingTransformer
bean 中。
若要使用 Java 設定提供 SpEL 函數,您可以為每個函數宣告 SpelFunctionFactoryBean
bean。以下範例顯示如何建立自訂函數
@Bean
public SpelFunctionFactoryBean xpath() {
return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
}
在父內容中宣告的 SpEL 函數也適用於任何子內容。每個內容都有自己的 integrationEvaluationContext factory 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
) 位於類別路徑中。否則,不會註冊#jsonPath
SpEL 函數。有關 JSON 的更多資訊,請參閱 轉換器 中的「JSON 轉換器」。
-
#xpath
:在某些提供的物件上評估 xpath。有關 XML 和 XPath 的更多資訊,請參閱 XML 支援 - 處理 XML 有效負載。
屬性存取器
Spring Integration 提供命名空間支援,讓您建立 SpEL 自訂 PropertyAccessor
實作。您可以使用 <spel-property-accessors/>
元件,將自訂 PropertyAccessor
實例的清單提供給整個框架中使用的 EvaluationContext
。您可以新增一或多個這些元件,而不是設定先前顯示的 factory bean,框架會自動將存取器新增至預設的 integrationEvaluationContext
factory bean。以下範例顯示如何執行此操作
<int:spel-property-accessors>
<bean id="jsonPA" class="org.springframework.integration.json.JsonPropertyAccessor"/>
<ref bean="fooPropertyAccessor"/>
</int:spel-property-accessors>
在前面的範例中,兩個自訂 PropertyAccessor
實例會注入到 EvaluationContext
中 (依宣告順序)。
若要使用 Java 設定提供 PropertyAccessor
實例,您應該宣告名稱為 spelPropertyAccessorRegistrar
的 SpelPropertyAccessorRegistrar
bean (由 IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME
常數指示)。以下範例顯示如何使用 Java 設定兩個自訂 PropertyAccessor
實例
@Bean
public SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
return new SpelPropertyAccessorRegistrar(new JsonPropertyAccessor())
.add(fooPropertyAccessor());
}
在父內容中宣告的自訂
|