Springboot3.x整合swagger3

在网上看了许多教程,发现很多都是针对Spring Boot 2 框架的,即使有针对Spring Boot 3 的,用法也不太一样,配置项经常找不到类,经过对比测试,最后我使用的是 SpringDoc OpenAPI Starter WebMvc UI.

pom为

<!--swaggerdoc--><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.2.0</version></dependency>

该jar包不是swagger官方推荐的springfox包,只是前端ui一样,配置会有些许不同,并且不与swagger2配置兼容,请读者注意.

它是 Spring Boot 项目中用于自动生成 API 文档的一个依赖库。它结合了 Swagger UI,提供了一个可视化的界面来展示和测试你的 RESTful APIs。这个依赖库特别适用于使用 Spring Web MVC 框架构建的项目。

这个依赖项包括了 Swagger UI 和 SpringDoc OpenAPI Starter WebMvc API,无需额外引入其他依赖即可使用。

yml配置 (实测不加也没有报错)

server:port: 8080springdoc:api-docs:#是否开启文档功能enabled: true#swagger后端请求地址path: /api-docsswagger-ui:#自定义swagger前端请求路径,输入http:127.0.0.1:8080/test会自动重定向到swagger页面path: /test#包扫描路径packages-to-scan: com.hello.controller,com.hello.dto#这里定义了两个分组,可定义多个,也可以不定义group-configs:#分组名- group: admin#按路径匹配pathsToMatch: /admin/**#分组名- group: user#按包路径匹配packagesToScan: com.hello.api.user

新建配置类

