1. 环境要求

1.1 系统要求

  • 操作系统: Linux、macOS 或 Windows
  • 内存: 至少 8GB RAM(推荐 16GB)
  • 磁盘空间: 至少 10GB 可用空间
  • 网络: 稳定的网络连接用于下载依赖

1.2 软件依赖

# 必需软件版本
Java: 17 或更高版本
GraalVM: 22.3.0 或更高版本
Maven: 3.8.0 或更高版本
Docker: 20.10.0 或更高版本(可选)
Git: 2.30.0 或更高版本

2. GraalVM 安装

2.1 下载和安装

# Linux/macOS 安装脚本
#!/bin/bash
# install-graalvm.sh

set -e

# 配置变量
GRAALVM_VERSION="22.3.0"
JAVA_VERSION="17"
PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)

# 确定架构
case $ARCH in
    x86_64)
        ARCH="amd64"
        ;;
    aarch64|arm64)
        ARCH="aarch64"
        ;;
    *)
        echo "不支持的架构: $ARCH"
        exit 1
        ;;
esac

# 下载 GraalVM
echo "下载 GraalVM $GRAALVM_VERSION for $PLATFORM-$ARCH..."
GRAALVM_URL="https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-$GRAALVM_VERSION/graalvm-ce-java$JAVA_VERSION-$PLATFORM-$ARCH-$GRAALVM_VERSION.tar.gz"

# 创建安装目录
INSTALL_DIR="/opt/graalvm"
sudo mkdir -p $INSTALL_DIR

# 下载并解压
wget -O graalvm.tar.gz $GRAALVM_URL
sudo tar -xzf graalvm.tar.gz -C $INSTALL_DIR --strip-components=1
rm graalvm.tar.gz

# 设置环境变量
echo "设置环境变量..."
echo 'export GRAALVM_HOME=/opt/graalvm' | sudo tee -a /etc/environment
echo 'export JAVA_HOME=$GRAALVM_HOME' | sudo tee -a /etc/environment
echo 'export PATH=$GRAALVM_HOME/bin:$PATH' | sudo tee -a /etc/environment

# 安装 Native Image
echo "安装 Native Image..."
sudo $INSTALL_DIR/bin/gu install native-image

# 验证安装
echo "验证安装..."
$INSTALL_DIR/bin/java -version
$INSTALL_DIR/bin/native-image --version

echo "GraalVM 安装完成!"
echo "请重新加载环境变量: source /etc/environment"

2.2 Windows 安装

# Windows PowerShell 安装脚本
# install-graalvm.ps1

param(
    [string]$Version = "22.3.0",
    [string]$JavaVersion = "17",
    [string]$InstallPath = "C:\graalvm"
)

# 检查管理员权限
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Error "请以管理员身份运行此脚本"
    exit 1
}

# 下载 GraalVM
$downloadUrl = "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-$Version/graalvm-ce-java$JavaVersion-windows-amd64-$Version.zip"
$zipFile = "$env:TEMP\graalvm.zip"

Write-Host "下载 GraalVM $Version..."
Invoke-WebRequest -Uri $downloadUrl -OutFile $zipFile

# 创建安装目录
if (Test-Path $InstallPath) {
    Remove-Item $InstallPath -Recurse -Force
}
New-Item -ItemType Directory -Path $InstallPath -Force

# 解压
Write-Host "解压到 $InstallPath..."
Expand-Archive -Path $zipFile -DestinationPath $InstallPath -Force

# 移动文件到正确位置
$extractedDir = Get-ChildItem $InstallPath | Where-Object { $_.Name -like "graalvm-*" } | Select-Object -First 1
if ($extractedDir) {
    $items = Get-ChildItem $extractedDir.FullName
    foreach ($item in $items) {
        Move-Item $item.FullName $InstallPath
    }
    Remove-Item $extractedDir.FullName -Force
}

# 设置环境变量
Write-Host "设置环境变量..."
[Environment]::SetEnvironmentVariable("GRAALVM_HOME", $InstallPath, "Machine")
[Environment]::SetEnvironmentVariable("JAVA_HOME", $InstallPath, "Machine")

$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($currentPath -notlike "*$InstallPath\bin*") {
    [Environment]::SetEnvironmentVariable("Path", "$InstallPath\bin;$currentPath", "Machine")
}

