AOT-bearbetning och den inbyggda byggpipen
Förstå Springs ahead-of-time-motor och bygg native-avbildningar med GraalVM-verktygskedjan.
AOT-bearbetning och den inbyggda byggpipen är en gratis lektion i Spring Boot 4 – komplett guide på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Spring Boot 4 – komplett guide, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Varför native images?
En traditionell Spring Boot-applikation körs på JVM: bytekod läses in, klasser verifieras och JIT-kompilatorn värms upp över tid. Det ger hög toppgenomströmning, men kostar i uppstartstid och minnesanvändning.
GraalVM native images vänder på modellen. I stället för att leverera bytekod tillsammans med en JVM skapar ni en enda fristående körbar fil, där nästan allt arbete som normalt utförs vid körning flyttas till byggtiden.
- Uppstartstiden minskar från sekunder till tiotals millisekunder.
- Minnesanvändningen minskar drastiskt (ingen JIT och inga omfattande klassmetadata).
- Avvägning: längre och tyngre byggen samt ett antagande om en sluten värld.
Detta gör native images idealiska för serverless, CLI-verktyg och containrar med hög densitet.
Antagandet om en sluten värld
GraalVM:s native-kompilator (native-image) utför statisk analys av hela programmet och inkluderar endast kod som den kan bevisa är nåbar. Allt måste vara känt vid byggtiden – detta är antagandet om en sluten värld.
De funktioner som gör Spring flexibelt vid körning är precis de som orsakar problem vid analys med en sluten värld:
- Reflection – anrop av metoder eller fält som identifieras med namn vid körning.
- Dynamiska proxier – Spring AOP,
@Transactionaloch repository-gränssnitt. - Resursinläsning – filer som hittas via sökväg vid körning.
- Serialisering samt generering av klasser vid körning.
Spring:s AOT-motor finns för att överbrygga detta gap: den analyserar applikationen i förväg och genererar de metadata och den kod som GraalVM behöver.
Vad Spring AOT faktiskt gör
När ni bygger för native (eller bara aktiverar AOT) kör Spring en fas för förhandsbearbetning som omvandlar den dynamiska applikationskontexten till en statisk, förberäknad form.
Spring AOT genererar konkret:
- Bean-definitionkod – i stället för att skanna och tolka vid körning genererar Spring Java-källkod (
*__BeanDefinitions.java) som registrerar beans programmatiskt. - En
ApplicationContextInitializersom kopplar ihop kontexten utan scanning av classpath. - GraalVM:s metadata för nåbarhet – JSON-hintar för reflection, resurser, proxier och serialisering.
Körningskontexten blir i praktiken fryst: mängden beans fastställs vid byggtiden. Ni kan inte lägga till beans dynamiskt efter AOT-bearbetningen.
Aktivera AOT i bygget
Spring AOT styrs av byggpluginer. Med Maven exponerar spring-boot-maven-plugin ett process-aot-mål; profilen native kopplar ihop det med GraalVM:s native-maven-plugin.
Det viktiga beroendet för native-byggen är pluginen för GraalVM:s verktygskedja. Här är en typisk Maven-konfiguration som aktiverar AOT och native-kompilering.
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>Native-byggpipeline steg för steg
Att bygga en native image är en pipeline i flera steg. Om ni förstår ordningen blir det lättare att hitta fel.
- 1. Kompilera – normal
javac-kompilering av källkoden. - 2. AOT-bearbetning – Spring kör
process-aotoch genererar källkod för bean-definitioner samt metadata för nåbarhet undertarget/spring-aot. - 3. AOT-kompilering – de genererade källfilerna kompileras tillsammans med er kod.
- 4.
native-image– GraalVM utför statisk analys (steget med den slutna världen) och skapar en körbar native-fil.
Starta detta med Maven via native-profilen:
# Produce the native executable in target/
./mvnw -Pnative native:compile
# Or build a native container image with buildpacks
./mvnw -Pnative spring-boot:build-imageRuntime hints: det programmatiska API:et
Spring AOT upptäcker det mesta av användningen av reflection automatiskt, men för er egen dynamiska kod (till exempel en klass som ni läser in med reflection) måste ni deklarera hints. Det idiomatiska sättet är att använda en RuntimeHintsRegistrar.
Registrera registreraren med @ImportRuntimeHints på en konfiguration eller komponent. Vid AOT-bearbetningen anropar Spring den och införlivar era hints i GraalVM:s metadata.
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
public class MyRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(
com.example.PaymentProcessor.class,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_PUBLIC_METHODS);
hints.resources().registerPattern("config/*.properties");
}
}Koppla in hints i kontexten
En RuntimeHintsRegistrar gör ingenting förrän Spring känner till den. Koppla in den med @ImportRuntimeHints så att den deltar i AOT-bearbetningen.
På så sätt hålls native-specifik kunskap nära koden som behöver den, i stället för i en separat JSON-fil som ni måste underhålla manuellt.
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
@Configuration
@ImportRuntimeHints(MyRuntimeHints.class)
public class NativeConfig {
// Beans defined here are processed with the hints above
}Genvägen @RegisterReflectionForBinding
Det vanligaste skälet till att hints behövs är serialisering/deserialisering av DTO:er – Jackson använder reflection för era klasser. Att skriva en fullständig registrar för varje DTO är omständligt.
Spring erbjuder @RegisterReflectionForBinding, som automatiskt registrerar de reflection-metadata som behövs för att binda (serialisera/deserialisera) de angivna typerna.
import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RegisterReflectionForBinding({ OrderResponse.class, OrderItem.class })
class OrderController {
@GetMapping("/orders/latest")
OrderResponse latest() {
return new OrderResponse("A-100", List.of(new OrderItem("sku-1", 2)));
}
}GraalVM:s tracing agent
För tredjepartsbibliotek som använder reflection men inte levererar någon metadata kan AOT-motorn inte alltid härleda de nödvändiga hintsen. Reservlösningen är GraalVM:s tracing agent.
Kör applikationen på JVM med agenten ansluten och kör dess kodvägar (tester eller en smoke-körning). Agenten registrerar varje reflective åtkomst, resursinläsning och proxy och skriver dem som JSON-metadata.
- Resultatet hamnar under
META-INF/native-image/. - Endast kodvägar som faktiskt körs fångas – ofullständig testtäckning innebär att hints saknas.
- Betrakta detta som en sista utväg; föredra repositorier med metadata för nåbarhet och Spring:s automatiska upptäckt i första hand.
# Attach the tracing agent while running tests on the JVM
java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image \
-jar target/app.jarInitiering vid byggtid kontra körning
Ett subtilt men kritiskt koncept är att native-image kan köra statiska initierare vid byggtiden och baka in det resulterande tillståndet i imagen. Spring Boot:s standardinställningar flyttar det mesta av applikationsinitieringen till byggtiden för att öka hastigheten.
Detta orsakar ett klassiskt fel: allt som fångar miljöspecifikt eller tidskänsligt tillstånd i en static-initierare blir fryst vid byggtiden.
- Ett
static final SecureRandom seedsom beräknas vid byggtiden skulle vara identiskt på alla maskiner. - Om en miljövariabel läses i ett statiskt block fångas byggserverns värde, inte produktionens.
Lösningen är att skjuta upp sådant arbete till körningen (till exempel till en @Bean-metod eller lazy init), så att det utförs när den körbara filen faktiskt startar.
@Configuration
class CryptoConfig {
// Created when the native executable starts, NOT at build time
@Bean
SecureRandom secureRandom() {
return new SecureRandom();
}
}Verifiera och felsök native-bygget
Native-byggen misslyckas på andra sätt än JVM-applikationer. Två vanor sparar många timmar:
- Testa AOT-vägen på JVM först. Kör i läget
springAoteller med den genererade kontexten innan ni utför det långsamma steget mednative-image– de flesta problem med bean-koppling visar sig här på några sekunder. - Läs felen från den statiska analysen. Ett
ClassNotFoundExceptionellerNo instances of X are allowed in the image heapvid körning betyder nästan alltid att en hint för reflection eller resurser saknas, eller att en initiering oavsiktligt sker vid byggtiden.
Ni kan köra den AOT-bearbetade applikationen på JVM för att snabbt validera den frysta kontexten:
# Run the AOT-optimized context on a regular JVM (fast feedback loop)
./mvnw spring-boot:run -Dspring-boot.run.profiles=default \
-Dspring.aot.enabled=trueSnabb kontroll: AOT och native-pipelinen
Testa er förståelse av hur Spring:s AOT-motor samarbetar med GraalVM.
Sammanfattning: AOT-bearbetning och native-pipelinen
Ni förstår nu hur Spring Boot 4 omvandlar en dynamisk applikation till en körbar native-fil:
- Varför native: uppstart på millisekunder och låg minnesanvändning, på bekostnad av långsamma byggen och ett antagande om en sluten värld.
- Spring AOT körs vid byggtiden och genererar kod för bean-definitioner, en
ApplicationContextInitializersamt metadata för GraalVM:s nåbarhet; mängden beans blir fryst. - Pipelinen: kompilera →
process-aot→ kompilera genererade källfiler → statisk analys mednative-image. - Hints: använd
RuntimeHintsRegistrar+@ImportRuntimeHintsför egna behov,@RegisterReflectionForBindingför DTO:er och tracing agent som sista utväg för ogenomskinliga bibliotek. - Se upp med initiering vid byggtiden, eftersom den fryser tillstånd; skjut upp miljö- och tidskänsligt arbete till beans vid körning.
- Felsök snabbt genom att köra AOT-kontexten på JVM innan det långsamma native-bygget.
Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 21
- Lektioner
- 84
Vanliga frågor
Är lektionen ”AOT-bearbetning och den inbyggda byggpipen” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Spring Boot 4 – komplett guide, inklusive ”AOT-bearbetning och den inbyggda byggpipen”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Vad lär jag mig i ”AOT-bearbetning och den inbyggda byggpipen”?
Förstå Springs ahead-of-time-motor och bygg native-avbildningar med GraalVM-verktygskedjan. Ni övar på Spring Boot 4 – komplett guide med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Spring Boot 4 – komplett guide?
Du behöver inga förkunskaper. Utbildningen i Spring Boot 4 – komplett guide på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”AOT-bearbetning och den inbyggda byggpipen”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Spring Boot 4 – komplett guide-lektionen?
Ja. Varje Spring Boot 4 – komplett guide-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- AOT-bearbetning och den inbyggda byggpipen
- Körningsledtrådar för reflektion och resurser
- Class Data Sharing och finjustering av JVM-start
- Diagnostisera och åtgärda kompatibilitetsproblem för native