Context
Spring AOT has been designed originally in order to make GraalVM native image support possible and efficient, but can also be used on the JVM to make Spring applications more efficient. That said, this JVM usage of Spring AOT is still pretty niche, mainly because there are side-effects like the freeze of @Configuration
conditions at build time which makes sense on native, but is not really desirable on the JVM.
We also have deprecated spring-context-indexer
annotation processor in Spring Framework 6.1 in #30431, mentioning Spring AOT as a replacement, but in its current incarnation it is not yet, due to the side effects mentioned above.
Spring Data is about to introduce AOT repositories which are providing an extra efficiency boost to Spring applications, but again, it requires to enable Spring AOT with side effects usually not acceptable for JVM users.
Proposal
This enhancement proposal is about making Spring AOT more modular in Spring Framework 7.x (potentially in 7.1) by allowing to chose at Spring Framework level which optimization are enabled and which are not.
A proof-of-concept has been built (see related framework branch, boot branch).
It introduces a new GeneratedArtifact
enumeration that allows to identify what kind of artifact(s) we want to activate.
/**
* Enumeration that represents the artifact types generated by the Spring AOT engine.
*
* @author Sebastien Deleuze
*/
public enum GeneratedArtifact {
/**
* Source code (and related class files) for bean registration generated based on
* an AOT computation of the application context where configuration classes conditions
* are computed at build-time.
*/
BEAN_REGISTRATION,
/**
* Classpath indexes like the {@code META-INF/spring.components} file generated by
* the Spring AOT engine useful from skipping classpath or JPA entity runtime scanning.
*/
CLASSPATH_INDEXES,
/**
* Predefined classes such as CGLIB classes generated by the Spring AOT engine.
*/
PREDEFINED_CLASSES,
/**
* Reachability metadata generated by the Spring AOT engine based on the runtime hints,
* required for GraalVM native image support.
*/
REACHABILITY_METADATA
}
The proposed DevXP would be to configured Spring AOT at Spring Boot AOT plugin level which artifacts we want to generate, for example:
processAot {
predefinedClasses = true
classpathIndexes = true
}
Which would be equivalent to:
processAot {
beanRegistration = false
predefinedClasses = true
classpathIndexes = true
reachabilityMetadata = false
}
This could replace the spring-context-indexer
annotation processor by generating the same spring.components
file, with the additional benefits that it would scan at build-time all the classpath, providing a better DevXP than the annotation processor that had to be configured in each module containing the related source files. It would also provide the additional benefit to pre-generate the CGLIB classes.
Next step of the exploration is to introduce a classpath index SPI that could potentially be used by Spring Data (and other portfolio or community projects) to generate AOT repositories without suffering of current AOT side effects on the JVM, allowing a much wider adoption. The principle would be that it allows to generate sources code and related classes that will potentially be used by the application at runtime, depending of which Spring profile has been enabled.