Spring 式言語 (SpEL)
Spring 式言語で記述された式を使用して、多くの Spring Integration コンポーネントを構成できます。
ほとんどの場合、#root オブジェクトは Message であり、payload、payload.thing、headers['my.header'] などの式を許可する 2 つのプロパティ(headers および payload)があります。
場合によっては、追加の変数が提供されます。例: <int-http:inbound-gateway/> は、#requestParams (HTTP リクエストからのパラメーター)および #pathVariables (URI のパスプレースホルダーからの値)を提供します。
すべての SpEL 式において、BeanResolver を使用してアプリケーションコンテキスト内の任意の Bean(例: @myBean.foo(payload))への参照が可能です。さらに、2 つの PropertyAccessors も利用可能です。MapAccessor はキーを使用して Map の値にアクセスできるようにします。また、ReflectivePropertyAccessor はフィールドと JavaBean 準拠のプロパティ(getter と setter を使用)へのアクセスを可能にします。これにより、Message のヘッダーとペイロードプロパティにアクセスできます。
SpEL 評価コンテキストのカスタマイズ
Spring Integration 3.0 以降、フレームワークが使用する SpEL 評価コンテキストに追加の PropertyAccessor インスタンスを追加できます。フレームワークは(読み取り専用) JacksonPropertyAccessor を提供します。これを使用して、String の JsonNode または JSON からフィールドにアクセスできます。特定のニーズがある場合は、独自の PropertyAccessor を作成することもできます。
JacksonIndexAccessor 実装は、Jackson の ArrayNode API を使用して JSON 配列からインデックスを読み取る方法を備えています。整数リテラルとして提供されるインデックス(例: myJsonArray[1])をサポートします。また、負のインデックス(例: myJsonArray[-1] は myJsonArray[myJsonArray.length - 1] と同等)もサポートします。さらに、範囲外のインデックスに対しては null が返されます(詳細は ArrayNode.get(int) を参照してください)。
さらに、カスタム関数を追加できます。カスタム関数は、クラスで宣言された 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> バージョン 6.4 以降、AbstractEvaluationContextFactoryBean は IndexAccessor インスタンスのインジェクションをサポートします。詳細については、AbstractEvaluationContextFactoryBean メソッドの Javadoc を参照してください。
便宜上、Spring Integration は、次のセクションで説明するように、プロパティアクセサーと関数の両方に名前空間のサポートを提供します。フレームワークは、ユーザーに代わってファクトリ Bean を自動的に構成します。
このファクトリ Bean 定義は、デフォルトの integrationEvaluationContext Bean 定義をオーバーライドします。これにより、カスタムアクセサーと 1 つのカスタム関数がリストに追加されます。これには、前述の標準アクセサーも含まれます。
カスタム関数は静的メソッドであることに注意してください。上記の例では、カスタム関数は MyFunctions というクラスの calc という静的メソッドであり、型 MyThing の単一パラメーターを取ります。
型が MyThing のペイロードを持つ Message があるとします。さらに、何らかのアクションを実行して MyThing から MyObject というオブジェクトを作成し、そのオブジェクトで calc というカスタム関数を呼び出す必要があるとします。
標準のプロパティアクセサーは MyThing から MyObject を取得する方法を知らないため、カスタムプロパティアクセサーを作成および構成することができます。その結果、最終的な式は "#barcalc(payload.myObject)" になる可能性があります。
ファクトリ Bean には、SpEL 評価中に使用される TypeLocator をカスタマイズできる別のプロパティ(typeLocator)があります。非標準の 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 Integration は、SpEL カスタム関数を作成できるネームスペースサポートを提供します。<spel-function/> コンポーネントを指定して、フレームワーク全体で使用される EvaluationContext にカスタム SpEL 機能を提供できます。前述のファクトリ Bean を構成する代わりに、これらのコンポーネントを 1 つ以上追加することができ、フレームワークはそれらをデフォルトの integrationEvaluationContext ファクトリ 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のデフォルトのIntegrationEvaluationContextFactoryBeanBean がアプリケーションコンテキストに登録されます。<spel-function/>は解析され、idをキーとして、静的Methodを値として、マップエントリとしてintegrationEvaluationContextのfunctionsMapに追加されます。integrationEvaluationContextファクトリ Bean は新しいStandardEvaluationContextインスタンスを作成し、デフォルトのPropertyAccessorインスタンス、BeanResolver、カスタム関数で構成されます。その
EvaluationContextインスタンスはExpressionEvaluatingTransformerBean に注入されます。
Java 構成を使用して SpEL 関数を提供するには、各関数に対して SpelFunctionFactoryBean Bean を宣言できます。次の例は、カスタム関数を作成する方法を示しています。
@Bean
public SpelFunctionFactoryBean xpath() {
return new SpelFunctionFactoryBean(XPathUtils.class, "evaluate");
} 親コンテキストで宣言された SpEL 関数は、すべての子コンテキストでも使用可能になります。コンテキストごとに異なる BeanResolver が必要なため、各コンテキストには integrationEvaluationContext ファクトリ Bean の独自のインスタンスがありますが、関数宣言は継承され、同じ名前の SpEL 関数を宣言することでオーバーライドできます。 |
組み込み SpEL 関数
Spring Integration は次の標準関数を提供しており、起動時にアプリケーションコンテキストに自動的に登録されます。
#jsonPath: 指定されたオブジェクトで 'jsonPath' を評価します。この関数はJsonPathUtils.evaluate(…)を呼び出し、Jayway JsonPath ライブラリ [GitHub] (英語) に委譲します。次のリストは、使用例を示しています。<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は、3 番目の(オプションの)パラメーターであるcom.jayway.jsonpath.Filter[GitHub] (英語) の配列もサポートしています。これは、Bean または Bean メソッドへの参照によって提供できます(たとえば)。この関数を使用するには、Jayway JsonPath ライブラリ ( json-path.jar) がクラスパスにある必要があります。それ以外の場合、#jsonPathSpEL 関数は登録されません。JSON の詳細については、Transformer の "JSON Transformers" を参照してください。
#xpath: 提供されたオブジェクトの xpath を評価するため。XML と XPath の詳細については、"XML サポート - XML ペイロードの処理" を参照してください。
プロパティアクセサー
Spring Integration は、SpEL カスタム PropertyAccessor (Javadoc) 実装を作成できるように名前空間サポートを提供します。<spel-property-accessors/> コンポーネントを使用して、フレームワーク全体で使用される EvaluationContext にカスタム PropertyAccessor インスタンスのリストを提供できます。前述のファクトリ Bean を構成する代わりに、このコンポーネントを追加できます。フレームワークは、デフォルトの integrationEvaluationContext ファクトリ Bean にアクセサーを自動的に追加します。また、バージョン 6.4 以降では、同様の方法で IndexAccessor Bean を構成するための専用の <index-accessors> サブ要素が提供されています。次の例は、その方法を示しています。
<int:spel-property-accessors>
<index-accessors>
<beans:bean id="jsonIndex" class="org.springframework.integration.json.JacksonIndexAccessor"/>
</index-accessors>
<bean id="jsonPA" class="org.springframework.integration.json.JacksonPropertyAccessor"/>
<ref bean="fooPropertyAccessor"/>
</int:spel-property-accessors> 前の例では、2 つのカスタム PropertyAccessor インスタンスが EvaluationContext に(宣言された順序で)挿入されます。
Java 構成を使用して PropertyAccessor インスタンスを提供するには、spelPropertyAccessorRegistrar (IntegrationContextUtils.SPEL_PROPERTY_ACCESSOR_REGISTRAR_BEAN_NAME 定数によって決定) という名前の SpelPropertyAccessorRegistrar Bean を宣言する必要があります。次の例は、Java を使用して 2 つのカスタム PropertyAccessor (およびバージョン 6.4 以降の IndexAccessor ) インスタンスを構成する方法を示しています。
@Bean
public SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
return new SpelPropertyAccessorRegistrar(new JacksonPropertyAccessor())
.add(fooPropertyAccessor())
.add(new JacksonIndexAccessor());
} 親コンテキストで宣言されたカスタム
|