Print
Interceptors

MVEL provides the ability to place interceptors within a compiled expression. This can be particularly useful for implementing change listeners or firing external events based from within an expression.

An interceptor declaration uses the @Syntax, similar to annotations in Java.

You declare interceptors before a statement you wish to enclose, and as such, an interceptor may implement either before or after listeners, or both. For example:

In this particular statement, the interceptor encloses the entire foreach block, so if the interceptor implements the after listener, that action will be fired when the foreach has completed.

The org.mvel.intergration.Interceptor Interface

The Interceptor interface provides two methods to be implemented: doBefore and doAfter. Here we will describe the meaning of the values passed into the methods from the MVEL runtime.

doBefore

The doBefore method is called before the enclosing statement is executed.


org.mvel.ASTNode::node

The handle to the ASTNode is a reference to the ASTNode which is wrapped by the interceptor. This can be used to obtain information about the actual compiled code.

About AST API

Icon

While access to the AST is provided, there is no guarantee that changes to the underlying AST API will not be changed in maintenance releases and subsequent revisions to MVEL, as certain bug fixes and performance improvements. Also certain compiler options may effect the structure of the AST and produce unexpected results, so understand this is an advanced feature.


org.mvel.integration.VariableResolverFactory::factory

The variable resolver factory provides access to the current scope of variables in the expression. Please see Variable Resolvers for more information.

doAfter

The doAfter method is called after the enclosing statement has executed.


java.lang.Object::exitStackValue

The doAfter method is executed after the enclosing statement has executed, but not before the end of the frame. Therefore, any value left on the stack at the end of the operation will still be present and therefore accessible to the interceptor. For example:

In this particular case, the reduced value of cost = cost + value will be present on the stack until the end of the execution frame, and therefore this value will be available as the exitStackValue in the doAfter call.


org.mvel.ASTNode::node

This is the same AST element as is passed to doBefore. See the last section for more details.

org.mvel.intergration.VariableResolverFactory::factory

See the last section for more details.

Using Interceptors in the Compiler

Interceptors must be provided to the compiler prior to compiling the expression in order to wire the interceptors into the expression. So it should be noted here that interceptors may not be used with the MVEL interpreter.

A Map is used to provide the compiler with the interceptors with the key representing the name of the interceptor, and the value being the interceptor instance.

For example:

Serializability of Expressions

Icon

If you intend to serialize a compiled expression for re-use across multiple runtime instances, you must ensure that your interceptors are, themselves, Serializable otherwise you will encounter serialization problems since your Interceptor instance is added to the AST directly.

Powered by Atlassian Confluence