# 安装 Native Image
Write-Host "安装 Native Image..."
& "$InstallPath\bin\gu.cmd" install native-image

# 清理
Remove-Item $zipFile -Force

# 验证安装
Write-Host "验证安装..."
& "$InstallPath\bin\java.exe" -version
& "$InstallPath\bin\native-image.exe" --version

Write-Host "GraalVM 安装完成!"
Write-Host "请重启 PowerShell 以使环境变量生效"

2.3 Docker 方式安装

# Dockerfile.graalvm
FROM ghcr.io/graalvm/graalvm-ce:22.3.0-java17

# 安装必要工具
RUN microdnf update && \
    microdnf install -y wget unzip git && \
    microdnf clean all

# 安装 Native Image
RUN gu install native-image

# 安装 Maven
ENV MAVEN_VERSION=3.9.0
RUN wget https://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz && \
    tar -xzf apache-maven-$MAVEN_VERSION-bin.tar.gz -C /opt && \
    ln -s /opt/apache-maven-$MAVEN_VERSION /opt/maven && \
    rm apache-maven-$MAVEN_VERSION-bin.tar.gz

ENV MAVEN_HOME=/opt/maven
ENV PATH=$MAVEN_HOME/bin:$PATH

# 设置工作目录
WORKDIR /workspace

# 验证安装
RUN java -version && \
    native-image --version && \
    mvn -version

CMD ["/bin/bash"]
# 构建和使用 Docker 镜像
docker build -f Dockerfile.graalvm -t graalvm-dev .
docker run -it -v $(pwd):/workspace graalvm-dev

3. IDE 配置

3.1 IntelliJ IDEA 配置

<!-- .idea/misc.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="GraalVM 22.3.0" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/out" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Maven" />
  </component>
</project>
<!-- .idea/compiler.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CompilerConfiguration">
    <annotationProcessing>
      <profile name="Maven default annotation processors profile" enabled="true">
        <sourceOutputDir name="target/generated-sources/annotations" />
        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
        <outputRelativeToContentRoot value="true" />
        <module name="spring-native-demo" />
      </profile>
    </annotationProcessing>
    <bytecodeTargetLevel>
      <module name="spring-native-demo" target="17" />
    </bytecodeTargetLevel>
  </component>
</project>

3.2 VS Code 配置

// .vscode/settings.json
{
    "java.home": "/opt/graalvm",
    "java.configuration.runtimes": [
        {
            "name": "GraalVM",
            "path": "/opt/graalvm",
            "default": true
        }
    ],
    "java.compile.nullAnalysis.mode": "automatic",
    "java.format.settings.url": "https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml",
    "spring-boot.ls.problem.application-properties.unknown-property": "warning",
    "files.associations": {
        "*.yml": "yaml",
        "*.yaml": "yaml"
    }
}
// .vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Spring Boot App",
            "request": "launch",
            "mainClass": "com.example.Application",
            "projectName": "spring-native-demo",
            "args": "",
            "envFile": "${workspaceFolder}/.env",
            "vmArgs": "-Dspring.profiles.active=dev"
        },
        {
            "type": "java",
            "name": "Native Image Debug",
            "request": "launch",
            "mainClass": "com.example.Application",
            "projectName": "spring-native-demo",
            "vmArgs": "-agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image"
        }
    ]
}
// .vscode/tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "maven-compile",
            "type": "shell",
            "command": "mvn",
            "args": ["clean", "compile"],
            "group": "build",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared"
            }
        },
        {
            "label": "native-compile",
            "type": "shell",
            "command": "mvn",
            "args": ["-Pnative", "native:compile"],
            "group": "build",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared"
            },
            "dependsOn": "maven-compile"
        },
        {
            "label": "native-test",
            "type": "shell",
            "command": "mvn",
            "args": ["-Pnative", "test"],
            "group": "test",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared"
            }
        }
    ]
}

4. 项目初始化

4.1 使用 Spring Initializr

# 使用 curl 创建项目
curl https://start.spring.io/starter.zip \
  -d dependencies=web,actuator,native \
  -d type=maven-project \
  -d language=java \
  -d bootVersion=3.0.0 \
  -d baseDir=spring-native-demo \
  -d groupId=com.example \
  -d artifactId=spring-native-demo \
  -d name=spring-native-demo \
  -d description="Spring Native Demo" \
  -d packageName=com.example.demo \
  -d packaging=jar \
  -d javaVersion=17 \
  -o spring-native-demo.zip

