[[aot]]
= Ahead-of-Time Processing

Spring AOT is a process that analyzes your application at build-time and generate an optimized version of it.
It is a mandatory step to run a Spring `ApplicationContext` in a native image.

NOTE: For an overview of GraalVM Native Images support in Spring Boot, check the {spring-boot-reference}/#native-image[reference documentation].

The Spring Boot Maven plugin offers goals that can be used to perform AOT processing on both application and test code.



== Processing Applications
To configure your application to use this feature, add an execution for the `process-aot` goal, as shown in the following example:

[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
----
include::../maven/aot/pom.xml[tags=aot]
----

As the `BeanFactory` is fully prepared at build-time, conditions are also evaluated.
This has an important difference compared to what a regular Spring Boot application does at runtime.
For instance, if you want to opt-in or opt-out for certain features, you need to configure the environment used at build time to do so.
The `process-aot` goal shares a number of properties with the <<run,run goal>> for that reason.



=== Using the Native Profile
If you use `spring-boot-starter-parent` as the `parent` of your project, a `native` profile can be used to streamline the steps required to build a native image.

The `native` profile configures the following:

* Execution of `process-aot` when the Spring Boot Maven Plugin is applied on a project.
* Suitable settings so that <<build-image,build-image>> generates a native image.
* Sensible defaults for the {nbt-reference}[Native Build Tools Maven Plugin], in particular:
** Making sure the plugin uses the raw classpath, and not the main jar file as it does not understand our repackaged jar format.
** Validate that a suitable GraalVM version is available.
** Download third-party reachability metadata.

To benefit from the `native` profile, a module that represents an application should define two plugins, as shown in the following example:

[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
----
include::../maven/aot-native/pom.xml[tags=aot-native]
----

A single project can trigger the generation of a native image on the command-line using either {spring-boot-reference}/#native-image.developing-your-first-application.buildpacks.maven[Cloud Native Buildpacks] or {spring-boot-reference}/#native-image.developing-your-first-application.native-build-tools.maven[Native Image Build Tools].

To use the `native` profile with a multi-modules project, you can create a customization of the `native` profile so that it invokes your preferred technique.

To bind Cloud Native Buildpacks during the `package` phase, add the following to the root POM of your multi-modules project:

[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
----
include::../maven/aot-native-profile-buildpacks/pom.xml[tags=profile]
----

The example below does the same for Native Build Tools:

[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
----
include::../maven/aot-native-profile-nbt/pom.xml[tags=profile]
----

Once the above is in place, you can build your multi-modules project and generate a native image in the relevant sub-modules, as shown in the following example:

[indent=0]
----
	$ mvn package -Pnative
----

NOTE: A "relevant" sub-module is a module that represents a Spring Boot application.
Such module must define the Native Build Tools and Spring Boot plugins as described above.



include::goals/process-aot.adoc[leveloffset=+1]



== Processing Tests
The AOT engine can be applied to JUnit 5 tests that use Spring's Test Context Framework.
Suitable tests are processed by the AOT engine in order to generate `ApplicationContextInitialzer` code.

To configure your application to use this feature, add an execution for the `process-test-aot` goal, as shown in the following example:

[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
----
include::../maven/aot-test/pom.xml[tags=aot]
----

TIP: If you are using `spring-boot-starter-parent`, this execution is automatically configured if you enable the `nativeTest` profile.

As with application AOT processing, the `BeanFactory` is fully prepared at build-time.

include::goals/process-test-aot.adoc[leveloffset=+1]
