Introduction to Spring Native – Spring本土化介绍

最后修改: 2021年 6月 29日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Native images provide various advantages like an instant startup and reduced memory consumption. Therefore, at times, we might want to build a native image of our Java application.

本地图像提供了各种优势,如即时启动和减少内存消耗。因此,有时候,我们可能想为我们的Java应用程序建立一个本地镜像。

In this tutorial, we’ll explore Spring Native to compile and build native images using Buildpacks and GraalVM’s native build tools.

在本教程中,我们将探讨Spring Native使用Buildpacks和GraalVM的本地构建工具来编译和构建本地镜像。

2. Basic Setup

2.基本设置

As a prerequisite, we’ll make sure to install Docker, required later to run native images.

作为先决条件,我们将确保安装Docker,这是以后运行本地图像所需要的

Then, we’ll create a simple Spring Boot project named baeldung-spring-native and use it throughout the tutorial to build a native image.

然后,我们将创建一个名为baeldung-spring-native的简单Spring Boot项目,并在整个教程中使用它来构建一个本地镜像。

Next, let’s add a link to the Spring repo to download dependencies and plugins required in later sections:

接下来,让我们添加一个指向Spring repo的链接,以下载后面章节所需的依赖和插件。

<repositories>
    <repository>
        <id>spring-release</id>
        <name>Spring release</name>
        <url>https://repo.spring.io/release</url>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>spring-release</id>
        <name>Spring release</name>
        <url>https://repo.spring.io/release</url>
    </pluginRepository>
</pluginRepositories>

Then, we’ll add the latest spring-native Maven dependency:

然后,我们将添加最新的spring-native Maven依赖。

<dependency>
    <groupId>org.springframework.experimental</groupId>
    <artifactId>spring-native</artifactId>
    <version>0.10.0</version>
</dependency>

However, for a Gradle project, Spring Native is automatically added by the Spring AOT plugin.

然而,对于Gradle项目,Spring Native是由Spring AOT插件自动添加的

We should note that each Spring Native version only supports a specific Spring Boot version – for example, Spring Native 0.10.0 supports Spring Boot 2.5.1. So, we should make sure to use the compatible Spring Boot Maven dependencies in our pom.xml.

我们应该注意,每个Spring Native版本只支持特定的Spring Boot版本 – 例如,Spring Native 0.10.0支持Spring Boot 2.5.1。因此,我们应该确保在pom.xml中使用兼容的Spring Boot Maven依赖项。

Next, we’ll add a few properties to use Java 8 for compilation:

接下来,我们将添加一些属性来使用Java 8进行编译。

<properties>
    <java.version>1.8</java.version>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

Last, we’ll create the SpringNativeApp class:

最后,我们将创建SpringNativeApp类。

public class SpringNativeApp {
    public static void main(String[] args) {
        System.out.println("Hello, World! This is a Baeldung Spring Native Application");
    }
}

3. Buildpacks

3.建设包

Now that our Spring Boot project, baeldung-spring-native, is ready with the basic setup, let’s integrate buildpacks in our Spring Boot project to build native images.

现在,我们的Spring Boot项目baeldung-spring-native已经准备好了基本设置,让我们在Spring Boot项目中集成buildpacks以构建本地图像

3.1. Spring Boot Maven Plugin

3.1 Spring Boot Maven Plugin

First, we’ll require the spring-boot-maven-plugin with native image configuration using the Paketo Java buildpacks:

首先,我们需要使用spring-boot-maven-plugin与本地镜像配置,使用Paketo Java buildpacks

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <image>
                    <builder>paketobuildpacks/builder:tiny</builder>
                    <env>
                        <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
                    </env>
                </image>
            </configuration>
        </plugin>
    </plugins>
</build>

Here, we’ll use the tiny builder out of the various available builders like base and full to build a native image. Also, we enabled the buildpack by providing the true value to the BP_NATIVE_IMAGE environment variable.

在这里,我们将使用tiny构建器来构建一个本地镜像,而不是像basefull这样的可用构建器。此外,我们通过为BP_NATIVE_IMAGE环境变量提供true值来启用构建包。