unzip spring-native-demo.zip
cd spring-native-demo

4.2 Maven 配置

<!-- pom.xml -->
<?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 
         http://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.0.0</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>spring-native-demo</artifactId>
    <version>1.0.0</version>
    <name>spring-native-demo</name>
    <description>Spring Native Demo Application</description>
    
    <properties>
        <java.version>17</java.version>
        <spring-native.version>0.12.1</spring-native.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        <!-- Spring Boot Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        
        <!-- Database -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <!-- JSON Processing -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        
        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-launcher</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <!-- Spring Boot Maven Plugin -->
            <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>
            </plugin>
            
            <!-- Native Build Tools Plugin -->
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <version>0.9.18</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <id>test-native</id>
                        <phase>test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>build-native</id>
                        <phase>package</phase>
                        <goals>
                            <goal>compile-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <fallback>false</fallback>
                    <verbose>true</verbose>
                    <sharedLibrary>false</sharedLibrary>
                    <buildArgs>
                        <buildArg>--no-fallback</buildArg>
                        <buildArg>--enable-url-protocols=http,https</buildArg>
                        <buildArg>--initialize-at-build-time</buildArg>
                        <buildArg>-H:+ReportExceptionStackTraces</buildArg>
                        <buildArg>-H:+RemoveUnusedSymbols</buildArg>
                        <buildArg>-H:+UseCompressedOops</buildArg>
                        <buildArg>-H:ConfigurationFileDirectories=src/main/resources/META-INF/native-image</buildArg>
                    </buildArgs>
                </configuration>
            </plugin>
            
            <!-- Compiler Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
            
            <!-- Surefire Plugin for Tests -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M8</version>
                <configuration>
                    <argLine>-Dfile.encoding=UTF-8</argLine>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
    <profiles>
        <!-- Native Profile -->
        <profile>
            <id>native</id>
            <properties>
                <repackage.classifier>exec</repackage.classifier>
                <native-buildtools.version>0.9.18</native-buildtools.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-launcher</artifactId>
                    <scope>test</scope>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>${native-buildtools.version}</version>
                        <extensions>true</extensions>
                        <executions>
                            <execution>
                                <id>test-native</id>
                                <phase>test</phase>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>build-native</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>compile-no-fork</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        
        <!-- Development Profile -->
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <spring.profiles.active>dev</spring.profiles.active>
            </properties>
        </profile>
        
        <!-- Production Profile -->
        <profile>
            <id>prod</id>
            <properties>
                <spring.profiles.active>prod</spring.profiles.active>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <configuration>
                            <jvmArguments>
                                -Dspring.profiles.active=prod
                            </jvmArguments>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    
    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

4.3 Gradle 配置

// build.gradle
plugins {
    id 'org.springframework.boot' version '3.0.0'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'org.graalvm.buildtools.native' version '0.9.18'
    id 'java'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/release' }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    
    runtimeOnly 'com.h2database:h2'
    
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
    useJUnitPlatform()
}

// Native Image Configuration
graalvmNative {
    binaries {
        main {
            fallback.set(false)
            verbose.set(true)
            buildArgs.add('--no-fallback')
            buildArgs.add('--enable-url-protocols=http,https')
            buildArgs.add('--initialize-at-build-time')
            buildArgs.add('-H:+ReportExceptionStackTraces')
            buildArgs.add('-H:+RemoveUnusedSymbols')
            buildArgs.add('-H:+UseCompressedOops')
            buildArgs.add('-H:ConfigurationFileDirectories=src/main/resources/META-INF/native-image')
        }
        test {
            fallback.set(false)
            verbose.set(true)
        }
    }
}

// Task for generating native image configuration
task generateNativeConfig(type: JavaExec) {
    classpath = sourceSets.main.runtimeClasspath
    mainClass = 'com.example.demo.Application'
    jvmArgs = [
        '-agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image'
    ]
}

5. 配置文件

5.1 应用配置

