GraalVM Native Image avec Spring Boot 3 en 2026 : compilation AOT pas à pas
Guide complet pour compiler une application Spring Boot 3 en native image avec GraalVM. Configuration AOT, optimisations et déploiement en production.

La compilation native avec GraalVM transforme une application Spring Boot 3 en exécutable natif. Le temps de démarrage passe de plusieurs secondes à quelques millisecondes, et la consommation mémoire diminue drastiquement. Ce guide détaille chaque étape de la configuration AOT jusqu'au déploiement en production.
GraalVM 22.3+ avec Native Image installé, Spring Boot 3.2+ et Maven ou Gradle. La compilation native nécessite plus de RAM (8 Go minimum recommandés) et prend plusieurs minutes.
Comprendre la compilation AOT et Native Image
Différence entre JIT et AOT
La JVM traditionnelle utilise la compilation Just-In-Time (JIT) : le bytecode est interprété puis compilé en code machine pendant l'exécution. GraalVM Native Image adopte l'approche Ahead-Of-Time (AOT) : tout le code est compilé avant l'exécution.
┌─────────────────────────────────────────────────────────────┐
│ Compilation JIT │
├─────────────────────────────────────────────────────────────┤
│ │
│ .java → .class → JVM → Interprétation → JIT → Machine │
│ (runtime) (runtime) │
│ │
│ Avantages: Optimisations adaptatives, chargement rapide │
│ Inconvénients: Démarrage lent, consommation mémoire │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Compilation AOT │
├─────────────────────────────────────────────────────────────┤
│ │
│ .java → .class → GraalVM Native Image → Exécutable natif │
│ (build time) │
│ │
│ Avantages: Démarrage instantané, faible mémoire │
│ Inconvénients: Build long, pas de réflexion dynamique │
└─────────────────────────────────────────────────────────────┘La compilation AOT analyse statiquement tout le code accessible depuis le point d'entrée. Tout code non détecté à la compilation est exclu de l'image native, ce qui explique les contraintes sur la réflexion et le chargement dynamique de classes.
Architecture Spring AOT
Spring Boot 3 intègre nativement le support AOT. Le processus de compilation génère du code source additionnel qui remplace les mécanismes dynamiques par des équivalents statiques.
// Configuration Spring standard
@Configuration
@EnableCaching
public class ApplicationConfig {
@Bean
public CacheManager cacheManager() {
// Bean créé dynamiquement au runtime en mode JIT
// Pré-généré statiquement en mode AOT
return new ConcurrentMapCacheManager("users", "products");
}
@Bean
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
public FeatureService featureService() {
// Les conditions sont évaluées au build time en AOT
return new FeatureServiceImpl();
}
}Le processus AOT de Spring génère automatiquement des fichiers dans target/spring-aot/main :
target/spring-aot/main/
├── sources/ # Code Java généré
│ └── com/example/
│ └── ApplicationConfig__BeanDefinitions.java
├── resources/
│ └── META-INF/
│ └── native-image/
│ ├── reflect-config.json # Configuration réflexion
│ ├── resource-config.json # Ressources incluses
│ └── proxy-config.json # Proxies JDKConfiguration du projet Spring Boot
Dépendances Maven
La configuration Maven utilise le plugin Spring Boot avec le profil native. Les dépendances doivent être compatibles GraalVM.
<!-- pom.xml -->
<!-- Configuration complète pour Spring Boot 3 Native -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.2</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>native-demo</artifactId>
<version>1.0.0</version>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<!-- Starter Web avec support native intégré -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JPA avec Hibernate 6 compatible native -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Driver PostgreSQL compatible native -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Validation avec hints natifs -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Tests avec support native -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Plugin GraalVM pour compilation native -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- Profil pour build native -->
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<!-- Options de build native -->
<buildArgs>
<!-- Optimisations pour la taille -->
<buildArg>-O2</buildArg>
<!-- Génère un rapport de build -->
<buildArg>--verbose</buildArg>
<!-- Active le support HTTP/2 -->
<buildArg>--enable-http</buildArg>
<buildArg>--enable-https</buildArg>
</buildArgs>
<!-- Mémoire pour le build -->
<jvmArgs>
<jvmArg>-Xmx8g</jvmArg>
</jvmArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>Configuration Gradle équivalente
Pour les projets Gradle, la configuration native est similaire avec le plugin GraalVM natif.
// Configuration Gradle pour Spring Boot Native
plugins {
java
id("org.springframework.boot") version "3.4.2"
id("io.spring.dependency-management") version "1.1.7"
// Plugin GraalVM Native
id("org.graalvm.buildtools.native") version "0.10.4"
}
group = "com.example"
version = "1.0.0"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
// Configuration du build native
graalvmNative {
binaries {
named("main") {
// Nom de l'exécutable généré
imageName = "native-demo"
// Options de compilation
buildArgs.addAll(
"-O2", // Niveau d'optimisation
"--enable-http", // Support HTTP
"--enable-https", // Support HTTPS
"--verbose" // Logs détaillés
)
// Configuration mémoire pour le build
jvmArgs.addAll("-Xmx8g")
}
named("test") {
// Tests natifs avec rapport
buildArgs.add("--verbose")
}
}
// Agent de tracing pour découverte automatique
agent {
defaultMode = "standard"
enabled = true
}
}
tasks.withType<Test> {
useJUnitPlatform()
}L'agent de tracing (-agentlib:native-image-agent) permet de découvrir automatiquement les appels de réflexion pendant l'exécution. Lancez l'application avec l'agent, exercez toutes les fonctionnalités, puis utilisez les fichiers de configuration générés.
Gestion de la réflexion et des ressources
Configuration manuelle de la réflexion
Certaines bibliothèques utilisent la réflexion de manière non détectable par l'analyse statique. La configuration manuelle devient nécessaire.
// Configuration des classes nécessitant la réflexion
[
{
"name": "com.example.entity.User",
"allDeclaredConstructors": true,
"allDeclaredMethods": true,
"allDeclaredFields": true
},
{
"name": "com.example.dto.UserDTO",
"allDeclaredConstructors": true,
"allDeclaredMethods": true,
"allDeclaredFields": true
},
{
"name": "com.example.config.DynamicProperties",
"methods": [
{ "name": "getValue", "parameterTypes": [] },
{ "name": "setValue", "parameterTypes": ["java.lang.String"] }
]
}
]Utilisation des RuntimeHints de Spring
Spring Boot 3 propose une API programmatique pour déclarer les hints natifs, plus maintenable que les fichiers JSON.
// Enregistrement programmatique des hints natifs
@Configuration
@ImportRuntimeHints(NativeHintsRegistrar.AppRuntimeHints.class)
public class NativeHintsRegistrar {
static class AppRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
// Enregistrement des classes pour réflexion
hints.reflection()
// Entités JPA avec tous les membres
.registerType(User.class, MemberCategory.values())
.registerType(Order.class, MemberCategory.values())
// DTOs avec constructeurs et getters/setters
.registerType(UserDTO.class,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_DECLARED_METHODS,
MemberCategory.DECLARED_FIELDS
);
// Enregistrement des ressources à inclure
hints.resources()
// Fichiers de configuration
.registerPattern("application*.yml")
.registerPattern("application*.properties")
// Templates et fichiers statiques
.registerPattern("templates/*")
.registerPattern("static/**/*")
// Messages de validation
.registerPattern("ValidationMessages*.properties");
// Enregistrement des proxies JDK
hints.proxies()
.registerJdkProxy(
UserRepository.class,
Repository.class
);
// Sérialisation pour le caching
hints.serialization()
.registerType(User.class)
.registerType(ArrayList.class);
}
}
}// Hints automatiques pour les entités JPA
@Component
public class EntityRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
// Scan automatique des entités dans le package
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
for (BeanDefinition bd : scanner.findCandidateComponents("com.example.entity")) {
try {
Class<?> entityClass = Class.forName(bd.getBeanClassName());
// Enregistre chaque entité pour la réflexion complète
hints.reflection().registerType(
entityClass,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_DECLARED_METHODS,
MemberCategory.DECLARED_FIELDS
);
} catch (ClassNotFoundException e) {
// Log l'erreur sans interrompre le build
System.err.println("Entity class not found: " + bd.getBeanClassName());
}
}
}
}Prêt à réussir tes entretiens Spring Boot ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Compilation et optimisation de l'image native
Commandes de build
La compilation native s'effectue avec Maven ou Gradle. Le processus prend plusieurs minutes et consomme beaucoup de ressources.
# Build Maven avec profil native
# Génère l'exécutable dans target/
mvn -Pnative native:compile
# Build Gradle
# Génère l'exécutable dans build/native/nativeCompile/
./gradlew nativeCompile
# Build avec tests natifs inclus
mvn -Pnative native:compile -DskipTests=false
# Build avec agent de tracing activé
mvn -Pnative -Dagent=true test
mvn -Pnative native:compileOptions d'optimisation avancées
Les options de compilation influencent la taille de l'image, le temps de démarrage et les performances runtime.
<!-- pom.xml -->
<!-- Configuration avancée du build native -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<buildArgs>
<!-- Niveau d'optimisation (0-3, défaut: 2) -->
<buildArg>-O3</buildArg>
<!-- Optimisation pour temps de démarrage -->
<buildArg>--pgo-instrument</buildArg>
<!-- Compression de l'exécutable (réduit taille) -->
<buildArg>-H:+CompressStrings</buildArg>
<!-- Garbage collector optimal pour containers -->
<buildArg>--gc=serial</buildArg>
<!-- Initialisation au build time -->
<buildArg>--initialize-at-build-time=org.slf4j</buildArg>
<!-- Debug symbols (désactiver en prod) -->
<buildArg>-H:-IncludeAllTimeZones</buildArg>
<!-- Rapport de build détaillé -->
<buildArg>-H:+ReportExceptionStackTraces</buildArg>
<buildArg>--verbose</buildArg>
<!-- Support monitoring -->
<buildArg>--enable-monitoring=heapdump,jfr</buildArg>
</buildArgs>
<!-- Quickbuild pour développement (plus rapide, moins optimisé) -->
<quickBuild>false</quickBuild>
<!-- Fallback au jar si native échoue -->
<fallback>false</fallback>
</configuration>
</plugin>// Initialisation au build time pour réduire le démarrage
@Configuration
public class BuildTimeInitializer {
// Ces configurations sont évaluées au build time
// et non au runtime
static {
// Initialise les loggers au build time
LoggerFactory.getLogger(BuildTimeInitializer.class);
}
@Bean
@NativeHint(options = "--initialize-at-build-time=com.example.Constants")
public ConstantsProvider constantsProvider() {
// Les constantes sont calculées une seule fois au build
return new ConstantsProvider();
}
}Comparaison des performances
Les gains de performance avec la compilation native sont significatifs.
┌─────────────────────────────────────────────────────────────────────┐
│ Comparaison JIT vs Native │
├─────────────────────┬─────────────────┬─────────────────────────────┤
│ Métrique │ JIT (JVM) │ Native (GraalVM) │
├─────────────────────┼─────────────────┼─────────────────────────────┤
│ Temps de démarrage │ 2.5 - 5 sec │ 50 - 200 ms │
│ Mémoire RSS │ 200 - 400 MB │ 50 - 100 MB │
│ Taille exécutable │ JAR ~30 MB │ Binary ~80 MB │
│ Temps premier req. │ 100 - 500 ms │ < 10 ms │
│ Peak throughput │ Excellent │ Bon (85-95% du JIT) │
│ Temps de build │ 30 sec │ 3 - 10 min │
└─────────────────────┴─────────────────┴─────────────────────────────┘Le throughput maximum en mode natif peut être légèrement inférieur au mode JIT car les optimisations adaptatives du JIT ne sont pas disponibles. Pour les workloads à haute performance soutenue, évaluer les deux modes.
Résolution des problèmes courants
Erreurs de réflexion
L'erreur la plus fréquente concerne la réflexion non déclarée. L'exception indique la classe manquante.
// Diagnostic et résolution des erreurs de réflexion
@Component
@Slf4j
public class ReflectionErrorHandler {
// Erreur typique :
// java.lang.ClassNotFoundException: com.example.SomeClass
// au moment de l'accès réflexif
// Solution 1 : Ajouter la configuration manuelle
// src/main/resources/META-INF/native-image/reflect-config.json
// Solution 2 : Utiliser l'annotation @RegisterReflection
@RegisterReflection(classes = {
SomeClass.class,
AnotherClass.class
})
public void configureReflection() {
// Les classes annotées seront disponibles pour réflexion
}
// Solution 3 : RuntimeHints programmatique
public void registerHints(RuntimeHints hints) {
hints.reflection().registerType(
SomeClass.class,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_DECLARED_METHODS
);
}
}Ressources manquantes
Les fichiers de ressources doivent être explicitement déclarés pour être inclus dans l'image native.
// Configuration des ressources à inclure
{
"resources": {
"includes": [
{"pattern": "application\\.yml"},
{"pattern": "application-.*\\.yml"},
{"pattern": "messages.*\\.properties"},
{"pattern": "templates/.*\\.html"},
{"pattern": "static/.*"},
{"pattern": "db/migration/.*\\.sql"}
],
"excludes": [
{"pattern": ".*\\.java"},
{"pattern": ".*\\.class"}
]
},
"bundles": [
{"name": "messages"},
{"name": "ValidationMessages"}
]
}// Configuration programmatique des ressources
@Configuration
@ImportRuntimeHints(ResourceHintsConfig.ResourceHints.class)
public class ResourceHintsConfig {
static class ResourceHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
// Fichiers YAML/Properties
hints.resources()
.registerPattern("application*.yml")
.registerPattern("application*.properties");
// Templates Thymeleaf
hints.resources().registerPattern("templates/**");
// Scripts SQL Flyway
hints.resources().registerPattern("db/migration/*.sql");
// Fichiers statiques
hints.resources().registerPattern("static/**");
// Bundles de messages
hints.resources().registerResourceBundle("messages");
hints.resources().registerResourceBundle("ValidationMessages");
}
}
}Problèmes avec les proxies
Les proxies JDK et CGLIB nécessitent une configuration spécifique pour fonctionner en mode natif.
// Gestion des proxies pour compilation native
@Configuration
public class ProxyConfiguration implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
// Proxies JDK pour interfaces Spring Data
hints.proxies().registerJdkProxy(
UserRepository.class,
Repository.class,
CrudRepository.class
);
// Proxies pour interfaces de service
hints.proxies().registerJdkProxy(
PaymentService.class,
TransactionalService.class
);
}
// Alternative : forcer les proxies CGLIB
@Bean
public BeanFactoryPostProcessor forceProxyTargetClass() {
return beanFactory -> {
// Utilise CGLIB au lieu de JDK proxies
// Plus compatible avec la compilation native
};
}
}Déploiement Docker et Kubernetes
Dockerfile multi-stage optimisé
Le build multi-stage sépare la compilation de l'exécution pour une image minimale.
# Dockerfile
# Build multi-stage pour Spring Boot Native
# Stage 1: Build avec GraalVM
FROM ghcr.io/graalvm/graalvm-community:21 AS builder
# Installe Native Image
RUN gu install native-image
WORKDIR /app
# Copie les fichiers de build
COPY pom.xml .
COPY src ./src
# Installe Maven
RUN microdnf install -y maven
# Build native avec cache des dépendances
RUN \
mvn -Pnative native:compile -DskipTests
# Stage 2: Image runtime minimale
FROM gcr.io/distroless/base-debian12
WORKDIR /app
# Copie l'exécutable natif
COPY /app/target/native-demo /app/native-demo
# Port exposé
EXPOSE 8080
# Healthcheck
HEALTHCHECK \
CMD ["/app/native-demo", "--health"]
# Exécution
ENTRYPOINT ["/app/native-demo"]# Dockerfile.alpine
# Alternative avec Alpine pour image encore plus légère
FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN \
mvn -Pnative native:compile \
-Dspring-boot.aot.jvmArguments="-Dspring.aot.processing.resource.matching.strategy=GLOB" \
-DskipTests
# Image Alpine minimale (< 20 MB)
FROM alpine:3.19
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY /app/target/native-demo /app/native-demo
EXPOSE 8080
ENTRYPOINT ["/app/native-demo"]Déploiement Kubernetes avec ressources optimisées
Les applications natives nécessitent moins de ressources que les applications JVM traditionnelles.
# kubernetes/deployment.yaml
# Déploiement Kubernetes optimisé pour native
apiVersion: apps/v1
kind: Deployment
metadata:
name: native-demo
spec:
replicas: 3
selector:
matchLabels:
app: native-demo
template:
metadata:
labels:
app: native-demo
spec:
containers:
- name: native-demo
image: registry.example.com/native-demo:1.0.0
ports:
- containerPort: 8080
# Ressources réduites grâce au native
resources:
requests:
memory: "64Mi" # vs 256Mi pour JVM
cpu: "50m" # vs 200m pour JVM
limits:
memory: "128Mi" # vs 512Mi pour JVM
cpu: "200m" # vs 500m pour JVM
# Probes rapides (démarrage instantané)
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 1 # vs 30s pour JVM
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 2 # vs 60s pour JVM
periodSeconds: 10
failureThreshold: 3
# Variables d'environnement
env:
- name: SPRING_PROFILES_ACTIVE
value: "production"
- name: JAVA_TOOL_OPTIONS
value: "" # Pas besoin d'options JVM
---
apiVersion: v1
kind: Service
metadata:
name: native-demo
spec:
selector:
app: native-demo
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: native-demo-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: native-demo
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70Le temps de démarrage instantané permet un scaling horizontal très rapide. Les nouveaux pods sont prêts en quelques secondes, idéal pour les workloads avec pics de charge.
Tests et validation de l'image native
Configuration des tests natifs
Les tests peuvent également être compilés et exécutés en mode natif pour valider le comportement.
// Tests d'intégration pour validation native
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {
"spring.datasource.url=jdbc:h2:mem:testdb",
"spring.jpa.hibernate.ddl-auto=create-drop"
})
class NativeIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private UserRepository userRepository;
@Test
void shouldCreateAndRetrieveUser() {
// Arrange : création d'un utilisateur
UserDTO request = new UserDTO("John", "john@example.com");
// Act : appel API
ResponseEntity<UserDTO> createResponse = restTemplate.postForEntity(
"/api/users",
request,
UserDTO.class
);
// Assert : vérification création
assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED);
assertThat(createResponse.getBody()).isNotNull();
assertThat(createResponse.getBody().getName()).isEqualTo("John");
// Vérification récupération
Long userId = createResponse.getBody().getId();
ResponseEntity<UserDTO> getResponse = restTemplate.getForEntity(
"/api/users/{id}",
UserDTO.class,
userId
);
assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(getResponse.getBody().getEmail()).isEqualTo("john@example.com");
}
@Test
void shouldHandleReflectionCorrectly() {
// Test spécifique pour valider la configuration de réflexion
User user = new User();
user.setName("Test");
user.setEmail("test@example.com");
// L'ORM utilise la réflexion pour mapper les entités
User saved = userRepository.save(user);
assertThat(saved.getId()).isNotNull();
assertThat(userRepository.findById(saved.getId())).isPresent();
}
}<!-- pom.xml -->
<!-- Configuration des tests natifs -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<testArgs>
<!-- Inclut les tests dans le build native -->
<testArg>--verbose</testArg>
</testArgs>
</configuration>
<executions>
<execution>
<id>test-native</id>
<goals>
<goal>test</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
</plugin>Prêt à réussir tes entretiens Spring Boot ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Conclusion
La compilation native avec GraalVM transforme les applications Spring Boot 3 en exécutables performants. Les points essentiels à retenir :
Configuration du projet :
- ✅ Spring Boot 3.2+ avec plugin GraalVM natif
- ✅ RuntimeHints pour la réflexion et les ressources
- ✅ Agent de tracing pour découverte automatique
Optimisations de build :
- ✅ Options de compilation adaptées (O2/O3, GC, compression)
- ✅ Initialisation au build time pour les composants statiques
- ✅ Quickbuild pour le développement, full build pour la production
Résolution des problèmes :
- ✅ Configuration explicite de la réflexion pour les bibliothèques tierces
- ✅ Déclaration des ressources à inclure
- ✅ Gestion des proxies JDK et CGLIB
Déploiement :
- ✅ Images Docker multi-stage avec distroless
- ✅ Ressources Kubernetes réduites (64 Mi vs 256 Mi)
- ✅ Probes avec délais minimaux (démarrage instantané)
La compilation native est idéale pour les microservices, les fonctions serverless et les environnements à ressources limitées. Le temps de démarrage instantané et la faible consommation mémoire compensent largement le temps de build plus long.
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
Tags
Partager
Articles similaires

Spring Boot logging en 2026 : logs structurés pour la production avec Logback et JSON
Guide complet des logs structurés Spring Boot. Configuration Logback JSON, MDC pour le tracing, best practices production et intégration ELK Stack.

Spring Kafka : architecture event-driven avec consumers résilients
Guide complet Spring Kafka pour architectures event-driven. Configuration, consumers résilients, retry policies, dead letter queues et patterns de production pour applications distribuées.

Spring GraphQL en entretien : resolvers, DataLoaders et gestion du problème N+1
Préparez vos entretiens Spring GraphQL avec ce guide complet. Resolvers, DataLoaders, gestion N+1, mutations et bonnes pratiques pour réussir vos questions techniques.