Similarly, when using Gradle, we can add the tiny builder along with the BP_NATIVE_IMAGE environment variable to the build.gradle file:

同样,在使用Gradle时,我们可以将tiny构建器与BP_NATIVE_IMAGE环境变量一起加入到build.gradle文件中。

bootBuildImage {
    builder = "paketobuildpacks/builder:tiny"
    environment = [
        "BP_NATIVE_IMAGE" : "true"
    ]
}

3.2. Spring AOT Plugin

3.2 Spring AOT插件

Next, we’ll need to add the Spring AOT plugin that performs ahead-of-time transformations helpful in improving the footprint and compatibility of the native image.

接下来,我们需要添加Spring AOT插件,该插件可执行ahead-of-time转换,有助于改善本地图像的占用率和兼容性。

So, let’s add the latest spring-aot-maven-plugin Maven dependency to our pom.xml:

因此,让我们把最新的spring-aot-maven-plugin Maven依赖性添加到我们的pom.xml

<plugin>
    <groupId>org.springframework.experimental</groupId>
    <artifactId>spring-aot-maven-plugin</artifactId>
    <version>0.10.0</version>
</plugin>

Similarly, for a Gradle project, we can add the latest org.springframework.experimental.aot dependency in the build.gradle file:

同样,对于Gradle项目,我们可以在build.gradle文件中添加最新的org.springframework.experimental.aot依赖项。

plugins {
    id 'org.springframework.experimental.aot' version '0.10.0'
}

Also, as we noted earlier, this will add the Spring Native dependency to the Gradle project automatically.

另外,正如我们前面所指出的,这将自动把Spring Native的依赖性添加到Gradle项目中。

The Spring AOT plugin provides several options to determine the source generation. For example, options like removeYamlSupport and removeJmxSupport remove the Spring Boot Yaml and Spring Boot JMX support, respectively.

Spring AOT插件提供了几个选项来决定源的生成。例如,像removeYamlSupportremoveJmxSupport这样的选项分别移除Spring Boot Yaml和Spring Boot JMX支持。

3.3. Build and Run Image

3.3.构建和运行图像

That’s it! we’re ready to build a native image of our Spring Boot project by using the Maven command:

就这样!我们已经准备好通过使用Maven命令为我们的Spring Boot项目建立一个本地镜像。

$ mvn spring-boot:build-image

The Maven command should create a native image of our Spring Boot App with the name baeldung-spring-native:0.0.1-SNAPSHOT.

Maven命令应该为我们的Spring Boot应用创建一个本地镜像,名称为baeldung-spring-native:0.0.1-SNAPSHOT

Note: building native images consumes a lot of resources. So, we must increase the memory and CPU allocated to Docker when we encounter issues while building the native images.

注意:构建本地镜像会消耗大量的资源。因此,当我们在构建本地镜像时遇到问题,我们必须增加分配给Docker的内存和CPU

Last, we can run the image of our app on Docker using the docker run command:

最后,我们可以使用docker run命令在Docker上运行我们应用程序的镜像。

$ docker run --rm -p 8080:8080 baeldung-spring-native:0.0.1-SNAPSHOT

So, our app should start almost instantaneously and provide output like:

因此,我们的应用程序应该几乎瞬间启动,并提供类似的输出。

Hello, World! This is a Baeldung Spring Native Application

4. GraalVM Native Build Tools

4.GraalVM本地构建工具

As an alternative to the Paketo buildpacks, we can use GraalVM‘s native build tools to compile and build native images using GraalVM’s native-image compiler.

作为Paketo buildpacks的替代方案,我们可以使用GraalVMnative build tools,使用GraalVM的native-image编译器编译和构建本地图像。

4.1. Native Image Compiler Installation

4.1 本地图像编译器的安装

As a prerequisite, we must install SDKMAN to smooth the process of setup. Then, we can use the SDKMAN to install GraalVM for Java 8:

作为前提条件,我们必须安装SDKMAN,以顺利完成设置过程。然后,我们可以使用SDKMAN来安装GraalVM for Java 8

$ sdk install java 21.0.0.2.r8

Next, we’ll set up JAVA_HOME pointing to GraalVM’s 21.0.0.2.r8 distribution.

接下来,我们将设置JAVA_HOME,指向GraalVM的21.0.0.2.r8发行版。

Last, let’s install the native-image compiler provided by the installed GraalVM’s 21.0.0.2.r8 distribution:

最后,让我们安装由已安装的GraalVM的21.0.0.2.r8发行版提供的native-image编译器。

$ gu install native-image

4.2. Spring AOT

4.2.SpringAOT

Along with the spring-native dependency, we’ll add the latest spring-aot Maven dependency, required for native build tools, in our pom.xml:

除了spring-native依赖,我们还将在pom.xml中添加最新的spring-aotMaven依赖,这是本地构建工具所需的。

<dependency>
    <groupId>org.springframework.experimental</groupId>
    <artifactId>spring-aot</artifactId>
    <version>0.10.0</version>
</dependency>

4.3. Spring Boot Maven Plugin

4.3 Spring Boot Maven Plugin

Similar to the Paketo buildpacks, GraalVM’s native build tools also require spring-boot-maven-plugin:

与Paketo的构建包类似,GraalVM的本地构建工具也需要spring-boot-maven-plugin

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

4.4. Spring AOT Maven Plugin

4.4 Spring AOT Maven Plugin

Also, we’ll add the spring-aot-maven-plugin to our pom.xml with the generate goal:

此外,我们还要在spring-aot-maven-plugin中添加pom.xmlgenerate目标。

<plugin>
    <groupId>org.springframework.experimental</groupId>
    <artifactId>spring-aot-maven-plugin</artifactId>
    <version>0.10.0</version>
    <executions>
        <execution>
            <id>generate</id>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

4.5. Native Profile

4.5.本土概况

Next, we’ll add a profile named native with build support of a few plugins like native-maven-plugin and spring-boot-maven-plugin:

接下来,我们将添加一个名为native的配置文件,支持一些插件的构建,如native-maven-pluginspring-boot-maven-plugin

<profiles>
    <profile>
        <id>native</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.graalvm.buildtools</groupId>
                    <artifactId>native-maven-plugin</artifactId>
                    <version>0.9.0</version>
                    <executions>
                        <execution>
                            <id>build-native</id>
                            <goals>
                                <goal>build</goal>
                            </goals>
                            <phase>package</phase>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <classifier>exec</classifier>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

This profile will invoke the native-image compiler from the build during the package phase.

这个配置文件将在打包阶段从构建中调用native-image编译器。

However, when using Gradle, we’ll add the latest org.graalvm.buildtools.native plugin to the build.gradle file:

然而,当使用Gradle时,我们将在build.gradle文件中添加最新的org.graalvm.buildtools.native插件。

plugins {
    id 'org.graalvm.buildtools.native' version '0.9.0'
}

4.6. Build and Run

4.6.建立和运行

That’s it! We’re ready to build our native image by providing the native profile in the Maven package command:

就这样了通过在Maven package命令中提供本地配置文件,我们就可以构建本地镜像了。

$ mvn -Pnative -DskipTests package

The Maven command will create the baeldung-spring-native executor file in the target folder. So, we can run our app by simply accessing the executor file:

Maven命令将在target文件夹中创建baeldung-spring-native执行器文件。因此,我们只需访问该执行文件即可运行我们的应用。

$ target/baeldung-spring-native
Hello World!, This is Baeldung Spring Native Application

5. Conclusion

5.总结

In this tutorial, we explored Spring Native along with buildpacks and GraalVM’s native build tools.

在本教程中,我们探讨了Spring Native以及构建包和GraalVM的本地构建工具。

First, we created a simple Spring Boot project and built a native image using Paketo buildpacks. Then, we examined GraalVM’s native build tools to build and run native images by utilizing GraalVM’s native-image compiler.

首先,我们创建了一个简单的Spring Boot项目,并使用Paketo buildpacks构建了一个本地镜像。然后,我们研究了GraalVM的本地构建工具,通过利用GraalVM的native-image编译器构建和运行本地镜像。

As usual, all the code implementations are available over on GitHub.

像往常一样,所有的代码实现都可以在GitHub上找到