# src/main/resources/application.yml
spring:
  application:
    name: spring-native-demo
  
  profiles:
    active: dev
  
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password: 
  
  h2:
    console:
      enabled: true
      path: /h2-console
  
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
    properties:
      hibernate:
        format_sql: true
  
  jackson:
    serialization:
      write-dates-as-timestamps: false
    time-zone: UTC
  
  web:
    resources:
      static-locations: classpath:/static/
      cache:
        period: 3600

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true

logging:
  level:
    com.example: DEBUG
    org.springframework.web: DEBUG
    org.hibernate.SQL: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/application.log

---
# Development Profile
spring:
  config:
    activate:
      on-profile: dev
  
  datasource:
    url: jdbc:h2:mem:devdb
  
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true

logging:
  level:
    root: INFO
    com.example: DEBUG

---
# Production Profile
spring:
  config:
    activate:
      on-profile: prod
  
  datasource:
    url: jdbc:h2:file:./data/proddb
  
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

logging:
  level:
    root: WARN
    com.example: INFO
  file:
    name: /var/log/spring-native-demo/application.log

management:
  endpoints:
    web:
      exposure:
        include: health,metrics

5.2 原生镜像配置

// src/main/resources/META-INF/native-image/reflect-config.json
[
  {
    "name": "com.example.demo.model.User",
    "allDeclaredConstructors": true,
    "allDeclaredMethods": true,
    "allDeclaredFields": true
  },
  {
    "name": "com.example.demo.dto.UserDto",
    "allDeclaredConstructors": true,
    "allDeclaredMethods": true,
    "allDeclaredFields": true
  },
  {
    "name": "java.lang.String",
    "allDeclaredConstructors": true,
    "allPublicMethods": true
  },
  {
    "name": "java.util.ArrayList",
    "allDeclaredConstructors": true
  },
  {
    "name": "java.util.HashMap",
    "allDeclaredConstructors": true
  }
]
// src/main/resources/META-INF/native-image/resource-config.json
{
  "resources": {
    "includes": [
      {
        "pattern": "application.*\.yml"
      },
      {
        "pattern": "application.*\.yaml"
      },
      {
        "pattern": "application.*\.properties"
      },
      {
        "pattern": "static/.*"
      },
      {
        "pattern": "templates/.*"
      },
      {
        "pattern": "META-INF/spring.factories"
      },
      {
        "pattern": "META-INF/spring/.*"
      }
    ]
  },
  "bundles": [
    {
      "name": "messages",
      "locales": ["en", "zh"]
    }
  ]
}
// src/main/resources/META-INF/native-image/serialization-config.json
[
  {
    "name": "com.example.demo.model.User"
  },
  {
    "name": "com.example.demo.dto.UserDto"
  },
  {
    "name": "java.util.ArrayList"
  },
  {
    "name": "java.util.HashMap"
  }
]
// src/main/resources/META-INF/native-image/proxy-config.json
[
  {
    "interfaces": [
      "com.example.demo.repository.UserRepository",
      "org.springframework.data.repository.Repository",
      "org.springframework.transaction.interceptor.TransactionalProxy",
      "org.springframework.aop.framework.Advised",
      "org.springframework.core.DecoratingProxy"
    ]
  }
]

6. 验证安装

6.1 环境验证脚本

#!/bin/bash
# verify-environment.sh

set -e

echo "=== Spring Native 环境验证 ==="

# 检查 Java 版本
echo "检查 Java 版本..."
if command -v java &> /dev/null; then
    JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2)
    echo "✓ Java 版本: $JAVA_VERSION"
    
    # 检查是否是 GraalVM
    if java -version 2>&1 | grep -q "GraalVM"; then
        echo "✓ 使用 GraalVM"
    else
        echo "⚠ 警告: 未使用 GraalVM,建议使用 GraalVM"
    fi
else
    echo "✗ 错误: 未找到 Java"
    exit 1
fi

# 检查 Native Image
echo "检查 Native Image..."
if command -v native-image &> /dev/null; then
    NATIVE_VERSION=$(native-image --version | head -n 1)
    echo "✓ Native Image: $NATIVE_VERSION"
else
    echo "✗ 错误: 未找到 native-image"
    exit 1
fi

# 检查 Maven
echo "检查 Maven..."
if command -v mvn &> /dev/null; then
    MVN_VERSION=$(mvn -version | head -n 1)
    echo "✓ Maven: $MVN_VERSION"
else
    echo "✗ 错误: 未找到 Maven"
    exit 1
