当前位置: 首页 > news >正文

SpringBoot 3 新特性

目录

    • 1. GraalVM
      • 1.1 生成本地可执行应用
      • 1.2 生成docker镜像
    • 2. 支持虚拟线程
    • 3. HTTP Interface

1. GraalVM

  • 使用GraalVM将SpringBoot应用程序编译成本地可执行的镜像文件,可以显著提升启动速度、峰值性能以及减少内存应用。
  • 传统的应用都是编译成字节码,然后通过JVM解释并最终编译成机器码来运行,而Spring Native则是通过AOT提前编译为机器码,在运行时直接静态编译成可执行文件,比如windows上的.exe文件,不依赖JVM。GraalVM的即时编译器和AOT编译器可以显著提高应用程序的性能。
  • AOT: Ahead-of-Time Compilation,预编译在Java9中作为实验性功能提出。将Java类编译为本机代码,减少Java应用的启动时间和内存占用。

1.1 生成本地可执行应用

  • maven使用的插件
<plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId>
</plugin>
  • 生成本地应用命令
mvn -Pnative native:compile
  • gradle需要使用下面的插件
plugins {id 'java'id 'org.springframework.boot' version '3.2.2'id 'io.spring.dependency-management' version '1.1.4'id 'org.graalvm.buildtools.native' version '0.9.28'
}
  • 生成本地应用命令
gradle nativeCompile
  • 或者在IDEA中点击build下的nativeCompile

在这里插入图片描述

  • 最后会在build/native/nativeCompile下生成一个本地可执行文件,可以双击运行

在这里插入图片描述

  • 启动速度只有毫秒级

在这里插入图片描述

  • 参考https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.developing-your-first-application.native-build-tools.maven

1.2 生成docker镜像

  • maven使用的命令
mvn -Pnative spring-boot:build-image
  • gradle使用的命令
gradle bootBuildImage
  • 或者在IDEA中点击build下的bootBuildImage
  • 因为这里会通过docker拉取其他的依赖,所以这时候需要启动docker,通过docker客户端会发现多了3个image,后面显示的created时间是错的,不需要在意
paketobuildpacks/run-jammy-tiny
paketobuildpacks/builder-jammy-tiny
# tptpbfysrt会每次不一样
pack.local/builder/tptpbfysrt

在这里插入图片描述

  • 然后会自动使用pack.local/builder/...启动一个container用来创建镜像,会下载很多东西,如果执行失败,再次点击start运行即可,不会重新下载已经下载过的文件,不要重新执行gradle bootBuildImage命令,不然会全部从头开始执行一遍下载依赖的过程,非常耗费时间。

在这里插入图片描述

  • 执行成功后,会在images中出现一个新生成的镜像文件

在这里插入图片描述

  • 使用下面命令启动
# myproject:0.0.1-SNAPSHOT换成你自己的项目名称和版本
docker run --rm -p 8080:8080 docker.io/library/myproject:0.0.1-SNAPSHOT

在这里插入图片描述

  • 参考https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.developing-your-first-application.buildpacks.maven

2. 支持虚拟线程

  • Spring Boot3.2开始虚拟线程,需要使用JDK21,并设置以下属性
spring.threads.virtual.enabled=true
  • 启用虚拟线程后,Tomcat 和 Jetty 将使用虚拟线程处理请求。这意味着处理网络请求的应用代码(如Controller中的方法)将在虚拟线程上运行。下面是Tomcat开启虚拟线程的代码,在tomcat-embed-core-10.1.19.jar!\org\apache\tomcat\util\net\AbstractEndpoint.class
    public void createExecutor() {internalExecutor = true;if (getUseVirtualThreads()) {executor = new VirtualThreadExecutor(getName() + "-virt-");} else {TaskQueue taskqueue = new TaskQueue();TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);taskqueue.setParent( (ThreadPoolExecutor) executor);}}
  • 创建一个controller

在这里插入图片描述

  • 启动程序,调用hello接口,查看日志打印
