We experience extremely high CPU (15 cores on 100%) when running high load on our application. The profiles shows that 20%+ is used by SpEL which is used mostly by the ServiceActivatingHandler. The application uses service activators to handle messages but never uses any SpEL.
There's about 12 ServiceActivators in a flow which are defined as follows:
<service-activator ref="myService"/>
or
<service-activator ref="myService" method="addStuff"/>
Most signatures are as follows:
@ServiceActivator public Message<String> handle(Message<String>, @Header("header1") String header1, @Header("header2") String header2, @Header("header3") String header3)
How can this expression evaluation be avoided? Application runs on SprintBoot and SpringIntegration 4.3.x
Extracting the headers is a bit expensive; it's a bit unusual to pass in the message and also have the framework extract headers. Since you have the whole message, you have access to the headers that way.
You can compile the SpEL, which is considerably faster; in my test it dropped from 8000ms (for 100,000 calls) to 137ms.
-Dspring.expression.compiler.mode=MIXED
However, this needs Spring Framework 4.3.7 or later (this fix is needed) or Spring Integration 4.3.8 or later (which has this workaround)
In 5.0, we avoid SpEL if possible and the same test runs in about 400ms.