Spring Boot 集成 Knife4j 的 Swagger 文档
在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j 的 Swagger,以实现 API 文档的自动生成和展示。
官网:Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j
源码:knife4j: Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案
1. UI 界面配置步骤
1.1. 添加依赖
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version>
</dependency>
1.2. 添加配置文件
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {/*** 该方法的主要作用是通过knife4j生成接口文档,若想要多个分组,则需要配置多个Docket实例** @return Docket 实例,用于Swagger接口文档的配置和生成*/@Beanpublic Docket docket(Environment environment) {// 构建API信息,用于Swagger文档的元数据ApiInfo apiInfo = new ApiInfoBuilder().title("swagger测试项目接口文档") // 设置API的标题.contact(new Contact("zjp", "http://termurl.com", "zjp@email.com")).version("1.0") // 设置API的版本.description("swagger测试项目接口文档") // 设置API的描述信息.termsOfServiceUrl("http://termurl.com") // 设置服务条款URL,非必要.license("Apache 2.0") // 设置API的授权协议,非必要.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0") // 设置授权协议的URL,非必要.build();// 创建Docket实例并进行配置Docket docket = new Docket(DocumentationType.SWAGGER_2) // 指定文档类型为Swagger2。支持SWAGGER_12(1.2版本)、SWAGGER_2(2.0版本)、OAS_30(3.0版本)等。多个实例版本不同会在各个版本中各生成一个文档.enable(environment.acceptsProfiles(Profiles.of("dev", "test"))) // 设置是否启用Swagger,默认为true,也可以通过环境变量或配置文件来动态控制.apiInfo(apiInfo) // 设置API信息.select() // 进入配置选择器// 若需要匹配指定包路径的控制器,可以使用basePackage()方法,可以是包名或类名,支持通配符*;// 若需要匹配所有路径,可以使用any()方法,例如:any();// 若需要匹配指定注解的控制器,可以使用withClassAnnotation()方法,例如:withClassAnnotation(RestController.class);// 若需要匹配指定方法注解的控制器,可以使用withMethodAnnotation()方法,例如:withMethodAnnotation(ApiOperation.class);// 若不需要匹配任何注解的控制器,可以使用none()方法,例如:none();.apis(RequestHandlerSelectors.basePackage("com.zjp.knife4jswaggerdemo.controller"))// 若需要匹配指定类,可以使用any()方法,例如:any();// 若需要匹配指定路径,可以使用ant()方法,例如:ant("/api/**");// 若需要排除某些路径,可以使用ant()方法,例如:ant("!/api/**");// 若需要匹配以指定字符串结尾的路径,可以使用ant()方法,例如:ant("/**/api");// 若需要匹配以指定字符串开头的路径,可以使用regex()方法,例如:regex("/api/.*");// 若不需要匹配任何路径,可以使用none()方法,例如:none().paths(PathSelectors.any()).build() // 结束配置并构建Docket实例.groupName("default"); // 设置分组名称,多个分组名称不能重名
// .pathMapping("/") // 设置路径映射,用于指定Swagger UI的根路径,默认为/。
// .protocols(new HashSet<>(Arrays.asList("http", "https"))) // 设置支持的协议
// .securitySchemes(Collections.singletonList(new ApiKey("token", HttpHeaders.AUTHORIZATION, In.HEADER.toValue()))) // 授权信息设置,必要的header token等认证信息
// .securityContexts(Collections.singletonList(
// SecurityContext.builder()
// .securityReferences(Collections.singletonList(new SecurityReference("token", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
// .build())); // 设置全局安全上下文,用于指定全局的授权信息return docket;}/*** 该方法的主要作用是通过knife4j生成接口文档,若想要多个分组,则需要配置多个Docket实例* 例如配置第二个Docket实例,分组名称为api** @return Docket 实例,用于Swagger接口文档的配置和生成*/@Beanpublic Docket docket1() {// 构建API信息,用于Swagger文档的元数据ApiInfo apiInfo = new ApiInfoBuilder().title("swagger测试项目接口文档").version("1.0").description("swagger测试项目接口文档").build();// 创建Docket实例并进行配置Docket docket = new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo) // 设置API信息.select() // 进入配置选择器.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)).paths(PathSelectors.ant("/api/**")).build().groupName("api");return docket;}/*** 该方法用于在Spring MVC中配置静态资源的访问路径和位置* 它通过ResourceHandlerRegistry对象来注册资源处理器,* 从而使得特定URL路径下的请求能够映射到应用程序的静态资源上** @param registry ResourceHandlerRegistry实例,用于注册资源处理器*/protected void addResourceHandlers(ResourceHandlerRegistry registry) {// 映射/doc.html到classpath:/META-INF/resources/,以便访问该路径时能够获取到相应的静态文件registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");// 映射/webjars/**到classpath:/META-INF/resources/webjars/,用于支持webjars资源的访问registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}
}
1.3. 启动测试
浏览器访问 http://localhost:8080/doc.html ,访问结果如下图:
界面说明:
左上角的下拉框对应的分组,如下图所示:
主页对应的是 ApiInfo 里的信息及 Docket 里的 groupName 。
在文档管理-全局参数设置可以设置全局请求头和参数。
2. 使用swagger
2.1. 常用注解
注解 | 用途 | 示例 |
@Api | 标记一个控制器类,描述该类的功能 | @Api(value = "用户管理相关接口", tags = {"用户管理"}) |
@ApiOperation | 描述一个 API 接口的方法 | @ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户信息") |
@ApiParam | 描述方法参数 | @ApiParam(name = "id", value = "用户ID", required = true) |
@ApiImplicitParam | 描述隐式参数,常用于 GET 请求的查询参数 | @ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header") |
@ApiImplicitParams | 描述多个隐式参数 | @ApiImplicitParams({ @ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header"), @ApiImplicitParam(name = "page", value = "页码", required = false, dataType = "integer", paramType = "query") }) |
@ApiResponse | 描述方法的响应信息 | @ApiResponse(code = 200, message = "成功返回用户信息") |
@ApiResponses | 描述多个响应信息 | @ApiResponses({ @ApiResponse(code = 200, message = "成功返回用户信息"), @ApiResponse(code = 404, message = "用户不存在") }) |
@ApiModel | 描述一个模型类 | @ApiModel(description = "用户信息") |
@ApiModelProperty | 描述模型类的属性 | @ApiModelProperty("主键值") |
@ApiIgnore | 忽略某个方法或类,不生成 API 文档 | @ApiIgnore |
@ApiExample | 描述 API 示例请求 | @ApiExample(value = "获取用户信息示例", source = "GET /users/{id}") |
2.2. 使用示例
controller层使用示例:
import com.zjp.knife4jswaggerdemo.pojo.User;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@Api(value = "用户管理相关接口", tags = {"用户管理"})
public class UserController {@GetMapping("/getUser")@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户信息")@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header"),@ApiImplicitParam(name = "page", value = "页码", required = false, dataType = "integer", paramType = "query")})@ApiResponses({@ApiResponse(code = 200, message = "成功返回用户信息"),@ApiResponse(code = 404, message = "用户不存在")})public User getUser(@ApiParam(name = "id", value = "用户ID", required = true) @RequestParam Integer id) {User user = new User();user.setId(1);user.setName("Alice");user.setAge(18);user.setSex("female");return user;}
}
实体类使用示例:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(value = "用户信息", description = "用户信息实体类")
public class User {@ApiModelProperty(value = "主键值", example = "1001")private Integer id;@ApiModelProperty(value = "名称", example = "Bob")private String name;@ApiModelProperty(value = "年龄", example = "32")private Integer age;@ApiModelProperty(value = "性别", example = "male")private String sex;
}
2.3. 启动测试
浏览器访问 http://localhost:8080/doc.html ,访问结果如下图:
实体类信息如下(不调用实体类这里不会展示实体类信息):
接口文档:
测试接口:
3. 其他配置
属性 | 默认值 | 说明值 |
---|---|---|
knife4j.enable | false | 是否开启Knife4j增强模式 |
knife4j.cors | false | 是否开启一个默认的跨域配置,该功能配合自定义Host使用 |
knife4j.production | false | 是否开启生产环境保护策略,详情参考文档 |
knife4j.basic | 对Knife4j提供的资源提供BasicHttp校验,保护文档 | |
knife4j.basic.enable | false | 关闭BasicHttp功能 |
knife4j.basic.username | basic用户名 | |
knife4j.basic.password | basic密码 | |
knife4j.documents | 自定义文档集合,该属性是数组 | |
knife4j.documents.group | 所属分组 | |
knife4j.documents.name | 类似于接口中的tag,对于自定义文档的分组 | |
knife4j.documents.locations | markdown文件路径,可以是一个文件夹(classpath:markdowns/* ),也可以是单个文件(classpath:md/sign.md ) | |
knife4j.setting | 前端Ui的个性化配置属性 | |
knife4j.setting.enable-after-script | true | 调试Tab是否显示AfterScript功能,默认开启 |
knife4j.setting.language | zh-CN | Ui默认显示语言,目前主要有两种:中文(zh-CN)、英文(en-US) |
knife4j.setting.enable-swagger-models | true | 是否显示界面中SwaggerModel功能 |
knife4j.setting.swagger-model-name | Swagger Models | 重命名SwaggerModel名称,默认 |
knife4j.setting.enable-document-manage | true | 是否显示界面中"文档管理"功能 |
knife4j.setting.enable-reload-cache-parameter | false | 是否在每个Debug调试栏后显示刷新变量按钮,默认不显示 |
knife4j.setting.enable-version | false | 是否开启界面中对某接口的版本控制,如果开启,后端变化后Ui界面会存在小蓝点 |
knife4j.setting.enable-request-cache | true | 是否开启请求参数缓存 |
knife4j.setting.enable-filter-multipart-apis | false | 针对RequestMapping的接口请求类型,在不指定参数类型的情况下,如果不过滤,默认会显示7个类型的接口地址参数,如果开启此配置,默认展示一个Post类型的接口地址 |
knife4j.setting.enable-filter-multipart-api-method-type | POST | 具体接口的过滤类型 |
knife4j.setting.enable-host | false | 是否启用Host |
knife4j.setting.enable-host-text | false | HOST地址 |
knife4j.setting.enable-home-custom | false | 是否开启自定义主页内容 |
knife4j.setting.home-custom-path | 主页内容Markdown文件路径 | |
knife4j.setting.enable-search | false | 是否禁用Ui界面中的搜索框 |
knife4j.setting.enable-footer | true | 是否显示Footer |
knife4j.setting.enable-footer-custom | false | 是否开启自定义Footer |
knife4j.setting.footer-custom-content | false | 自定义Footer内容 |
knife4j.setting.enable-dynamic-parameter | false | 是否开启动态参数调试功能 |
knife4j.setting.enable-debug | true | 启用调试 |
knife4j.setting.enable-open-api | true | 显示OpenAPI规范 |
knife4j.setting.enable-group | true | 显示服务分组 |
3.1. 访问权限控制
对应官网原文:3.5 访问权限控制 | Knife4j
3.1.1. 生产环境禁用
目前Springfox-Swagger以及Knife4j提供的资源接口包括如下:
资源 | 说明 |
---|---|
/doc.html | Knife4j提供的文档访问地址 |
/v2/api-docs-ext | Knife4j提供的增强接口地址,自2.0.6 版本后删除 |
/swagger-resources | Springfox-Swagger提供的分组接口 |
/v2/api-docs | Springfox-Swagger提供的分组实例详情接口 |
/swagger-ui.html | Springfox-Swagger提供的文档访问地址 |
/swagger-resources/configuration/ui | Springfox-Swagger提供 |
/swagger-resources/configuration/security | Springfox-Swagger提供 |
springdoc以及Knife4j提供的资源接口包括如下:
资源 | 说明 |
---|---|
/doc.html | Knife4j提供的文档访问地址 |
/v3/api-docs | springdoc提供的实例接口 |
/v3/api-docs/swagger-config | springdoc提供的分组接口 |
/v3/api-docs/** | 分组 |
/swagger-ui/index.html | springdoc提供的文档访问地址 |
当我们部署系统到生产系统,为了接口安全,需要屏蔽所有Swagger的相关资源
如果使用SpringBoot框架,只需在application.properties
或者application.yml
配置文件中配置:
knife4j:# 开启增强配置 enable: true# 开启生产环境屏蔽production: true
配置此属性后,所有资源都会屏蔽输出.
效果图如下:
3.1.2. 登录认证
不管是官方的swagger-ui.html
或者doc.html
,目前接口访问都是无需权限即可访问接口文档的,很多朋友以前问我能不能提供一个登陆界面的功能,开发者输入用户名和密码来控制界面的访问,只有知道用户名和密码的人才能访问此文档
做登录页控制需要有用户的概念,所以相当长一段时间都没有提供此功能
针对Swagger的资源接口,Knife4j
提供了简单的Basic认证功能
效果图如下:
允许开发者在配置文件中配置一个静态的用户名和密码,当对接者访问Swagger页面时,输入此配置的用户名和密码后才能访问Swagger文档页面,如果您使用SpringBoot开发,则只需在相应的application.properties
或者application.yml
中配置如下:
knife4j:# 开启增强配置 enable: true# 开启Swagger的Basic认证功能,默认是falsebasic:enable: true# Basic认证用户名username: test# Basic认证密码password: 123
如果用户开启了basic认证功能,但是并未配置用户名及密码,Knife4j
提供了默认的用户名和密码:
admin/123321
3.2. 请求参数缓存
在默认情况下,在接口调试的情况下,Knifetj对于接口的请求参数都会缓存起来,该配置可以在前端界面中的个性化设置中看到,如下图:
缓存的情况只会在后端没有给属性example
的情况下产生,如果后端在写Swagger的注解的时候,给每个字段赋予了example的值,那么,Knife4j
不会使用调试时缓存的值,而是会一直使用后端的example值。
当然,开发者也可以在后端控制文档的接口调试功能,针对请求后的参数是否需要缓存(自2.0.6版本开始)
yml配置如下:
knife4j:enable: truesetting:# 对于调试中的请求参数是否缓存进行开启配置,该参数默认为trueenable-request-cache: true
也可以手动清理缓存:
3.3. 动态请求参数
方式一:后台开启
开发者也可以通过开启Knife4j的增强配置,进行默认开启,配置如下:
knife4j:enable: truesetting:# 开启动态请求参数,true-开启,false-关闭enable-dynamic-parameter: true
方式二:界面开启
当在配置中勾选该选项后,我们的接口栏会有变化,如下图:
在原本已存在的参数栏下会出现一栏空的参数栏,开发者可以输入参数名称、参数值对参数进行添加
不管是参数名称的变化还是参数值的变化,变化后会自动追加一行新的调试栏参数,效果图如下:
相关文章:

Spring Boot 集成 Knife4j 的 Swagger 文档
在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j …...
极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【一】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料: 极狐GitLab 官网极狐…...

C# 在Word文档模板中,按照占位符插入文字或图片
1,引入包:DocX 2,代码如下 public class CC{public static void Ma22in(){// 示例:加载现有模板并替换占位符string templatePath "报告模板.docx"; // 模板文件路径string outputPath "Output.docx"; // 输出文…...

在使用PCA算法进行数据压缩降维时,如何确定最佳维度是一个关键问题?
一、PCA算法的基本原理 PCA算法的核心思想是通过正交变换,将一组可能相关的变量转换成一组线性不相关的变量,称为主成分。这组主成分能够以最小的信息损失来尽可能多地保留原始数据集的变异性。具体来说,PCA算法包括以下几个步骤:…...
深度学习3
五、自动微分 1、基础概念 模块 autograd 负责自动计算张量操作的梯度,具有自动求导功能;autograd 创建一个动态计算图来跟踪张量的操作,每个张量是计算图中的一个节点,节点之间的操作构成图的边。 属性 requires_grad 决定…...

Qt5.14.2的安装与环境变量及一些依赖库的配置
目录 1.Qt5.14.2安装 2.Qt环境变量及一些依赖库的配置 1.Qt5.14.2安装 QT从入门到入土(一)——Qt5.14.2安装教程和VS2019环境配置 - 唯有自己强大 - 博客园 2.Qt环境变量及一些依赖库的配置 假设QT安装目录为: D:\Qt\Qt5.14.2 将目录: D:\Qt\Qt5.14.…...

PYNQ 框架 - 时钟系统 + pl_clk 时钟输出不准确问题
目录 1. 简介 2. PS 时钟计算 2.1 计算框架 2.2 KV260 的参考时钟 2.3 PL_CLK 设置 3. 测试 3.1 Block design 3.2 引脚绑定 3.3 使用 AD2 测量 3.4 调整分频 4. PYNQ 时钟驱动 4.1 源码解析 4.2 查看 PL_CLK 4.3 配置 PL_CLK 5. 总结 1. 简介 ZYNQ MPSoC 具有…...
CDAF / PDAF 原理 | PDAF、CDAF 和 LAAF 对比 | 图像清晰度评价指标
注:本文为 “CDAF / PDAF 原理 | PDAF、CDAF 和 LAAF 对比 | 图像清晰度评价指标” 几篇相关文章合辑。 文章中部分超链接、图片异常受引用之前的原文所限。 相机自动对焦原理 TriumphRay 于 2020-01-16 18:59:41 发布 凸透镜成像原理 这一部分大家中学应该就学过…...

类和对象--中--初始化列表(重要)、隐式类型转化(理解)、最后两个默认成员函数
1.初始化列表 1.1作用: 通过特定的值,来初始化对象。 1.2定义: 初始化列表,就相当于定义对象(开空间)。不管写不写初始化列表,每个成员变量都会走一遍初始化列表(开出对应的空间…...

uni-app运行 安卓模拟器 MuMu模拟器
最近公司开发移动端系统,使用真机时每次调试的时候换来换去的麻烦,所以使用模拟器来调试方便。记录一下安装和连接的过程 一、安装MuMu模拟器 百度搜索MuMu模拟器并打开官网或者点这里MuMu模拟器官网 点击下载模拟器 安装模拟器,如果系统…...
java 打印对象所有属性的值 循环
在Java中,如果你想要打印一个对象的所有属性值,可以使用反射(Reflection)来获取对象的所有字段,并循环遍历这些字段以打印它们的值。以下是一个示例代码,展示了如何实现这一点: 示例类 假设我…...
k8s认证、授权
在 Kubernetes 中,kubectl auth can-i 命令用于检查当前用户或指定的 ServiceAccount 是否有权限执行特定的操作: kubectl auth can-i create deployment --as system:serviceaccount:default:dev-sa这个命令的作用是检查名为 dev-sa 的 ServiceAccount…...

基于spring boot的纺织品企业财务管理系统论文
摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升&…...
@RequestBody和前端的关系以及,如何在前后端之间传递数据?
RequestBody 注解在 Spring MVC 中用于将 HTTP 请求体中的数据绑定到控制器方法的参数上。为了更好地理解 RequestBody 和前端之间的关系,我们可以从以下几个方面进行探讨: 1. 请求体的格式 前端发送的请求体通常是一个 JSON 字符串,也可以…...

详解登录MySQL时出现SSL connection error: unknown error number错误
目录 登录MySQL时出错SSL connection error: unknown error number 出错原因 使用MySQL自带的工具登录MySQL 登陆之后,使用如下命令进行查看 解决方法 找到MySQL8安装目录下的my.ini配置文件 记事本打开my.ini文件,然后按下图所示添加配置 此时再…...

【大数据学习 | Spark-Core】Spark的改变分区的算子
当分区由多变少时,不需要shuffle,也就是父RDD与子RDD之间是窄依赖。 当分区由少变多时,是需要shuffle的。 但极端情况下(1000个分区变成1个分区),这时如果将shuffle设置为false,父子RDD是窄依赖关系&…...
Spring Boot Web应用开发:测试
在Spring Boot中,测试是开发过程的一个重要部分,它确保你的应用按预期工作,并且可以帮助你在早期发现和修复问题。Spring Boot提供了多种便捷的测试工具,使得编写和运行测试案例变得简单。 Spring Boot测试简介 Spring Boot支持…...

服务器数据恢复—光纤存储FC硬盘数据恢复案例
服务器存储数据恢复环境: 某品牌光纤存储上共有16块FC硬盘。存储上的卷映射到Linux操作系统上。Linux操作系统上运行Oracle数据库。 服务器存储故障&检测: 存储上2块硬盘故障灯亮起,存储映射到linux操作系统上的卷挂载不上,业…...

Android Binder技术概览
Android中的Binder是一种基于远程过程调用(Remote Procedure Call, RPC)的轻量级通信机制,核心用于 Android 系统中的进程间通信(Inter-Process Communication, IPC)。Binder 是 Android 系统中不可或缺的一部分&#…...

09 —— Webpack搭建开发环境
搭建开发环境 —— 使用webpack-dev-server 启动Web服务,自动检测代码变化,有变化后会自动重新打包,热更新到网页(代码变化后,直接替换变化的代码,自动更新网页,不用手动刷新网页) …...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...