2024-02-24T16:41:15.778+08:00  INFO 14252 --- [omcat-handler-0] com.example.demo.Controller : [Controller][hello] VirtualThread[#46,tomcat-handler-0]/runnable@ForkJoinPool-1-worker-1

在这里插入图片描述

  • 通过VirtualThread[#46,tomcat-handler-0]可以看出使用的是虚拟线程
  • 关闭虚拟线程,再次调用接口,查看日志打印
2024-02-24T16:43:14.715+08:00  INFO 15844 --- [nio-8080-exec-1] com.example.demo.Controller : [Controller][hello] Thread[#39,http-nio-8080-exec-1,5,main]

在这里插入图片描述

  • 通过Thread[#39,http-nio-8080-exec-1,5,main]可以看出使用的是平台线程

3. HTTP Interface

  • 将 HTTP 服务定义为带有 @HttpExchange 方法的接口,并将这样的接口传递给 HttpServiceProxyFactory,创建一个代理,通过 HTTP 客户端(如 RestClient 或 WebClient)执行请求。类似于Feign使用声明式的方式访问Http服务。可以参考https://docs.spring.io/spring-framework/reference/integration/rest-clients.html#rest-http-interface

  • 创建一个http interface

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;@HttpExchange("/api")
public interface HelloClient {@GetExchange("/hello")String hello(@RequestParam String msg);}
  • 注入声明式客户端,通过给HttpServiceProxyFactory注入带目标接口baseUrl的client,可以RestClient、WebClient、RestTemplate,这里使用RestClient
import com.example.springboot3.client.HelloClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.support.RestClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;@Configuration
public class AppConfig {@Beanpublic HelloClient toClient() {RestClient restClient = RestClient.builder().baseUrl("http://localhost:80/").build();HttpServiceProxyFactory httpServiceProxyFactory = HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient)).build();return httpServiceProxyFactory.createClient(HelloClient.class);}}
  • Controller
import com.example.springboot3.client.HelloClient;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@Resourceprivate HelloClient client;@GetMapping("hello")public String hello(@RequestParam String msg) {return client.hello(msg);}}
  • 更具体的修改内容可以查看https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes

相关文章:

SpringBoot 3 新特性

目录 1. GraalVM1.1 生成本地可执行应用1.2 生成docker镜像 2. 支持虚拟线程3. HTTP Interface 1. GraalVM 使用GraalVM将SpringBoot应用程序编译成本地可执行的镜像文件&#xff0c;可以显著提升启动速度、峰值性能以及减少内存应用。传统的应用都是编译成字节码&#xff0c;…...

Day02:Web架构前后端分离站Docker容器站集成软件站建站分配

目录 常规化站点部署 站库分离 前后端分离 集成软件搭建Web应用 Docker容器搭建Web应用 建立分配站 静态 与 伪静态 总结 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗…...

链表和顺序表的优劣分析及其时间、空间复杂度分析

链表和顺序表的优劣分析及其时间、空间复杂度分析 一、链表和顺序表的优劣分析二、算法复杂度<font face "楷体" size 5 color blue>//上面算法的执行次数大致为&#xff1a;F&#xff08;N&#xff09; N^22*N10;   N 10,F(10) 1002010 130次   N 1…...

QQ防红跳转短网址生成网站完整源码

使用此源码可以生成QQ自动跳转到浏览器的短链接&#xff0c;无视QQ报毒&#xff0c;任意网址均可生成。 全新界面&#xff0c;网站背景图采用Bing随机壁纸 支持生成多种短链接 兼容电脑和手机页面 生成网址记录功能&#xff0c;域名黑名单功能 网站后台可管理数据 安装说明&am…...

面试redis篇-10Redis集群方案-主从复制

在Redis中提供的集群方案总共有三种: 主从复制哨兵模式分片集群主从复制 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 主从数据同步原理 Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每…...

【BUG 记录】史诗级 BUG - MYSQL 删库删表却没有备份如何恢复数据

【BUG 记录】史诗级 BUG - MYSQL 删库删表却没有备份如何恢复数据 1. 问题描述2. 解决方案&#xff08;binlog&#xff09;2.1 构造测试环境2.2 查看 MySQL 环境是否开启 binlog2.3 查看所有的 binlog 日志记录2.4 查看当前正在使用的是哪一个 binlog 文件2.5 查看此时的 binlo…...

天翼云登录参数JavaSrcipt逆向

天翼云登录参数 password 、comParam_curTime、comParam_seqCode、comParam_signature JavaSrcipt逆向 目标网站 https://m.ctyun.cn/wap/main/auth/login?redirect/my 目标参数 要逆向的有 password、comParam_curTime、comParam_seqCode、comParam_signature 四个参数 …...

AI与大数据:智慧城市安全的护航者与变革引擎

一、引言 在数字化浪潮的席卷下&#xff0c;智慧城市正成为现代城市发展的新方向。作为城市的神经系统&#xff0c;AI与大数据的融合与应用为城市的安全与应急响应带来了革命性的变革。它们如同城市的“智慧之眼”和“聪明之脑”&#xff0c;不仅为城市管理者提供了强大的决策…...

adb pull 使用

adb pull 是 Android Debug Bridge (ADB) 工具提供的一个命令&#xff0c;用于将设备上的文件拷贝到计算机上。通过 adb pull 命令&#xff0c;实现从 Android 设备上获取文件并保存到本地计算机上。 使用 adb pull 命令的基本语法如下&#xff1a; adb pull <设备路径>…...

算法【线性表的查找-顺序查找】

线性表的查找-顺序查找 顺序查找基本思想应用范围顺序表的表示数据元素类型定义查找算法示例分析 时间效率分析顺序查找的特点如何提高查找效率 顺序查找 基本思想 在表的多种结构定义方式中&#xff0c;线性表是最简单的一种。而顺序查找是线性表查找中最简单的一种。 顺序查…...

力扣1143. 最长公共子序列(动态规划)

Problem: 1143. 最长公共子序列 文章目录 题目描述思路复杂度Code 题目描述 思路 我们统一标记&#xff1a;str1[i]代表text1表示的字符数组&#xff0c;str2[j]代表text2表示的字符数组&#xff1b;LCS代表最长的公共子序列&#xff1b;&#xff08;我们易得只有str1[i]和str…...

如何使用群晖NAS中FTP服务开启与使用固定地址远程上传下载本地文件?

文章目录 1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP地址连接 本文主要介绍如何在群晖NAS中开启FTP服务并结合cpolar内网穿透工具&#xff0c;实现使用固定公网地址远程访问群晖FTP服务实现文件上传下载。 Cpolar内…...

C语言文件知识点

一.解释一些问题 1.标准输入文件&#xff08;sdtin&#xff09;&#xff0c;通常对应终端的键盘。 2.标准输出文件&#xff08;stdout&#xff09;和标准错误输出文件&#xff08;stderr&#xff09;&#xff0c;这两个文件 都对应终端的屏幕。 &#xff08;解释&#xff1a…...

C语言:数组指针 函数指针

C语言&#xff1a;数组指针 & 函数指针 数组指针数组名 数组访问二维数组 函数指针函数指针使用回调函数 typedef关键字 数组指针 数组本质上也是一个变量&#xff0c;那么数组也有自己的地址&#xff0c;指向整个数组的指针&#xff0c;就叫做数组指针。 我先为大家展示…...

全面介绍HTML的语法!轻松写出网页

文章目录 heading(标题)paragraph(段落)link(超链接)imagemap(映射)table(表格)list(列表)layout(分块)form(表单)更多输入:datalistautocompleteautofocusmultiplenovalidatepatternplaceholderrequired head(首部)titlebaselinkstylemetascriptnoscript iframe HTML&#xff…...

数学建模【相关性模型】

一、相关性模型简介 相关性模型并不是指一个具体的模型&#xff0c;而是一类模型&#xff0c;这一类模型用来判断变量之间是否具有相关性。一般来说&#xff0c;分析两个变量之间是否具有相关性&#xff0c;我们根据数据服从的分布和数据所具有的特点选择使用pearson&#xff…...

「优选算法刷题」:字母异位词分组

一、题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "na…...

【教程】 iOS混淆加固原理篇

目录 摘要 引言 正文 1. 加固的缘由 2. 编译过程 3. 加固类型 1) 字符串混淆 2) 类名、方法名混淆 3) 程序结构混淆加密 4) 反调试、反注入等一些主动保护策略 4. 逆向工具 5. OLLVM 6. IPA guard 7. 代码虚拟化 总结 摘要 本文介绍了iOS应用程序混淆加固的缘由…...

《银幕上的编码传奇:计算机科学与科技精神的光影盛宴》

目录 1.在电影的世界里&#xff0c;计算机科学不仅是一门严谨的学科&#xff0c;更是一种富有戏剧张力和人文思考的艺术载体。 2.电影作为现代文化的重要载体&#xff0c;常常以其丰富的想象力和视觉表现力来探讨计算机科学和技术的各种前沿主题。 3.电影中的程序员角色往往…...

linux提权之sudo风暴

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...