Many Spring Integration components can be configured using expressions. These expressions are written in the Spring Expression Language.
In most cases, the #root object is the
Message
which, of course, has two properties - headers
and
payload
- allowing such expressions as payload
, payload.foo
,
headers['my.header']
etc.
In some cases, additional variables are provided, for example the <int-http:inbound-gateway/>
provides #requestParams
(parameters from the HTTP request) and #pathVariables
(values from path placeholders in the URI).
For all SpEL expressions, a BeanResolver
is available, enabling references to
any bean in the application context. For example @myBean.foo(payload)
. In addition, two
PropertyAccessors
are available; a MapAccessor
enables accessing values in a Map
using a key, and a
ReflectivePropertyAccessor
which allows access to fields and or JavaBean compliant
properties (using getters and setters). This is how the Message
headers
and payload properties are accessible.
Starting with Spring Integration 3.0, it is possible to add additional
PropertyAccessor
s to the SpEL evaluation context.
In fact, the framework provides one such accessor,
the JsonPropertyAccessor
which can be used (read-only) to access fields from
a JsonNode
, or JSON in a String
. Or you can create your
own PropertyAccessor
if you have specific needs.
In addition, custom functions can be added. Custom functions are static
methods
declared on a class. Functions and property accessors are available in any SpEL
expression used throughout the framework.
To configure your custom accessors and functions, add an
IntegrationEvaluationContextFactoryBean
with
id="integrationEvaluationContext"
to your application context, with the appropriate configuration; for example:
<beans:bean id="integrationEvaluationContext" class="org.springframework.integration.config.IntegrationEvaluationContextFactoryBean"> <property name="propertyAccessors"> <list> <bean class="foo.MyCustomPropertyAccessor"/> </list> </property> <property name="functions"> <map> <entry key="barcalc" value="#{T(foo.MyFunctions).getMethod('calc', T(foo.MyBar))}"/> </map> </property> </bean>
This factory bean definition will override the default integrationEvaluationContext
bean definition, adding the custom accessor to the list (which also includes the standard
accessors mentioned above), and one custom function.
Note that custom functions are static methods.
In the above example, the custom function is a static method calc
on class
MyFunctions
and takes a single parameter of type MyBar
.
Say you have a Message
with a payload that has a type MyFoo
on which you need to perform some action to create a MyBar
object from it,
and you then want to invoke a custom function calc
on that object.
The standard property accessors wouldn't know how to get a MyBar
from a MyFoo
so you could write
and configure a custom property accessor to do so. So, your final expression might be
"#barcalc(payload.myBar)"
.
Namespace support is provided for easy addition of SpEL custom functions.
You can specify <spel-function/>
components to provide
custom SpEL functions to the EvaluationContext
used throughout the framework.
Instead of configuring the factory bean above, simply add one or more of these components
and the framework will automatically add them to the default integrationEvaluationContext
factory bean.
For example, assuming we have a useful static method to evaluate XPath:
<int:spel-function id="xpath" class="com.foo.test.XPathUtils" method="evaluate(java.lang.String, java.lang.Object)"/> <int:transformer input-channel="in" output-channel="out" expression="#xpath('//foo/@bar', payload)" />
With this sample:
IntegrationEvaluationContextFactoryBean
bean with id
integrationEvaluationContext is registered with the application
context.
<spel-function/>
is parsed and added to the functions
Map of integrationEvaluationContext as map entry with id
as the key
and the static Method
as the value.
StandardEvaluationContext
instance,
and it is configured with the default
PropertyAccessor
s, BeanResolver
and the custom function.
EvaluationContext
instance is injected into the
ExpressionEvaluatingTransformer
bean.
![]() | Note |
---|---|
SpEL functions declared in a parent context are also made available in any child context(s). Each
context has its own instance of the integrationEvaluationContext factory bean
because each needs a different BeanResolver , but the function
declarations are inherited (and can be overridden if needed by declaring a SpEL function with
the same name. The functions themselves are processed by the framework - they do not appear
as beans in the application context.
|
![]() | Note |
---|---|
At this time, PropertyAccessor s are not inherited and must be
declared as described above in each context.
|