package cn.gdgm.jsj.springboot2024.config;import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.List;
@OpenAPIDefinition(security = @SecurityRequirement(name = "userId"))//在所有接口加上"userId"身份信息
@SecurityScheme(type = SecuritySchemeType.APIKEY, name = "userId", scheme = "", in = SecuritySchemeIn.HEADER) //in表示在请求的哪部分添加 scheme是身份参数前默认添加的字符
@SecuritySchemes({@SecurityScheme(type = SecuritySchemeType.HTTP, name = "userId2", in = SecuritySchemeIn.COOKIE),@SecurityScheme(type = SecuritySchemeType.APIKEY, name = "userId3", in = SecuritySchemeIn.QUERY)})//添加多个身份验证
//swagger3前端地址http://localhost:82/swagger-ui/index.html
@Configuration
public class SwaggerConfig {@Beanpublic OpenAPI springShopOpenAPI() {// 定义联系人信息Contact contact = new Contact().name("Pieory") // 联系人姓名.url("Pieory") // 联系人网址.email("1112@qq.com"); // 联系人邮箱// 定义许可证信息License license = new License().name("许可证名称") // 许可证名称.url("许可证网址 http://springdoc.org"); // 许可证网址// 定义外部文档信息ExternalDocumentation externalDoc = new ExternalDocumentation().description("外部文档描述") // 外部文档描述.url("外部文档网址 https://springshop.wiki.github.org/docs"); // 外部文档网址// 创建 OpenAPI 实例return new OpenAPI().info(new Info().title("API标题-后端测试") // API 标题.contact(contact) // 联系人信息.description("API描述-我的API文档") // API 描述.version("API版本号-v1") // API 版本号.license(license)) // 许可证信息.servers(serversList()) // 服务器列表.components(new Components()) // 组件定义.externalDocs(externalDoc); // 外部文档信息}// 获取服务器列表private List<Server> serversList() {List<Server> servers = new ArrayList<>();// 添加本地服务器信息Server localServer = new Server();localServer.setUrl("http://localhost:82");// 设置服务器 URLlocalServer.setDescription("Springboot2024-本地环境"); // 服务器描述servers.add(localServer);Server localServer1 = new Server();localServer1.setUrl("http://localhost:83");// 设置服务器 URLlocalServer1.setDescription("Springboot2024-本地环境2"); // 服务器描述servers.add(localServer1);return servers;}}

在使用SecuritySchemeType.HTTP时,scheme 需要为"bearer"

@SecurityScheme(type = SecuritySchemeType.HTTP, name = "token2",scheme = "bearer", in = SecuritySchemeIn.HEADER)

常用参数详解

@OpenAPIDefinition全局只能定义一个,主要配置文档信息和安全配置,这里列举了session的安全配置模式
@OpenAPIDefinition下的info属性配置文档信息
@OpenAPIDefinition下的security配置认证方式,name属性引入自定义的认证模式
@SecurityScheme注解就是自定义的认证模式,配置请求头携带userId

@SecurityScheme 注解的主要属性:

type:必填身份认证类型,使用SecuritySchemeType枚举定义

name:自定义认证模式名字

description:模式的描述

paramName:参数名

in:添加到请求的哪一部分使用SecuritySchemeIn枚举定义

scheme:认证参数的值前默认添加的字符串

ref:填写参数时的正则校验

在接口方法上添加@Operation注解

import cn.gdgm.jsj.springboot2024.R.AjaxJsonResult;
import cn.gdgm.jsj.springboot2024.R.Status;
import cn.gdgm.jsj.springboot2024.domain.SysUser;
import cn.gdgm.jsj.springboot2024.service.ISysUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Tag(name = "登录接口", description = "这里为登录标签详情")
@SecurityRequirement(name = "")//单独为接口配置身份验证 这里的name要和swagger配置类中@SecurityScheme配置的name匹配 置空表示不需要身份信息
@RestController
@RequestMapping("/login")
public class LoginController {@Autowired@Qualifier("userService")private ISysUserService userService;@Operation(tags = {"注册"}, // 标签组,用于组织 API,会分配到新的"注册"文档组里summary = "根据SysUser查询用户信息", description = "根据SysUser查询用户信息,并返回响应结果信息",parameters = {// @Parameter(name = "id", description = "用户ID", required = false, example = "1")//参数描述 没有的参数不要写因为会自动在方法里加参数},responses = {@ApiResponse(responseCode = "200",description = "响应成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "Resul和StudentVO组合模型",description = "返回实体,AjaxResult内data为SysUserVO模型",anyOf = {AjaxJsonResult.class, SysUser.class}//返回参数的组合模型))),@ApiResponse(responseCode = "500",description = "响应失败",content = @Content(mediaType = "application/json",schema = @Schema(title = "Resul模型",description = "返回实体,AjaxResult内 data为空",implementation = AjaxJsonResult.class//返回参数的模型)))},security = {@SecurityRequirement(name = "")//将name设置为空,则表示该接口不需要身份验证 也可以在类上注解实现全部方法不需要身份验证})/*登录*/@PostMapping("/login")public AjaxJsonResult login(@Parameter(description = "登录名登录密码", required = true) // 参数描述//@Pattern(regexp = "\S{6,20}", message = "密码长度必须在6到20个字符之间") // 密码格式验证@RequestBody SysUser sysUser, HttpServletRequest request) {System.out.println("login=>" + sysUser);SysUser user = null;try {user = userService.login(sysUser);if (user == null) {return new AjaxJsonResult<>(Status.LOGIN_FAIL.getCode(), Status.LOGIN_FAIL.getMsg(), "查询user为空");}} catch (Exception e) {System.out.println("登录查询失败");e.printStackTrace();return new AjaxJsonResult<>(Status.ERROR.getCode(), Status.ERROR.getMsg(), e.getMessage());}HttpSession session = request.getSession();
//        session.setAttribute(user.getUserId().toString(),user.getUserName());session.setAttribute(user.getUserId().toString(), user.getUserName());session.setMaxInactiveInterval(20);System.out.println("/login-user=> " + user);return new AjaxJsonResult<SysUser>(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg(), user);}/*退出*/@Operation(tags = {"注册"}, // 标签组,用于组织 API,?会自动分配一个新的文档组summary = "注册", // 接口的功能简述description = "用户注册操作", // 更详细的描述responses = {//responses内容写法自行百度@ApiResponse(responseCode = "200", description = "登录成功"),@ApiResponse(responseCode = "400", description = "登录名或密码错误"),@ApiResponse(responseCode = "500", description = "服务器内部错误", headers = @Header(name = "Content-Type", description = "返回类型"))},security = {@SecurityRequirement(name = "")//将name设置为空,则表示该接口不需要身份验证 也可以在类上注解实现全部方法不需要身份验证})@PostMapping("/logout")public AjaxJsonResult<SysUser> logout(@RequestBody SysUser sysUser) {System.out.println("login=>" + sysUser);AjaxJsonResult ajaxJsonResult = new AjaxJsonResult();SysUser user = null;try {user = userService.register(sysUser);} catch (Exception e) {System.out.println(e.getMessage());return new AjaxJsonResult<>(Status.ERROR.getCode(), Status.ERROR.getMsg(), null);}System.out.println("/getUserBySysUserTest-user=> " + user);return new AjaxJsonResult<SysUser>(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg(), user);}/*注册*/@Operation(tags = {"注册"}, // 标签组,用于组织 API,?会自动分配一个新的文档组summary = "注册", // 接口的功能简述description = "用户注册操作", // 更详细的描述responses = {//responses内容写法自行百度@ApiResponse(responseCode = "200", description = "登录成功"),@ApiResponse(responseCode = "400", description = "登录名或密码错误"),@ApiResponse(responseCode = "500", description = "服务器内部错误", headers = @Header(name = "Content-Type", description = "返回类型"))},security = {@SecurityRequirement(name = "")//将name设置为空,则表示该接口不需要身份验证 也可以在类上注解实现全部方法不需要身份验证})@PostMapping("/register")public AjaxJsonResult<SysUser> register(@RequestBody SysUser sysUser) {System.out.println("register=>" + sysUser);int flag = 0;SysUser user = null;try {user = userService.register(sysUser);if (user != null) {System.out.println("/getUserBySysUserTest-user=> " + user);return new AjaxJsonResult<SysUser>(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg(), user);} else {System.out.println("注册失败");return new AjaxJsonResult<>(Status.ERROR.getCode(), Status.ERROR.getMsg(), null);}} catch (Exception e) {System.out.println(e.getMessage());return new AjaxJsonResult<>(Status.ERROR.getCode(), Status.ERROR.getMsg(), null);}}}

@Operation 注解支持的主要属性:

summary:一个简短的摘要描述。

description:一个详细的描述,可以包含 Markdown 格式的文本。

tags:用于对操作进行分类的字符串数组。

operationId:一个唯一的标识符,如果未提供,则默认为方法名。

responses:一个包含预期响应的列表,可以描述不同状态码对应的响应信息。

deprecated:一个布尔值,表示该操作是否已被废弃。

externalDocs:指向外部文档的链接。

security:一个包含安全需求的对象,指定了需要哪些安全方案才能访问该操作。

servers:一个服务器列表,指定了哪些服务器支持该操作。

callbacks:一个回调列表,用于异步操作。

parameters:一个参数列表,用于描述请求中的参数。

@ApiResponse(responseCode = "500",description = "响应失败",content = @Content(mediaType = "application/json",schema = @Schema(title = "Resul模型",description = "返回实体,AjaxResult内 data为空",implementation = AjaxJsonResult.class//返回参数的模型)))

@ApiResponse 注解的主要属性:

description:返回描述

responseCode:返回状态码

headers:响应头

content:返回信息定义 包括响应头,响应体模型

extensions:外部文档

用户实体类

package cn.gdgm.jsj.springboot2024.domain;import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;import java.io.Serializable;@Schema(name = "SysUser", description = "用户信息")
@Tag(name = "用户实体", description = "描述")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class SysUser implements Serializable {/*用户id*/@Schema( description = "用户id描述")//name不能使用中文 而且要和变量名一样 因为在测试的json会自动填入nameprivate Integer userId;/*用户名*/@Schema(description = "用户名描述")@NotEmpty // 字段不能为nullprivate String userName;/*用户密码*/@Schema(description = "用户密码描述")private String userPassword;/*用户电话*/@Schema(description = "用户电话描述")private String userPhone;}

统一返回类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class AjaxJsonResult <T>{private String code;private String msg;private T data;}

状态码枚举

public enum Status {SUCCESS("2000", "操作成功"),LOGIN_FAIL("4002", "用户名或密码错误"),ERROR("4000", "操作失败"),UNAUTHORIZED("4001", "未授权"),NOT_FOUND("4004", "未找到资源"),INTERNAL_SERVER_ERROR("5000", "服务器内部错误"),RESPONSE_FAIL_FLAG("4003", "登录状态失效"),RESPONSE_CODE_ERROR("4005","验证码错误");private String code;private String msg;Status(String code, String msg) {this.code = code;this.msg = msg;}public String getCode() {return code;}public String getMsg() {return msg;}
}

最后在拦截器配置放行 “/v3/api-docs/**”,“/swagger-ui/**”, “/v3/api-docs/**”

import cn.gdgm.jsj.springboot2024.Interceptor.UserLoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.Arrays;
import java.util.List;@Configuration
public class LoginConfig implements WebMvcConfigurer {@AutowiredUserLoginInterceptor userLoginInterceptor;List<String> excludePathPatterns= Arrays.asList("/login/**","/css/**","/js/**","/pic/**","/**.html","/swagger-resources/**","/webjars/.**","/v3/api-docs/**","/swagger-ui/**", "/v3/api-docs/**");//允许访问的路径@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(userLoginInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表示拦截所有请求.excludePathPatterns(excludePathPatterns)//设置拦截器不拦截哪些请求路径;}}

效果如下

使用登录接口登录后点击Authorize按钮填写身份信息在输入框内

本文参考:

Spring Boot 3.x 引入springdoc-openapi (内置Swagger UI、webmvc-api)_springdoc-openapi-starter-webmvc-ui-CSDN博客

Springboot整合Swagger3全注解配置(springdoc-openapi-ui)_swagger.v3-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/500353.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android.enableJetifier=true的作用:V4包的类自动编程成了androidx包的类,实现androidx的向下兼容

结论&#xff1a;引入androidx包后&#xff0c;可以兼容旧版本v4包的插件&#xff0c;把之前的 implementation com.yinglan.alphatabs:library:1.0.8 引入的组件中使用v4包的类&#xff0c;里面V4包自动反编译成 androidx包的类 结论; ‌V4包的类自动编程成了androidx包的…

详解MySQL在Windows上的安装

目录 查看电脑上是否安装了MySQL 下载安装MySQL 打开MySQL官网&#xff0c;找到DOWNLOADS 然后往下翻&#xff0c;找到MySQL Community(GPL) Downloads>> 然后找到MySQL Community Server 然后下载&#xff0c;选择No thanks,just start my download. 然后双击进行…

excel操作

来源&#xff1a;B站默默亚 一、版本识别 特点&#xff1a;向后兼容&#xff1b;高版本可以打开低版本&#xff0c;低版本不可以打开高版本 工作中&#xff0c;给老板最低版本&#xff0c;即2003版本 二、文件的扩展名 三、excel页面

最大化堡垒补给数量的策略与实现

最大化堡垒补给数量的策略与实现 问题描述输入格式输出格式问题分析解决方案代码实现代码解释问题描述 可怕的战争发生了,小度作为后勤保障工作人员,为了保卫国家而努力。现在有 N 个堡垒需要补给,然而总的预算 B 是有限的。每个堡垒需要价值 P(i) 的补给,并且需要 S(i) 的…

手机实时提取SIM卡打电话的信令声音-双卡手机来电如何获取哪一个卡的来电

手机实时提取SIM卡打电话的信令声音 --双卡手机来电如何获取哪一个卡的来电 一、前言 前面的篇章《手机实时提取SIM卡打电话的信令声音-智能拨号器的双SIM卡切换方案》中&#xff0c;我们论述了局域网SIP坐席通过手机外呼出去时&#xff0c;手机中主副卡的呼叫调度策略。 但…

国产手机嘴上喊着挑战苹果,实际行动却已承认失败,真的干不过

国产手机年年喊着挑战苹果&#xff0c;在苹果的iPhone15和iPhone16都被诟病创新不足的时候&#xff0c;国产手机更是以为迎来了赶超苹果的机会&#xff0c;然而随着年底的到来&#xff0c;诸多国产手机品牌的实际行动却说明他们其实已经承认败给苹果了。 近几周&#xff0c;国产…

微信小程序:定义页面标题,动态设置页面标题,json

1、常规设置页面标题 正常微信小程序中&#xff0c;设置页面标题再json页面中进行设置&#xff0c;例如 {"usingComponents": {},"navigationBarTitleText": "标题","navigationBarBackgroundColor": "#78b7f7","navi…

鸿蒙应用开发启航计划

以前有过简单的学习了解&#xff0c;但是现在工作内容的原因&#xff0c;要专门搞这个&#xff0c;因此需要更加熟练地掌握鸿蒙应用开发。 1.开发IDE -- DevEco Studio Windows环境 运行环境要求 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff…

LabVIEW 实现自动对焦的开发

自动对焦&#xff08;Autofocus, AF&#xff09;技术是通过分析图像或传感器信号&#xff0c;动态调整焦点位置以实现清晰成像或高精度定位的过程。在LabVIEW中&#xff0c;可以通过集成信号采集、数据处理、控制算法和硬件接口模块&#xff0c;实现多种自动对焦方法&#xff0…

网络安全 | 物联网安全:从设备到网络的全方位防护

网络安全 | 物联网安全&#xff1a;从设备到网络的全方位防护 一、前言二、物联网设备安全2.1 物联网设备的特点与安全风险2.2 物联网设备安全防护策略 三、物联网网络通信安全3.1 物联网网络通信的安全挑战3.2 物联网网络通信安全防护措施 四、物联网数据安全4.1 物联网数据的…

C# OpenCV机器视觉:目标跟踪

在一个阳光明媚的下午&#xff0c;阿强正在实验室里忙碌&#xff0c;突然他的同事小杨走了进来&#xff0c;脸上挂着一丝困惑。 “阿强&#xff0c;我的目标跟踪项目出了问题&#xff01;我想跟踪一个移动的物体&#xff0c;但总是跟丢&#xff01;”小杨一边说&#xff0c;一…

JSON结构快捷转XML结构API集成指南

JSON结构快捷转XML结构API集成指南 引言 在当今的软件开发世界中&#xff0c;数据交换格式的选择对于系统的互操作性和效率至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是两种广泛使用的数据表…

OpenAI发布o3:圣诞前夜的AI惊喜,颠覆性突破还是技术焦虑?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Springboot使用RabbitMQ实现关闭超时订单的一个简单示例

1.maven中引入rabbitmq的依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency> 2.application.yml中进行rabbitmq相关配置&#xff1a; # rabbit…

数据挖掘——决策树分类

数据挖掘——决策树分类 决策树分类Hunt算法信息增益增益比率基尼指数连续数据总结 决策树分类 树状结构&#xff0c;可以很好的对数据进行分类&#xff1b; 决策树的根节点到叶节点的每一条路径构建一条规则&#xff1b;具有互斥且完备的特点&#xff0c;即每一个样本均被且…

DeepSeek V3“报错家门”:我是ChatGPT

搜 &#xff1a;海讯无双Ai 要说这两天大模型圈的顶流话题&#xff0c;那绝对是非DeepSeek V3莫属了。 不过在网友们纷纷测试之际&#xff0c;有个bug也成了热议的焦点—— 只是少了一个问号&#xff0c;DeepSeek V3竟然称自己是ChatGPT。 甚至让它讲个笑话&#xff0c;生成…

haproxy+nginx负载均衡实验

准备三台虚拟机&#xff1a; HAProxy 服务器192.168.65.131Web 服务器 1192.168.65.132Web 服务器 2192.168.65.133 在 HAProxy 服务器&#xff08;192.168.65.131&#xff09;上操作&#xff1a; 安装 HAProxy&#xff1a; sudo yum install -y haproxy编辑 HAProxy 配置…

获取 Astro Bot AI 语音来增强您的游戏体验!

有很多用户尝试过Astro Bot&#xff0c;却被Astro Bot可爱的声音所吸引。您是否想知道如何使用 Astro Bot 语音来拨打恶作剧电话或用他的声音说话&#xff1f;如果您有&#xff0c;那么这篇文章适合您。我们将向您展示如何为 Astro Bot 提供逼真的 AI 声音并在在线对话中使用它…

c++表达范围勿用数学符号

目的 遇上了一个C基础问题&#xff0c;一下子陷到里面&#xff0c;不知怎么回事了&#xff0c;知道后&#xff0c;又感觉太可笑。 这也许就是成长的代价。 下面就是细说说所遇上的问题。 关于C逻辑的一些知识点&#xff1a; 定义: 用逻辑运算符将两个表达式链接起来的式子称为…

JVM对象内存分配

1 栈上分配 栈空间随着方法执行完毕而回收通过栈上分配对象内存空间的方式&#xff0c;减少对堆空间的使用&#xff0c;从而减少gc的压力&#xff0c;提升程序性能 逃逸分析&#xff1a;分析对象的作用域&#xff0c;判断对象所需内存是否可以在栈上分配当对象没有被外部方法或…