fi

# 检查 Git
echo "检查 Git..."
if command -v git &> /dev/null; then
    GIT_VERSION=$(git --version)
    echo "✓ Git: $GIT_VERSION"
else
    echo "⚠ 警告: 未找到 Git"
fi

# 检查 Docker(可选)
echo "检查 Docker..."
if command -v docker &> /dev/null; then
    DOCKER_VERSION=$(docker --version)
    echo "✓ Docker: $DOCKER_VERSION"
else
    echo "⚠ 信息: 未找到 Docker(可选)"
fi

# 检查环境变量
echo "检查环境变量..."
if [ -n "$GRAALVM_HOME" ]; then
    echo "✓ GRAALVM_HOME: $GRAALVM_HOME"
else
    echo "⚠ 警告: 未设置 GRAALVM_HOME"
fi

if [ -n "$JAVA_HOME" ]; then
    echo "✓ JAVA_HOME: $JAVA_HOME"
else
    echo "⚠ 警告: 未设置 JAVA_HOME"
fi

# 测试简单编译
echo "测试 Native Image 编译..."
cat > HelloWorld.java << 'EOF'
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Spring Native!");
    }
}
EOF

if javac HelloWorld.java && native-image HelloWorld; then
    echo "✓ Native Image 编译测试成功"
    if ./helloworld; then
        echo "✓ Native Image 执行测试成功"
    fi
    rm -f HelloWorld.java HelloWorld.class helloworld helloworld.exe
else
    echo "✗ 错误: Native Image 编译测试失败"
    rm -f HelloWorld.java HelloWorld.class
    exit 1
fi

echo "=== 环境验证完成 ==="
echo "✓ Spring Native 开发环境已就绪!"

6.2 项目验证

#!/bin/bash
# verify-project.sh

set -e

echo "=== 项目验证 ==="

# 编译项目
echo "编译项目..."
mvn clean compile
echo "✓ 项目编译成功"

# 运行测试
echo "运行测试..."
mvn test
echo "✓ 测试通过"

# 打包应用
echo "打包应用..."
mvn package -DskipTests
echo "✓ 应用打包成功"

# 运行 JAR
echo "测试 JAR 运行..."
java -jar target/*.jar --server.port=0 &
JAR_PID=$!
sleep 5
if kill -0 $JAR_PID 2>/dev/null; then
    echo "✓ JAR 运行成功"
    kill $JAR_PID
else
    echo "✗ JAR 运行失败"
    exit 1
fi

# 编译原生镜像
echo "编译原生镜像..."
mvn -Pnative native:compile
echo "✓ 原生镜像编译成功"

# 运行原生镜像
echo "测试原生镜像运行..."
./target/spring-native-demo --server.port=0 &
NATIVE_PID=$!
sleep 3
if kill -0 $NATIVE_PID 2>/dev/null; then
    echo "✓ 原生镜像运行成功"
    kill $NATIVE_PID
else
    echo "✗ 原生镜像运行失败"
    exit 1
fi

echo "=== 项目验证完成 ==="
echo "✓ Spring Native 项目配置正确!"

7. 核心要点

7.1 环境配置

  • GraalVM 安装: 正确安装和配置 GraalVM 及 Native Image
  • 环境变量: 设置 GRAALVM_HOME 和 JAVA_HOME
  • IDE 集成: 配置 IDE 支持 GraalVM 和 Spring Native
  • 构建工具: 配置 Maven 或 Gradle 支持原生编译

7.2 项目配置

  • 依赖管理: 选择兼容的依赖版本
  • 插件配置: 正确配置 Native Build Tools 插件
  • 配置文件: 创建必要的原生镜像配置文件
  • Profile 管理: 区分开发和生产环境配置

7.3 最佳实践

  • 渐进式迁移: 从简单项目开始,逐步迁移复杂应用
  • 配置生成: 使用 Agent 自动生成初始配置
  • 测试验证: 确保原生镜像和 JVM 版本行为一致
  • 性能监控: 监控编译时间和运行时性能

8. 下一步学习

  • 基础应用: 创建第一个 Spring Native 应用
  • 配置详解: 深入了解原生镜像配置选项
  • 性能优化: 学习原生镜像性能优化技巧
  • 部署实践: 了解原生镜像的部署和运维