Spring Native

Spring Native 官网地址:https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/

什么是spring native

Spring Native 可以通过 GraalVM 将 Spring 应用程序编译成原生镜像,提供了一种新的方式来部署 Spring 应用。

这个项目的目标是寻找 Spring JVM 的替代方案,提供一个能将应用程序打包,并运行在轻量级容器的方案。期望能够在 Spring Native 中支持所有的 Spring 应用程序。

spring native 的有优缺点

优点:
  • 编译出来的原生 Spring 应用可以作为一个独立的可执行文件进行部署(不需要安装 JVM)
  • 启动快(一般小于 100 毫秒)
  • 占用内存小
缺点:
  • GraalVM在打包的配置要求上较高
  • 比 JVM 构建时间更长
  • 对于使用了反射的项目来说,需要在使用GraalVm构建native image前需要通过配置列出反射可见的所有类型

原生镜像和常规 JVM 的区别

  • 在构建时会从主入口点,静态分析应用程序
  • 在构建时会移除未使用的代码
  • 需要配置反射、动态代理等
  • classpath 在构建时就已经确定
  • 没有类延迟加载:可执行文件中所有的内容都会在启动时加载到内存中
  • 在构建时就运行了一些代码
  • 构建原生镜像还存在一些 局限性

JVM 的程序运行时间长,是因为存在虚拟机的初始化和类加载过程,如果将字节码直接编译成原生代码,则可以彻底解决这些问题。同时因为没有即时编译器在运行时编译,所有代码都在编译期编译和优化。因为少了 Java 虚拟机、即时编译器这些额外组件,原生程序也能够省去它们原本消耗的内存资源和镜像体积。

了解GraalVM

GraalVM 是一个高性能的多语言运行时环境。设计目的是能够提高用 Java 和其他 JVM 语言编写的应用程序的执行速度,同时还为 JavaScript、Ruby、Python 和许多其他流行语言提供运行时。GraalVM 的多语言能力使得在一个应用程序中混合使用多种编程语言成为可能,同时消除了不同语言间互相调用的成本。

GraalVM 下的 Java 微服务

  • 启动时间更快
  • 内存占用更少

构建 Spring Boot native 应用程序有 2 种方式

  • 使用 Spring Boot Buildpacks support 构建一个包含本地可执行文件的轻量级容器。(要求java11+)
  • 使用 the GraalVM native image Maven plugin support 构建一个本地可执行文件。(要求SpringBoot3.0+,java17+)

Spring Native 所遇到的问题

对于反射,需要用户在编译期,通过配置文件或编译器参数的形式,明确告知编译器程序代码中哪些方法只通过反射来访问的。

用户往往不知道动态生成字节码的具体信息,这些只能由程序去做妥协。默认情况下,每一个 Spring 管理的 Bean 都要用到 CGLib。从 Spring Framework 5.2(SpringBoot与SpringFramework对应关系) 开始增加了@proxyBeanMethods 注解来排除对 CGLib 的依赖,仅使用标准的动态代理去增强类。

成功通过Spring Boot Buildpacks support 构建一个包含本地可执行文件的轻量级容器的关键

  1. java jdk 要求版本 jdk-11.0.18+
  2. 安装本地 maven 并配置好环境 版本不要太低
  3. 安装Windows下docker 并配置好环境 https://blog.csdn.net/qubernet/article/details/125593666
  4. maven 配置文件
    <?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>
    
      <groupId>org.example</groupId>
      <artifactId>spring-native</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>spring-native</name>
    
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath/>
      </parent>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring-native.version>0.11.0</spring-native.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
          <groupId>org.springframework.experimental</groupId>
          <artifactId>spring-native</artifactId>
          <version>${spring-native.version}</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <!--Spring AOT 插件执行代码的提前转换,用以修复 native image 的兼容性-->
          <plugin>
            <groupId>org.springframework.experimental</groupId>
            <artifactId>spring-aot-maven-plugin</artifactId>
            <version>${spring-native.version}</version>
            <executions>
              <execution>
                <id>test-generate</id>
                <goals>
                  <goal>test-generate</goal>
                </goals>
              </execution>
              <execution>
                <id>generate</id>
                <goals>
                  <goal>generate</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <!--Spring Boot Buildpacks support 可以将 Spring Boot 应用程序打包成一个容器-->
          <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>
    
      <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>
    </project>
    
    
  5. 开始通过mvn构建镜像前先把梯子打开
  6. 开始构建 mvn spring-boot:build-image 第一次构建时间比较慢长(大约10分钟以上),之后再构建大约3分钟左右
  7. 构建成功后就可以直接启动 docker run --rm -p 8080:8080 镜像名称
    删除镜像 docker rmi -f 镜像ID

