Spring Boot 4教程 / 第 120 节

第12章:GraalVM Native Image 增强

本章概述

Spring Boot 4 大幅改进了 GraalVM 原生镜像支持,提供更快的启动时间和更小的内存占用。

本章重点:

  • ✅ 原生镜像支持改进
  • ✅ 启动时间与内存优化
  • ✅ AOT (Ahead-of-Time) 编译
  • ✅ 构建配置简化

12.1 原生镜像构建

12.1.1 Maven 配置

pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.graalvm.buildtools</groupId>
            <artifactId>native-maven-plugin</artifactId>
            <configuration>
                <imageName>${project.artifactId}</imageName>
                <mainClass>com.example.Application</mainClass>
                <buildArgs>
                    <buildArg>--no-fallback</buildArg>
                    <buildArg>-H:+ReportExceptionStackTraces</buildArg>
                </buildArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

12.1.2 构建命令

# 构建原生镜像
./mvnw -Pnative native:compile

# 运行原生镜像
./target/my-app

12.2 性能对比

12.2.1 启动时间

模式启动时间内存占用包大小
JVM2.5s256MB50MB
Native (Boot 3)0.15s65MB80MB
Native (Boot 4)0.05s45MB60MB

改进:

  • ✅ 启动时间: 67% 更快
  • ✅ 内存占用: 31% 更少
  • ✅ 包大小: 25% 更小

12.2.2 运行时性能

@SpringBootApplication
public class NativeImageDemo {
    
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        SpringApplication.run(NativeImageDemo.class, args);
        long endTime = System.currentTimeMillis();
        
        System.out.println("Startup time: " + (endTime - startTime) + "ms");
    }
}

12.3 AOT 编译

12.3.1 启用 AOT

application.yml:

spring:
  aot:
    enabled: true
    processing:
      optimize-configuration: true
      remove-unused-autoconfig: true

12.3.2 AOT 提示

NativeHints.java:

@Configuration
public class NativeHints implements RuntimeHintsRegistrar {
    
    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        // 注册反射提示
        hints.reflection()
            .registerType(MyClass.class, 
                MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
                MemberCategory.INVOKE_DECLARED_METHODS);
        
        // 注册资源提示
        hints.resources()
            .registerPattern("config/*.properties");
    }
}

12.4 Docker 集成

Dockerfile:

FROM ghcr.io/graalvm/native-image:ol8-java21 AS builder

WORKDIR /app
COPY . .
RUN ./mvnw -Pnative native:compile

FROM gcr.io/distroless/base

COPY --from=builder /app/target/my-app /app
ENTRYPOINT ["/app"]

12.5 最佳实践

12.5.1 优化建议

  1. 避免反射: 尽量使用编译时已知的类型
  2. 资源文件: 明确声明所有资源文件
  3. 动态代理: 注册所有代理接口
  4. 序列化: 注册需要序列化的类

12.5.2 常见问题

问题: ClassNotFoundException 解决: 添加反射配置

{
  "name": "com.example.MyClass",
  "allDeclaredConstructors": true,
  "allDeclaredMethods": true
}

12.6 小结

原生镜像改进

  • 更快的启动(0.05s)
  • 更少的内存(45MB)
  • 更小的包(60MB)

AOT 编译

  • 编译时优化
  • 移除未使用的配置

简化的构建

  • 一条命令构建
  • Docker 集成

导航: