SpringDoc【使用详解】
SpringDoc使用详解
- 一、何为SpringDoc
- 二、概念解释
- 三、SpringDoc使用
- 2.1简单集成
- 2.2 配置SpringDoc
- 2.2.1 yml方式配置
- 2.2.2配置文档信息
- 2.3配置文档分组
- 2.4使用注解
- 2.4.1 @Tag
- 2.4.2 @Operation
- 2.4.3 @Schema
- 2.4.4 @NotNull
- 2.4.5 @Parameter
- 2.4.6 @Parameters
- 2.4.7 @ApiResponses 和@ApiResponse
- 四、认证授权
- 3.1无需认证
- 3.2需要认证
- 五、SpringDoc整合Knife4j
- 1.前世今生
- 2.Spring Boot版本兼容性
- 3.Spring Boot 3
- 4.Spring Boot 2
一、何为SpringDoc
SpringDoc是一个用来自动生成API文档的库。它是基于SpringBoot项目的,遵循OpenAPI3(一个组织规定的规范)规范。它是通过检查我们运行中的程序,推断出基于Spring配置、类结构和各种注解的API语义,从而自动生成JSON、YAML和HTML格式的接口文档。
而我们不得不提的就是Swagger。Swagger是一个公司的开源项目,将自己的API设计贡献给了OpenAPI并由其标准化。在SpringDoc之前我们还可以使用Springfox,和SpringDoc一样是一个用于生成API文档的库,2020年起不再更新。
SpringDoc官网
二、概念解释
谈到API文档,那就绕不开大名鼎鼎的Swagger,但是你是否还听说过:OpenAPI,Springfox,Springdoc?你第一次看到这些脑瓜子是不是嗡嗡的?
-
OpenAPI
是一个组织(OpenAPI Initiative),他们指定了一个如何描述HTTP API的规范(OpenAPI Specification)。既然是规范,那么谁想实现都可以,只要符合规范即可。 -
Swagger
它是SmartBear这个公司的一个开源项目,里面提供了一系列工具,包括著名的 swagger-ui。swagger是早于OpenApi的,某一天swagger将自己的API设计贡献给了OpenApi,然后由其标准化了。 -
Springfox
是Spring生态的一个开源库,是Swagger与OpenApi规范的具体实现。我们使用它就可以在spring中生成API文档。以前基本上是行业标准,目前最新版本可以支持 Swagger2, Swagger3 以及 OpenAPI3 三种格式。但是其从 2020年7月14号就不再更新了,不支持springboot3,所以业界都在不断的转向我们今天要谈论的另一个库Springdoc,新项目就不要用了。 -
Springdoc
算是后起之秀,带着继任Springfox的使命而来。其支持OpenApi规范,支持Springboot3,我们的新项目都应该使用这个。
三、SpringDoc使用
我们可以在springboot中使用SpringDoc来生成API文档,详情可以参考官网,下面我们来简单的实践一下。
2.1简单集成
在springboot中使用springdoc起步非常容易,只需要引入其starter即可
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.8.6</version></dependency>
运行后访问下面的链接即可
http://server:port/context-path/swagger-ui.html
例如
http://localhost:8080/swagger-ui.html
例如我们有如下代码:
@RestController
@RequestMapping("/api/programmer")
public class ProgrammerController {@PostMapping()public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {return new Programmer(1, request.getAge(), request.getProgrammingLang());}@GetMapping("/{id}")public Programmer getProgrammer(@PathVariable Integer id) {return new Programmer(1, 35, List.of("Java,Python,SQL"));}
}
添加依赖运行后访问http://localhost:8080/swagger-ui.html后结果如下

是不是特牛逼?当然springdoc的集成不可能就这点东西,不然也没有这篇文章了,咱接着往下看。苦于网上的一些教程不直观,对初学者不友好,所以本文以代码和其效果的形式来展示,保你一看就会。
2.2 配置SpringDoc
2.2.1 yml方式配置
springdoc:api-docs:# 是否开启接口文档enabled: trueswagger-ui:# 持久化认证数据persistAuthorization: trueinfo:# 标题title: '标题:${demo.name}多租户管理系统_接口文档'# 描述description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'# 版本version: '版本号: ${demo.version}'# 作者信息contact:name: Agazigiemail: 123456789@qq.comurl: www.baidu.comcomponents:# 鉴权方式配置security-schemes:apiKey:type: APIKEYin: HEADERname: ${sa-token.token-name}#这里定义了两个分组,可定义多个,也可以不定义group-configs:- group: 1.演示模块packages-to-scan: org.dromara.demo- group: 2.通用模块packages-to-scan: org.dromara.web- group: 3.系统模块packages-to-scan: org.dromara.system- group: 4.代码生成模块packages-to-scan: org.dromara.generator

2.2.2配置文档信息
得益于springboot的强大,我们只需添加一个依赖就可以使用API文档了,但是使用的都是默认值,我们当然也希望对其进行各种自定义的配置
- 配置文档信息
创建一个OpenAPI 的bean,配置文档名称等信息
@Configuration
public class SpringDocConfig {@Beanpublic OpenAPI myOpenAPI() {return new OpenAPI().info(new Info() //设置信息.title("程序员API") //标题.description("程序员的大本营") //描述信息.version("v1.0.0") //版本.license(new License() //许可证.name("许可协议").url("https://shusheng007.top")).contact(new Contact() //作者信息.name("书生007").email("wangben850115@gmail.com"))).externalDocs(new ExternalDocumentation() //外部文档.description("ShuSheng007博客").url("https://shusheng007.top"));}// 指定扫描的包路径@Beanpublic GroupedOpenApi publicApi() {return GroupedOpenApi.builder().group("my_api") // 分组名称(自定义).packagesToScan("com.ls.ai.demo.controller") // 包路径.addOpenApiMethodFilter(methodPredicate()) // 方法级注解过滤.build();}// 定义过滤条件:仅包含带有 @Operation 注解的方法private Predicate<HandlerMethod> methodPredicate() {return handlerMethod ->handlerMethod.hasMethodAnnotation(io.swagger.v3.oas.annotations.Operation.class);}// 可选:过滤类级别的注解(如 @Tag)private Predicate<HandlerMethod> classPredicate() {return handlerMethod ->handlerMethod.getBeanType().isAnnotationPresent(io.swagger.v3.oas.annotations.tags.Tag.class);}}
效果:

里面的配置项很多,可以根据代码和截图对照一下,按照自己的需求配置即可
2.3配置文档分组
用来配置分组的,假如你有两类controller一类以/api为前缀,一类以/admin为前缀,就可以将其配置为两个分组。很多时候我们只有一个分组,所以就不需要下面的配置。
@Configuration
public class SpringDocConfig {...@Beanpublic GroupedOpenApi publicApi() {return GroupedOpenApi.builder().group("api").pathsToMatch("/api/**").build();}@Beanpublic GroupedOpenApi adminApi() {return GroupedOpenApi.builder().group("admin").pathsToMatch("/admin/**").build();}
}
效果:

可以通过右上角的下拉框选择要展示的group。
2.4使用注解
这个是咱们的重头戏,OpenApi规范提供了很多注解,下面是一些常用的
| 注解 | 含义 |
|---|---|
| @Tag | 用在controller类上,描述此controller的信息 |
| @Operation | 用在controller的方法里,描述此api的信息 |
| @Parameter | 用在controller方法里的参数上,描述参数信息 |
| @Parameters | 用在controller方法里的参数上 |
| @Schema | 用于Entity,以及Entity的属性上 |
| @ApiResponse | 用在controller方法的返回值上 |
| @ApiResponses | 用在controller方法的返回值上 |
| @Hidden | 用在各种地方,用于隐藏其api |
下面我们一起来看看效果
2.4.1 @Tag
@Tag(name = "程序员", description = "程序员乐园")
@RestController
@RequestMapping("/api/programmer")
public class ProgrammerController {
...
}
效果

2.4.2 @Operation
@Operation(summary = "创建程序员", description = "用于创建一个闷骚的程序员")
@PostMapping()
public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {return new Programmer(666, "王二狗", request.getAge(), request.getProgrammingLang());
}

@Operation 其实很复杂的,我们可以将下面要用的@Parameter以及@ApiResponse都可以配置在它里面。
2.4.3 @Schema
@Schema 用于实体类和其属性,例如有如下代码:
@Schema(description = "创建程序员入参")
public class CreateProgrammerRequest {@Schema(description = "名称", example = "王二狗")private String name;@Schema(description = "年龄", example = "35")private Integer age;@Schema(description = "掌握的编程语言", type = "List", example = "[\"Java\",\"Sql\"]")private List<String> programmingLang;
}
效果:

还可以切换到 Schema选项进行查看

2.4.4 @NotNull
同时,Springdoc还支持 Java Bean Validation API 的注解,例如@NotNull 等
@Schema(description = "创建程序员入参")
public class CreateProgrammerRequest {@NotNull@Schema(description = "名称", example = "王二狗")private String name;@NotNull@Min(18)@Max(35)@Schema(description = "年龄", example = "35")private Integer age;...
}
效果:

注意红框中的内容,name和age右上角都有出现了一个红色的星星,表示是必填的。age也被限制了范围。
2.4.5 @Parameter
用于添加接口参数信息
@GetMapping("/{id}")
public Programmer getProgrammer(@Parameter(description = "程序员id") @PathVariable Integer id) {...
}
效果

2.4.6 @Parameters
与@Parameter作用一样,但是可以批量添加,不用一个一个的写在参数前面
@Parameters(value = {@Parameter(name = "name", description = "姓名", in = ParameterIn.PATH),@Parameter(name = "age", description = "年龄", in = ParameterIn.QUERY)
})
@GetMapping("/{name}")
public List<Programmer> getProgrammers(@PathVariable("name") String name, @RequestParam("age") Integer age) { ...
}
parameters里的parameter使用name来找到方法中的入参,这块要对应上。
效果:

2.4.7 @ApiResponses 和@ApiResponse
顾名思义,此注解用来描述返回值的。
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功",content = {@Content(mediaType = "application/json",schema = @Schema(implementation = Programmer.class))}),@ApiResponse(responseCode = "405", description = "非法输入",content = @Content)})@PostMapping()public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {...}
效果

可见,我们成功配置了两种情况的返回值。但是我们一般不会手动给每个API 写上一堆@ApiResponse,那的多烦啊。业界通常会有一个统一的返回类型,例如
public class Result<T> implements Serializable {private int code;private String message;private T data;private String traceId;
}
还会有一个统一的异常处理类,使用@RestControllerAdvice标记,然后每个方法会捕捉对应的异常,只要我们使用@ResponseStatus来标记这些方法,springdoc就会自动生成相应的文档
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public Result handleException(HttpServletRequest httpServletRequest, Exception e) {return new Result(StatusCode.FAILED.getCode(), StatusCode.FAILED.getMessage(), null);}@ExceptionHandler(value = ApiException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Result handleBusinessException(HttpServletRequest httpServletRequest, ApiException e) {return new Result(e.getCode(), e.getMessage(), null);}
}
例如我们有如下代码:
...
@RequestMapping(value = "/api/programmer",produces = "application/json")
public class ProgrammerController {@GetMapping("/{id}")public Result<Programmer> getProgrammer(@Parameter(description = "程序员id") @PathVariable Integer id) {...}
}
生成的api文档如下:

可见,多了400和500。
四、认证授权
我们知道·swagger-ui·不仅可以看API文档也可以直接调用API,这点很牛逼。但有时我们的服务需要认证,否则就调用不通,那怎么办?稍安勿躁,OpenApi规范也考虑到了这个问题。
OpenAPI 3.0 支持下面的认证模式:
- HTTP authentication schemes (使用Authorization header):
- Basic
- Bearer
- Other HTTP schemes as defined by RFC 7235 and HTTP Authentication Scheme Registry
- API keys in headers, query string or cookies
- Cookie authentication
- OAuth 2
- OpenID Connect Discovery
有的我也没用过,我们常用的就是Http Auth,以及OAuth2。本文以HTTP Bearer来作为我们服务的认证授权模式,如下图所示。

3.1无需认证
当你的服务没有认证机制的话是可以直接调用的:
每个API 右上角都有一个try it out按钮,点击输入参数点击execute按钮即可,如下所示。

3.2需要认证
如果你的服务需要认证后才能调用,那么默认情况下就不行了。例如你使用了Spring Security,或者你自己写了个Filter 来实现认证功能。
下面是demo服务用来做认证的Filter,采用HTTP Bearer 模式。所以需要在请求的Authentication Header 里 携带token 123才能通过认证。
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {...@Overrideprotected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {...// get token from header [Authorization: Bearer <token>]String authHeader = request.getHeader(AUTH_HEADER);...String authToken = authHeader.split(" ")[1];if (!"123".equals(authToken)) {genUnauthResponse(response);return;}filterChain.doFilter(request, response);}
所以当从swagger-ui上调用API时,返回了401,如下图所示。那怎么才能正常调用API呢?接下来让我们看一下

Springdoc 使用@SecurityScheme 来定义一个安全模式,我们可以定义全局的,也可以针对某个controller定义类级别的,我们这里定义一个全局的。
- 在Application类上添加
@SecurityScheme
@SecurityScheme(name = "api_token", type = SecuritySchemeType.HTTP, scheme ="bearer", in = SecuritySchemeIn.HEADER)
@SpringBootApplication
public class SpringdocIntegrateApplication {public static void main(String[] args) {SpringApplication.run(SpringdocIntegrateApplication.class, args);}
}
我们定义了一个名为api_token的安全模式,并指定了其使用HTTP Bearer的方式。
- 使此安全模式生效
@Configuration
public class SpringDocConfig {@Beanpublic OpenAPI myOpenAPI() {return new OpenAPI()....security(List.of(new SecurityRequirement().addList("api_token")));}
}
注意api_token正是我们第一步定义的那个Security schema。
经过上面两步后查看生成的API文档,你会发现其右上角出现了一个Authorize的按钮, 而且每个API的右边也出现了一把小锁,如下图所示。

当点击Authorize按钮后会弹出一个让你提供认证信息的弹出,其根据不同的认证方式会有所区别。

我们这里需要输入一个token,然后点击Authorize按钮后关闭此弹窗。你会发现每个API右边的那把小锁从打开状态变为了关闭状态,颜色也从灰色变成了黑色,证明其生效了。
然后我们再来请求一下API,就会正常返回了。
- 声明是否需要认证
默认情况下按照上面两步设置后,整个应用程序的API生效,但是有的API是不需要认证的,例如登录。 对于这种情况,我们可以使用@SecurityRequirements()来设置。
@RestController
@RequestMapping(value = "/admin",produces = "application/json")
public class AuthController {...@SecurityRequirements()@PostMapping("/login")public Result<String> login(@RequestBody LoginRequest request){return Result.ok("123");}
}
@SecurityRequirements() 里面需要一个String数组,里面列出需要使用的@SecurityScheme,例如我们这里的api_token。如果不写就说明不需要任何的安全模式,这里就是这种情况。

从上图可以看出,/admin/login这个API右边没有小锁的标志,表示其不需要认证。针对本案例来说,不需要认证的意思就是:在发起这个请求的时候,不在Authentication header里面附加token。
这里只是展示了HTTP bearer 这种安全模式,其他的原理类似,小朋友们可以开动你们聪明的大脑研究一下,给补充到这里。
五、SpringDoc整合Knife4j
1.前世今生
在更名为Knife4j之前,原来的名称是叫swagger-bootstrap-ui,这是两种不一样风格的Ui,对比情况如下:
| 名称 | 开发语言&框架 | 状态 | 最后版本 | 风格 |
|---|---|---|---|---|
| Knife4j | Java、JavaScript、Vue | 持续更新中… | 无 | 黑色 |
| swagger-bootstrap-ui | Java、JavaScript、jQuery | 停更 | 1.9.6 | 蓝色 |
Knife4j从开源至今,目前主要经历版本的变化,分别如下:
| 版本 | 说明 |
|---|---|
| 1.0~1.9.6 | 名称是叫swagger-bootstrap-ui,蓝色风格Ui |
| 1.9.6 | 蓝色皮肤风格,开始更名,增加更多后端模块 |
| 2.0~2.0.5 | Ui基于Vue2.0+AntdV重写,黑色风格,参考示例,底层依赖的springfox框架版本是2.9.2,仅提供Swagger2规范的适配 |
| 2.0.6~2.0.9 | 底层springfox框架版本升级至2.10.5,仅提供Swagger2规范的适配 |
| 3.0~3.0.3 | 底层依赖springfox框架版本升级至3.0.3,OpenAPI规范是v3,过度版本,建议开发者不要使用 |
| 4.0~ | 区分OpenAPI2和Swagger3的Maven坐标artifactId OpenAPI2规范服务端解析框架稳定在springfox2.10.5 OpenAPI3框架服务端解析跟随springdoc项目更新迭代 建议开发者使用该版本,请参考4.x升级文档 |
2.Spring Boot版本兼容性
首先,确保您了解您的项目所使用的Spring Boot版本。
以下是一些常见的Spring Boot版本及其对应的Knife4j版本兼容推荐:
| Spring Boot版本 | Knife4j Swagger2规范 | Knife4j OpenAPI3规范 |
|---|---|---|
1.5.x~2.0.0 | <Knife4j 2.0.0 | >=Knife4j 4.0.0 |
2.0~2.2 | Knife4j 2.0.0 ~ 2.0.6 | >=Knife4j 4.0.0 |
2.2.x~2.4.0 | Knife4j 2.0.6 ~ 2.0.9 | >=Knife4j 4.0.0 |
2.4.0~2.7.x | >=Knife4j 4.0.0 | >=Knife4j 4.0.0 |
>= 3.0 | >=Knife4j 4.0.0 | >=Knife4j 4.0.0 |
Knife4j在之前的版本更新中,逐渐提供了一些服务端适配的增强特性功能。
但是开发者应该明白,不管是Swagger2规范还是OpenAPI3规范,Knife4j的最新版本的纯Ui版本,是可以适配Spring Boot所有版本的。
如果你不考虑使用Knife4j提供的服务端增强功能,引入Knife4j的纯Ui版本没有任何限制。只需要考虑不同的规范即可
3.Spring Boot 3
提示
Spring Boot 3 只支持OpenAPI3规范
Knife4j提供的starter已经引用springdoc-openapi的jar,开发者需注意避免jar包冲突
JDK版本必须 >= 17
详细Demo请参考knife4j-spring-boot3-demo
首先,引用Knife4j的starter,Maven坐标如下:
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.5.0</version>
</dependency>
其实现在就可以使用Knife4j了,暂不做其他配置,启动项目,浏览器输入http://localhost:8080/doc.html查看接口文档
由于我们没有进行任何的属性配置,所以看到的页面是knife4j的初始页面

引入之后,其余的配置,开发者即可完全参考springdoc-openapi的项目说明,Knife4j只提供了增强部分,如果要启用Knife4j的增强功能,可以在配置文件中进行开启
部分配置如下:
# springdoc-openapi项目配置
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: 'default'paths-to-match: '/**'packages-to-scan: com.xiaominfo.knife4j.demo.web
# knife4j的增强配置,不需要增强可以不配
knife4j:enable: truesetting:language: zh_cn
Knife4j更多增强配置明细,请移步文档进行查看
最后,使用OpenAPI3的规范注解,注释各个Spring的REST接口,示例代码如下:
@RestController
@RequestMapping("body")
@Tag(name = "body参数")
public class BodyController {@Operation(summary = "普通body请求")@PostMapping("/body")public ResponseEntity<FileResp> body(@RequestBody FileResp fileResp){return ResponseEntity.ok(fileResp);}@Operation(summary = "普通body请求+Param+Header+Path")@Parameters({@Parameter(name = "id",description = "文件id",in = ParameterIn.PATH),@Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),@Parameter(name = "name",description = "文件名称",required = true,in=ParameterIn.QUERY)})@PostMapping("/bodyParamHeaderPath/{id}")public ResponseEntity<FileResp> bodyParamHeaderPath(@PathVariable("id") String id,@RequestHeader("token") String token, @RequestParam("name")String name,@RequestBody FileResp fileResp){fileResp.setName(fileResp.getName()+",receiveName:"+name+",token:"+token+",pathID:"+id);return ResponseEntity.ok(fileResp);}
}
最后,访问Knife4j的文档地址:http://ip:port/doc.html即可查看文档
4.Spring Boot 2
提示
Spring Boot 版本建议 2.4.0~3.0.0之间
Spring Boot 版本 < 2.4 版本则建议选择Knife4j 4.0之前的版本
Spring Boot 2 + OpenAPI2 demo:knife4j-spring-boot27-demo
Spring Boot 2 + OpenAPI3 demo:knife4j-springdoc-openapi-demo
OpenAPI2
OpenAPI2(Swagger)规范是Knife4j之前一直提供支持的版本,底层依赖框架为Springfox,此次在4.0版本开始
Knife4j有了新的变化,主要有以下几点:
- Springfox版本选择的依然是2.10.5版本,而并非springfox最新3.0.0版本
- 不支持以Springfox框架为基础的OpenAPI3规范,放弃Springfox项目的后续版本适配支持工作
- Spring Boot 版本建议 2.4.0~3.0.0之间
可以使用 knife4j-openapi2-spring-boot-starter,maven 坐标如下:
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.5.0</version>
</dependency>
配置yml属性,如下:
knife4j:enable: trueopenapi:title: Knife4j官方文档description: "`我是测试`,**你知道吗**# aaa"email: xiaoymin@foxmail.comconcat: 八一菜刀url: https://docs.xiaominfo.comversion: v4.0license: Apache 2.0license-url: https://stackoverflow.com/terms-of-service-url: https://stackoverflow.com/group:test1:group-name: 分组名称api-rule: packageapi-rule-resources:- com.knife4j.demo.new3
最后,访问Knife4j的文档地址:http://ip:port/doc.html即可查看文档
OpenAPI3
OpenAPI3的规范,目前针对Java的Spring Boot项目,主要支持的有2个版本
- springfox 3.0.0: 同时兼容OpenAPI2以及OpenAPI3,但是停更很久了
- springdoc-openapi: 兼容OpenAPI3规范,更新速度频繁
Knife4j在只有的OpenAPI3规范中,底层基础框架选择springdoc-openapi项目
针对Springfox3.0.0版本会放弃。
建议开发者如果使用OpenAPI3规范的话,也尽快迁移过来。
可以使用 knife4j-openapi3-spring-boot-starter,maven 坐标如下:
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter</artifactId><version>4.5.0</version>
</dependency>
引入jar包后,同上面的Spring Boot 3版本使用方式一样,进行配置即可。
相关文章:
SpringDoc【使用详解】
SpringDoc使用详解 一、何为SpringDoc二、概念解释三、SpringDoc使用2.1简单集成2.2 配置SpringDoc2.2.1 yml方式配置2.2.2配置文档信息 2.3配置文档分组2.4使用注解2.4.1 Tag2.4.2 Operation2.4.3 Schema2.4.4 NotNull2.4.5 Parameter2.4.6 Parameters2.4.7 ApiResponses 和Ap…...
Redis持久化 | RDB AOF | 常见问题
目录 RDB(Redis DataBase) 给什么内存数据做快照——(全量) 触发机制 RDB文件生成的时候会阻塞主线程吗? 关闭持久化命令 bgsave执行流程 RDB文件怎么配置?有哪些优缺点 优点: 缺点&am…...
判断矩阵A是否可以相似对角化
【例题1】 【例题2】...
React 列表渲染
开发环境:Reacttsantd 你可能经常需要通过 JavaScript 的数组方法 来操作数组中的数据,从而将一个数据集渲染成多个相似的组件。在这篇文章中,你将学会如何在 React 中使用 filter() 筛选需要渲染的组件和使用 map() 把数组转换成组件数组。 …...
C#核心学习(八)面向对象--封装(7)终章 C#内部类和分部类、密封类
目录 一、内部类(Inner Class) 1. 什么是内部类? 2. 内部类的作用 3. 如何定义内部类? 4. 常见应用场景 二、分部类(Partial Class) 1. 什么是分部类? 2. 分部类的写法 3.…...
[ctfshow web入门] web25
信息收集 要想拿到flag,需要突破两层if。 解题 第一个if 传入r0,拿到mt_rand的值,由于每一次访问都会重新设置种子,所以每一次访问都是一样的随机数。 所以我们的r mt_rand-显示的值 1799250188 r1799250188就可以突破第一…...
局域网访问 Redis 方法
局域网访问 Redis 方法 默认情况下,Redis 只允许本机 (127.0.0.1) 访问。如果你想让局域网中的其他设备访问 Redis,需要 修改 Redis 配置,并确保 防火墙放行端口。 方法 1:修改 Redis 配置 1. 修改 redis.conf(或 me…...
oracle 索引失效
在 Oracle 11g 中,索引失效的常见原因包括函数修改列、隐式类型转换、统计信息过时等,解决方法需结合版本特性(如虚拟列、索引跳跃扫描)。通过执行计划分析、统计信息维护和合理使用提示(Hints),…...
网络安全-等级保护(等保) 0. 前言
各位伙伴好: 招投标总结已过去一年了,时间飞逝,一直忙于工作,等保相关的内容断断续续整理了近半年的时间,但一直无暇完成博客内容。 等保已经是一个成熟的体系,现在已进入等保2.0时代,相关政策…...
【数据结构】树的介绍
目录 一、树1.1什么是树?1.2 树的概念与结构1.3树的相关术语1.4 树形结构实际运用场景 二、二叉树2.1 概念与结构2.2 特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 个人主页,点击这里~ 数据结构专栏,点击这里~ 一、树 1.1什么是树࿱…...
大模型是如何把向量解码成文字输出的
hidden state 向量 当我们把一句话输入模型后,例如 “Hello world”: token IDs: [15496, 995]经过 Embedding Transformer 层后,会得到每个 token 的中间表示,形状为: hidden_states: (batch_size, seq_len, hidd…...
Android源码之App启动
目录 App启动概述 App启动过程 App启动过程图 源码概述 跨进程启动 进程内启动 下面以应用桌面Launcher启动App的MainActivity来举例: App启动概述 首先,MainActivity是由Launcher组件来启动的,而Launcher又是通过Activity管理服务Act…...
nginx如何实现负载均衡?
Nginx 是一款高性能的 Web 服务器和反向代理服务器,它可以通过配置实现负载均衡功能。以下是实现负载均衡的详细步骤和方法: 1. 基本概念 负载均衡是将客户端请求分发到多个后端服务器上,以提高系统的可用性和性能。Nginx 支持多种负载均衡策…...
【GESP】C++二级练习 luogu-B3721 [语言月赛202303] Stone Gambling S
GESP二级练习,多层循环分支练习,难度★✮☆☆☆。 题目题解详见:https://www.coderli.com/gesp-2-luogu-b3721/ 【GESP】C二级练习 luogu-B3721 [语言月赛202303] Stone Gambling S | OneCoderGESP二级练习,多层循环分支练习&am…...
2. Qt界面文件原理
本节主要介绍ui文件如何与窗口关联,并通过隐式连接方式显示对话框 本文部分ppt、视频截图原链接:[萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频] 1 UI文件如何与窗口关联 1.1 mainwindow.cpp的头文件ui_mainwindow.h 根据编译原理的基本规…...
Elastic 的 OpenTelemetry 分发版(EDOT)现已正式发布:开源、可用于生产环境的 OTel
作者:来自 Elastic Miguel Luna 及 Bahubali Shetti Elastic 自豪地宣布正式发布 Elastic OpenTelemetry 分发版(Elastic Distributions of OpenTelemetry - EDOT),其中包含 Elastic 自定义版本的 OpenTelemetry Collector 以及多…...
docker部署jenkins并成功自动化部署微服务
一、环境版本清单: docker 26.1.4JDK 17.0.28Mysql 8.0.27Redis 6.0.5nacos 2.5.1maven 3.8.8jenkins 2.492.2 二、服务架构:有gateway,archives,system这三个服务 三、部署步骤 四、安装linux 五、在linux上安装redis&#…...
UML对象图
UML对象图 一、对象图核心概念 对象图(Object Diagram)描述的是系统在某一时刻对象(实例)的状态快照。它关注的是实际对象之间的实例关系,而不是类与类之间的静态结构。主要特点有: 对象(Ob…...
【NLP 53、投机采样加速推理】
目录 一、投机采样 二、投机采样改进:美杜莎模型 流程 改进 三、Deepseek的投机采样 流程 Ⅰ、输入文本预处理 Ⅱ、引导模型预测 Ⅲ、候选集筛选(可选) Ⅳ、主模型验证 Ⅴ、生成输出与循环 骗你的,其实我在意透了 —— 25.4.4 一、…...
[250403] HuggingFace 新增检查模型与电脑兼容性的功能 | Firefox 发布137.0 支持标签组
目录 Hugging Face 让寻找兼容的 AI 模型变得更容易Firefox 137 版本更新摘要 Hugging Face 让寻找兼容的 AI 模型变得更容易 Hugging Face 是一个流行的在线平台,用于访问开源人工智能 (AI) 工具和模型。该平台推出了一项有用的新功能,允许个人轻松检查…...
VScode连接CentOS 7.6虚拟机
本文内容:在Windows上使用VMware运行虚拟机,然后使用VScode连接CentOS 7.6虚拟机。 进入系统前 安装VMware 安装教程参考:VMware安装 下载CentOS 7.6镜像 可以使用国内镜像源,但是一般国内镜像源要么已经不维护CentOS 7.6这个…...
Android Hilt 教程
Android Hilt 教程 —— 一看就懂,一学就会 1. 什么是 Hilt?为什么要用 Hilt? Hilt 是 Android 官方推荐的 依赖注入(DI)框架,基于 Dagger 开发,能够大大简化依赖注入的使用。 为什么要用 Hi…...
高德地图 3D 渲染-区域纹理图添加
引入-初始化地图(关键代码) // 初始化页面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申请的key值></script>// 添加地图容器 <div idcontainer ></div>// 地图初始化应该…...
K8S核心技术点
Pod,Service和Deployment的关系 Pod:Kubernetes 中最小的部署单元,用于运行容器化应用。 Service:提供服务发现和负载均衡,为 Pod 提供稳定的网络端点,ClusterIP,NodePort,LoadBala…...
Spring Boot 与 TDengine 的深度集成实践(二)
创建数据模型 定义实体类 在完成数据库连接配置后,我们需要创建与 TDengine 表对应的 Java 实体类。实体类是 Java 对象与数据库表之间的映射,通过定义实体类,我们可以方便地在 Java 代码中操作数据库中的数据,实现数据的持久化…...
搭建hadoop集群模式并运行
3.1 Hadoop的运行模式 先去官方看一看Apache Hadoop 3.3.6 – Hadoop: Setting up a Single Node Cluster. 本地模式:数据直接存放在Linux的磁盘上,测试时偶尔用一下 伪分布式:数据存放在HDFS,公司资金不足的时候用 完全分布式&a…...
Qt实现鼠标右键弹出弹窗退出
Qt鼠标右键弹出弹窗退出 1、鼠标右键实现1.1 重写鼠标点击事件1.2 添加头文件1.3 添加定义2、添加菜单2.1添加菜单头文件2.2创建菜单对象2.3 显示菜单 3、添加动作3.1添加动作资源文件3.2 添加头文件3.3 创建退出动作对象3.4菜单添加动作对象 4、在当前鼠标位置显示菜单4.1当前…...
Spring 服务调用接口时,提示You should be redirected automatically to target URL:
问题 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>Redirecting...</title><h1>Redirecting...</h1><p>You should be redirected automatically to target URL: <a href"http://xxx/api/v1/branch…...
Springboot整合Mybatis+Maven+Thymeleaf学生成绩管理系统
前言 该系统为学生成绩管理系统,可以当作学习参考,也可以成为Spirng Boot初学者的学习代码! 系统描述 学生成绩管理系统提供了三种角色:学生,老师,网站管理员。主要实现的功能如下: 登录 &a…...
马井堂js设置倒计时页面
js-倒计时页面 提示:这里简述项目相关背景: 例如:项目场景:倒计时需求 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible&…...