温馨提示
maven demo项目https://github.com/enChenging/spring-native
gradle demo项目https://github.com/enChenging/spring-native-gradle-simple

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java8新特性及实战视频教程完整版Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda 表达式可以使代码变的更加简洁紧凑。Java8实战视频-01让方法参数具备行为能力Java8实战视频-02Lambda表达式初探Java8实战视频-03Lambda语法精讲Java8实战视频-04Lambda使用深入解析Java8实战视频-05Lambda方法推导详细解析-上.wmvJava8实战视频-06Lambda方法推导详细解析-下Java8实战视频-07Stream入门及Stream在JVM中的线程表现Java8实战视频-08Stream知识点总结Stream源码阅读Java8实战视频-09如何创建Stream上集Java8实战视频-10如何创建Stream下集.wmvJava8实战视频-11Stream之filter,distinct,skip,limit,map,flatmap详细介绍Java8实战视频-12Stream之Find,Match,Reduce详细介绍Java8实战视频-13NumericStream的详细介绍以及和Stream之间的相互转换Java8实战视频-14Stream综合练习,熟练掌握API的用法Java8实战视频-15在Optional出现之前经常遇到的空指针异常.wmvJava8实战视频-16Optional的介绍以及API的详解Java8实战视频-17Optional之flatMap,综合练习,Optional源码剖析Java8实战视频-18初识Collector体会Collector的强大Java8实战视频-19Collector使用方法深入详细介绍-01Java8实战视频-20Collector使用方法深入详细介绍-02Java8实战视频-21Collector使用方法深入详细介绍-03.wmvJava8实战视频-22Collector使用方法深入详细介绍-04Java8实战视频-23Collector原理讲解,JDK自带Collector源码深度剖析Java8实战视频-24自定义Collector,结合Stream的使用详细介绍Java8实战视频-25Parallel Stream编程体验,充分利用多核机器加快计算速度Java8实战视频-26Fork Join框架实例深入讲解Java8实战视频-27Spliterator接口源码剖析以及自定义Spliterator实现一个Stream.wmvJava8实战视频-28Default方法的介绍和简单的例子Java8实战视频-29Default方法解决多重继承冲突的三大原则详细介绍Java8实战视频-30多线程Future设计模式原理详细介绍,并且实现一个Future程序Java8实战视频-31JDK自带Future,Callable,ExecutorService介绍Java8实战视频-32实现一个异步基于事件回调的Future程序.wmvJava8实战视频-33CompletableFuture用法入门介绍Java8实战视频-34CompletableFuture之supplyAsync详细介绍Java8实战视频-35CompletableFuture流水线工作,join多个异步任务详细讲解Java8实战视频-36CompletableFuture常用API的重点详解-上Java8实战视频-37CompletableFuture常用API的重点详解-下Java8实战视频-38JDK老DateAPI存在的问题,新的DateAPI之LocalDate用法及其介绍.wmvJava8实战视频-39New Date API之LocalTime,LocalDateTime,Instant,Duration,Period详细介绍Java8实战视频-40New Date API之format和parse介绍

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值