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
は、キーと ReflectivePropertyAccessor
を使用して Map
の値にアクセスできるようにします。これにより、フィールドおよび JavaBean 準拠のプロパティにアクセスできます(getter および setter を使用)。これにより、Message
ヘッダーとペイロードプロパティにアクセスできます。
SpEL 評価コンテキストのカスタマイズ
Spring Integration 3.0 以降、フレームワークが使用する SpEL 評価コンテキストに追加の PropertyAccessor
インスタンスを追加できます。フレームワークは(読み取り専用) JsonPropertyAccessor
を提供します。これを使用して、String
の JsonNode
または JSON からフィールドにアクセスできます。特定のニーズがある場合は、独自の PropertyAccessor
を作成することもできます。
バージョン 6.4 以降では、Jackson の ArrayNode
API を使用して JSON 配列からインデックスを読み取る方法を認識する JsonIndexAccessor
実装が提供されています。整数リテラルとして提供されるインデックス (例: 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
メソッド JavaDocs を参照してください。
便宜上、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
のデフォルトのIntegrationEvaluationContextFactoryBean
Bean がアプリケーションコンテキストに登録されます。<spel-function/>
は解析され、id
をキーとして、静的Method
を値として、マップエントリとしてintegrationEvaluationContext
のfunctions
Map
に追加されます。integrationEvaluationContext
ファクトリ Bean は新しいStandardEvaluationContext
インスタンスを作成し、デフォルトのPropertyAccessor
インスタンス、BeanResolver
、カスタム関数で構成されます。その
EvaluationContext
インスタンスはExpressionEvaluatingTransformer
Bean に注入されます。
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
) がクラスパスにある必要があります。それ以外の場合、#jsonPath
SpEL 関数は登録されません。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.JsonIndexAccessor"/>
</index-accessors>
<bean id="jsonPA" class="org.springframework.integration.json.JsonPropertyAccessor"/>
<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 JsonPropertyAccessor())
.add(fooPropertyAccessor())
.add(new JsonIndexAccessor());
}
親コンテキストで宣言されたカスタム
|