🚀 Spring AOT Engine Cheatsheet Completo 🚀

El Spring AOT Engine (Ahead-of-Time Engine) es un conjunto de herramientas y un proceso dentro de Spring Boot 3+ que permite transformar una aplicación Spring Boot estándar en un ejecutable nativo compilado. Esto se logra mediante la generación de metadatos de configuración para GraalVM Native Image en tiempo de compilación (AOT), lo que permite a las aplicaciones Spring beneficiarse de arranques instantáneos y una huella de memoria reducida.


1. 🌟 Conceptos Clave


2. 🛠️ Configuración Inicial y Proceso de Construcción

2.1. Requisitos

2.2. Configuración (Maven)

El spring-boot-maven-plugin gestiona el proceso.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

&lt;!-- Perfil Maven para la compilación nativa -->
<profiles>
    <profile>
        <id>native</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.graalvm.buildtools</groupId>
                    <artifactId>native-maven-plugin</artifactId>
                    <version>0.10.1</version> &lt;!-- Usar la versión compatible -->
                    <extensions>true</extensions>
                    <executions>
                        <execution>
                            <id>build-native</id>
                            <goals>
                                <goal>compile-native</goal>
                            </goals>
                            <phase>package</phase>
                        </execution>
                    </executions>
                    <configuration>
                        &lt;!-- Opciones de compilación de Native Image (opcional) -->
                        &lt;!-- <buildArgs>
                            --enable-url-protocols=http
                        </buildArgs> -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

2.3. Proceso de Construcción

  1. Compilación de Código Fuente: javac compila .java a .class.
  2. Procesamiento AOT (Phase 1: process-aot):
    • Spring AOT Engine analiza el bytecode de tu aplicación y sus dependencias.
    • Genera código fuente Java adicional que contiene los RuntimeHints (metadatos sobre reflexión, proxies, etc.) y un contexto de Spring optimizado para AOT.
    • Este código generado se guarda en target/spring-aot/main/sources (o similar).
  3. Compilación del Código Generado: El compilador Java compila este código generado a .class.
  4. Generación del “Thin Jar”: El spring-boot-maven-plugin crea un JAR que contiene tu código original, las clases generadas por AOT y las dependencias de la aplicación (pero no las librerías de JVM).
  5. Compilación a Native Image (compile-native):
    • El native-maven-plugin invoca a la herramienta native-image de GraalVM.
    • native-image toma el “thin jar” y todos los hints generados por Spring AOT.
    • Analiza exhaustivamente el código para detectar todas las clases, métodos y campos accesibles en tiempo de ejecución.
    • Compila todo el código y los hints a un ejecutable nativo independiente.

2.4. Ejecución del Build

mvn clean package -Pnative # Construye el ejecutable nativo
# Para Gradle: ./gradlew bootBuildImage --imageName my-app:native (si usas Cloud Native Buildpacks)
# O para solo construir el nativo: ./gradlew nativeCompile

3. 📝 Runtime Hints y RuntimeHintsRegistrar

Los hints son la clave para que Native Image entienda el dinamismo de Spring.

import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;

// 1. Clase que implementa RuntimeHintsRegistrar
public class MyCustomRuntimeHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        // Ejemplo 1: Registrar reflexión para una clase específica
        hints.reflection()
             .registerType(
                 TypeReference.of("com.example.myapp.MyDynamicClass"),
                 hint -&gt; hint.withPublicFields().withPublicMethods());

        // Ejemplo 2: Registrar un proxy dinámico para una interfaz
        hints.proxies()
             .registerJdkProxy(
                 TypeReference.of("com.example.myapp.MyInterface"),
                 TypeReference.of("java.io.Serializable"));

        // Ejemplo 3: Registrar un recurso accesible por classpath
        hints.resources()
             .registerPattern("my-data/*.json");

        // Ejemplo 4: Registrar serialización para una clase
        hints.serialization()
             .registerType(TypeReference.of(com.example.myapp.MySerializableClass.class));
    }
}

// 2. Importar el registrador en una clase de configuración de Spring
@Configuration
@ImportRuntimeHints(MyCustomRuntimeHints.class)
public class AppRuntimeHintsConfig {
    // Este bean solo sirve para importar los hints.
    // No necesita lógica adicional.
}

4. 📈 Beneficios del Spring AOT Engine (al compilar a Nativo)


5. ⚠️ Limitaciones y Consideraciones


6. 💡 Buenas Prácticas y Consejos


Este cheatsheet te proporciona una referencia completa de Spring AOT Engine, cubriendo sus conceptos esenciales, el proceso de construcción para ejecutables nativos con GraalVM, la gestión de RuntimeHints y las mejores prácticas para construir aplicaciones Spring Boot de alto rendimiento y bajo consumo de recursos.