Open sdeleuze opened 1 year ago
Perform SpEL to bytecode generation at build-time to skip that processing at runtime
I've put some thought into this, and I'll share my findings here.
The first challenge is saving the compiled bytecode to .class
files.
Luckily, we already have a prototype for that.
At the end of the SpelCompiler.createExpressionClass(SpelNodeImpl)
method, there's a commented-out invocation of saveGeneratedClassFile(expressionToCompile.toStringAST(), className, data)
.
A simple implementation of that exists in SpelCompilationCoverageTests
.
Using that and running a SpEL compilation test currently generates files such as build/spel.Ex2.class
. We'd probably want to rename the package from spel
to something like org.springframework.expression.spel.compiled
. And we'd need to come up with unique class names that can be mapped to the expression.
So, compiling the expressions and saving the generated byte code to disk should be achievable tasks.
The main challenges that I foresee are:
The latter is necessary to successfully compile a SpEL expression. For example, a simple ternary expression such as #list.isEmpty() ? -1 : #list.size()
cannot be compiled unless both branches are evaluated. This means that such an expression must be evaluated twice: once with isEmpty()
returning true
and one with isEmpty()
returning false
.
The purpose of this issue is to explore if it is possible to remove SpEL implementation from the reachable code path by performing an AOT processing of SpEL expressions to generate related bytecode at build-time, and introduce a dedicated
BeanExpressionResolver
used in AOT mode without a dependency onStandardBeanExpressionResolver
with 3 goals:Pre-processing of SpEL expressions in annotations like Spring Framework
@Value
or Spring Security@PreAuthorize
/@PostAuthorize
/@PreFilter
/@PostFilter
(cc @rwinch) would be the main use cases, but other potential use cases ofBeanExpressionResolver
should be explored to ensure the feasibility of this optimization.Usage of SpEL in Thymeleaf would be probably out of the scope, or would require build-time compilation of Thymeleaf templates which is out of the scope of this issue, even if that's an interesting idea.