Spring Boot 4.0 + gRPC 极简集成:4步搞定,比REST还丝滑

如何在Spring Boot中使用gRPC 通过本文,我们详细介绍了如何在Spring Boot应用中集成和使用gRPC框架,利用其高效的RPC通信机制和自动生成的代码,帮助开发者构建高性能、可扩展的分布式系统。它可以更高效地连接跨语言和跨平台的服务,提供了简单的IDL(接口定义语言)和强大的代码生成工具,帮助开发者快速构建分布式系统。通过集成gRPC,可以利用其高效的底层通信协议和自动生成的客户端和服务端代码,简化分布式系统的开发和维护。首先,定义gRPC的服务和消息类型。编写Spring Boot中的gRPC客户端代码,调用远程的gRPC服务。 阅读详情

01 引言

gRPC 是 Google 开源的高性能 RPC 框架,基于 HTTP/2 + Protocol Buffers,序列化效率和传输速度都比传统 REST + JSON 高出一截,在微服务内部通信、移动端调用、跨语言服务等场景下非常吃香。

但传统 gRPC 的 Java 集成姿势比较原始:手写 ServerBuilder、手写 ManagedChannel、手写拦截器链,样板代码一堆。Spring gRPC(1.0.x,2025 年正式发布)的目标就是把这些脏活全包了,让你像写普通 Spring Boot 应用一样写 gRPC。

02 环境准备

Spring gRPC对环境还是有要求的:

  • 最低Java17
  • Spring Framework 7.0.1
  • Spring gRPC 1.0.x使用Spring Boot要求4.0.x

03 Spring gRPC Server

3.1 Maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-grpc-server</artifactId>
</dependency>

使用Spring的脚手架,还引入了protobuf-maven-plugin编译插件。

Protobuf 编译插件,让 Maven/Gradle 自动把 .proto 文件编译成 Java 类。

3.2 定义 proto 文件

在 src/main/proto/hello.proto 创建服务定义(注意把 java_package 换成你自己的包名)。

使用Spring脚手架自动生成proto文件包。

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.simonking.ws.boot.grpc.server.proto";
option java_outer_classname = "UserProto";

package user;

// 用户信息服务 - 展示多参数 gRPC 方法
service UserService {
  // 多参数创建用户
  rpc CreateUser (CreateUserRequest) returns (CreateUserResponse);
  // 多参数查询用户
  rpc GetUser (GetUserRequest) returns (GetUserResponse);
}

// ============ 通用消息 ============

// 用户信息
message UserInfo {
  int64 id = 1;
  string username = 2;
  string email = 3;
  int32 age = 4;
  string phone = 5;
  string created_at = 6;
  string updated_at = 7;
}

// ============ 创建用户 (多参数) ============

message CreateUserRequest {
  string username = 1;
  string email = 2;
  int32 age = 3;
  string phone = 4;
  string password = 5;
  string nickname = 6;
}

message CreateUserResponse {
  bool success = 1;
  string message = 2;
  int64 user_id = 3;
}

// ============ 查询用户 ============

message GetUserRequest {
  int64 user_id = 1;
}

message GetUserResponse {
  bool success = 1;
  string message = 2;
  UserInfo user = 3;
}

在这里定义方法,参数以及响应。

字段说明:

  • java_package:生成的 Java 类放在哪个包
  • java_multiple_files = true:每个 message 一个独立 .java 文件(推荐)
  • java_outer_classname:容器类名(一般用不到,因为开了 multiple_files)
  • 字段后面的 = 1 是 protobuf 的字段编号,不能改也不能重用,是序列化兼容性的关键

3.3 编译生成stub

执行:

./mvnw clean compile

编译完成之后,会在target/generated-sources/protobuf 生成对应的实体和服务:

IntelliJ 用户注意:右键 target/generated-sources 目录 → Mark Directory as → Generated Sources Root,否则 IDE 识别不到。

3.4 实现方法

继承XxxGrpc.XxxImplBase即可。

@GrpcService
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
    private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 内存存储模拟数据库
    private final ConcurrentHashMap<Long, UserInfo> userStore = new ConcurrentHashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(1);

    // ===================== 1. 创建用户 =====================

    @Override
    public void createUser(CreateUserRequest request,
                           StreamObserver<CreateUserResponse> responseObserver) {
        long userId = idGenerator.getAndIncrement();
        String now = LocalDateTime.now().format(DTF);

        UserInfo user = UserInfo.newBuilder()
                .setId(userId)
                .setUsername(request.getUsername())
                .setEmail(request.getEmail())
                .setAge(request.getAge())
                .setPhone(request.getPhone())
                .setCreatedAt(now)
                .setUpdatedAt(now)
                .build();

        userStore.put(userId, user);

        CreateUserResponse response = CreateUserResponse.newBuilder()
                .setSuccess(true)
                .setMessage("用户创建成功")
                .setUserId(userId)
                .build();

        responseObserver.onNext(response);
        responseObserver.onCompleted();
        log.info("===== createUser 响应: userId={} =====", userId);
    }

    // ===================== 2. 查询用户 =====================

    @Override
    public void getUser(GetUserRequest request,
                        StreamObserver<GetUserResponse> responseObserver) {
        log.info("===== getUser: userId={} =====", request.getUserId());

        UserInfo user = userStore.get(request.getUserId());
        if (user == null) {
            GetUserResponse response = GetUserResponse.newBuilder()
                    .setSuccess(false)
                    .setMessage("用户不存在: " + request.getUserId())
                    .build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
            return;
        }

        GetUserResponse response = GetUserResponse.newBuilder()
                .setSuccess(true)
                .setMessage("查询成功")
                .setUser(user)
                .build();

        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

注意实现类上的注解:org.springframework.grpc.server.service.GrpcService

3.5 启动类

启动类不需要额外的编写,但是启动类帮我们做了三件事:

  • 启动 Netty-based gRPC Server
  • 监听 spring.grpc.server.port(默认 9090)
  • 把所有 BindableService Bean 注册上去

04 Spring gRPC Client

客户端的编写和服务端差不多。

4.1 Maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-grpc-client</artifactId>
</dependency>

<build>
    <plugins>
        <plugin>
            <groupId>io.github.ascopes</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

3.2 定义 proto 文件

同服务端

3.3 编译生成stub

同服务端

3.4 配置客户端

由于gRPC基于Netty,所以需要配置通道信息。

@Configuration
public class GrpcClientConfig {

    @Value("${grpc.client.host:localhost}")
    private String host;

    @Value("${grpc.client.port:9090}")
    private int port;

    @Bean(destroyMethod = "shutdown")
    public ManagedChannel grpcChannel() {
        return ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext()
                .build();
    }

    @Bean
    public UserServiceGrpc.UserServiceBlockingStub blockingStub(ManagedChannel channel) {
        return UserServiceGrpc.newBlockingStub(channel);
    }
}

3.5 调用方法

@RestController
@RequestMapping("/user")
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserServiceBlockingStub blockingStub;

    // ===================== 1. 创建用户 =====================

    @PostMapping("/create")
    public Map<String, Object> createUser() {
        CreateUserRequest request = CreateUserRequest.newBuilder()
                .setUsername("test_user")
                .setEmail("test@example.com")
                .setAge(25)
                .setPhone("13800138000")
                .setPassword("123456")
                .setNickname("测试用户")
                .build();

        CreateUserResponse resp = blockingStub.createUser(request);
        log.info("createUser -> userId={}", resp.getUserId());
        return Map.of("success", resp.getSuccess(), "message", resp.getMessage(), "userId", resp.getUserId());
    }

    // ===================== 2. 查询用户 =====================

    @GetMapping("/{userId}")
    public Map<String, Object> getUser(@PathVariable long userId) {
        GetUserRequest request = GetUserRequest.newBuilder()
                .setUserId(userId)
                .build();
        GetUserResponse resp = blockingStub.getUser(request);

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("success", resp.getSuccess());
        result.put("message", resp.getMessage());
        if (resp.hasUser()) {
            result.put("user", toUserMap(resp.getUser()));
        }
        return result;
    }

    // ===================== 工具方法 =====================

    private Map<String, Object> toUserMap(UserInfo user) {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("id", user.getId());
        map.put("username", user.getUsername());
        map.put("email", user.getEmail());
        map.put("age", user.getAge());
        map.put("phone", user.getPhone());
        map.put("createdAt", user.getCreatedAt());
        map.put("updatedAt", user.getUpdatedAt());
        return map;
    }
}

3.6 测试

创建用户

查询用户

springboot整合gprc 传输对象 一,grpc简介: GRPC是google开源的一个高性能、跨语言的RPC框架,基于HTTP2协议,基于protobuf 3.x,基于Netty 4.x +。GRPC与thrift、avro-rpc等其实在总体原理上并没有太大的区别,简而言之GRPC并没有太多突破性的创新。    对于开发者而言:    1)需要使用protobuf定义接口,即.proto文件    2)然后使用compile工具... 阅读详情

相关推荐

Spring Boot整合LangChain4j与Qdrant:5分钟搞定向量数据库相似搜索

本文详细介绍了如何使用Spring Boot快速整合LangChain4j与Qdrant向量数据库,实现高效的语义搜索系统。通过5分钟的部署和编码,开发者可以轻松构建基于向量相似度的搜索服务,适用于电商、知识库等多种场景,提升搜索准确性和用户体验。

weixin_29091105的博客 273

Spring boot使用gRPC 的详细教程

本篇文章,我们介绍gRPC并通过例子详细演示使用gRPC的过程。

u013643074的博客 4884

Camunda工作流引擎实战:审批流程从建模到Spring Boot落地

工作流引擎将业务审批中的流程编排、状态流转与业务逻辑解耦,通过显式的流程定义替代散落的数据库状态字段,使流程变更无需发版、执行轨迹可追溯。BPMN作为可执行的流程建模语言,通过事件、网关、任务等元素描述分支、并行与异常边界,结合DMN决策表可进一步将规则判断从代码中剥离。这一机制在OA审批、订单处理、制造业点检等场景广泛应用,尤其适合基于Spring Boot构建的Java服务,以嵌入式方式获得流程实例管理、用户任务分配与历史数据查询能力。文本以Camunda 7.20为例,从模型设计、服务部署、用户任务与

weixin_31960565的博客 248

Springboot整合Grpc,实现服务间通信

通过Grpc实现服务间通信!!!

菜鸟博客 2551

Java + YOLOv8联邦学习落地:多工厂数据隐私保护下的模型协同训练(附Flower框架集成)

隐私与精度兼顾:数据不出厂,仅传参数,同时融合多工厂特征提升模型精度;企业级适配:Java管控端适配现有企业系统,支持节点权限、任务管控;合规性达标:符合数据隐私法规,避免企业数据合规风险。

2601_94871597的博客 402

Spring Boot 实现轻量级 JSON-RPC 服务实战

JSON-RPC 是一种基于 JSON 的远程过程调用协议,以方法名+参数+ID 为核心语义,相比 REST 更聚焦业务动作、相比 gRPC 更易在浏览器端调试。其原理在于通过标准 HTTP POST 承载结构化请求体,依赖服务端协议解析、方法路由、参数绑定与异常映射四层机制实现跨语言调用。技术价值体现在协议轻量、边界清晰、调试高效,尤其适合内部系统、管理后台、课程设计等中等复杂度场景。本文围绕 Spring Boot 构建可生产级 JSON-RPC Server,涵盖自定义注解、批量请求支持、Spring

weixin_31240035的博客 93

SpringBoot整合gRPC——入门级应用(详细注释)

一个简单的gRPCDemo,展示了阻塞调用和异步调用。如果有错误,欢迎大家指出,谢谢~

weixin_53306150的博客 2444

英飞凌 AURIX Development Studio工程移植到Hightec的方法

1. 软件简介 AURIX™ Development Studio是英飞凌针对AURIX TC2XX/TC3XX系列单片机推出了一款免费的软件,集成了iLLD库,内置Tasking compiler和Tasking Debugger,但这两个模块只能用于非商业用途,可供学习和试用。iLLD库是英飞凌为TC2XX和TC3XX Tricore系列单片机提供的底层驱动库,有完善的使用手册,和较好的移植性。 Hightec是一款可以用来开发Aurix系列单片机的编译器,有免费版,可商用,集成GCC编译器,可用UDE

weixin_42967006的博客 7137

Spring Boot - Spring Boot + gRPC 实战指南

本文介绍了Spring Boot与gRPC的集成方案,通过高性能的Protocol Buffers协议提升微服务通信效率。主要内容包括:gRPC相比REST API的优势(二进制序列化、HTTP/2多路复用等);基于.proto文件定义服务接口的流程;Spring Boot项目配置gRPC所需依赖;服务端实现与客户端调用方法;以及REST接口集成方案。文章还提供了完整的技术架构图和Maven配置示例,帮助开发者快速实现高效的微服务通信。

小工匠 2002

从ATE到ATPG:基于Scan Chain的芯片制造缺陷定位实战解析

本文深入解析了从ATE到ATPG的芯片制造缺陷定位实战技术,重点介绍了Scan Chain的工作原理、异步复位触发器处理技巧以及Design Compiler中的DFT实现方法。通过实际案例展示了如何利用ATE测试数据和ATPG工具进行精确的缺陷定位,并分享了提升测试覆盖率和优化测试成本的专业技巧,为芯片测试工程师提供了宝贵的实战经验。

weixin_42527160的博客 380

408——计算机组成原理(持续更新)

小数点前的0代表正数,1代表负数。

qq_55202378的博客 1722

Spring Cloud Samples 大升级:AI 智能体 + gRPC + Seata 分布式事务,三大重磅模块来袭

在→@Tool(注解更名)ChatClient构建方式统一为base-url需带/v1后缀MCP Server 配置通过完成提供生产环境可参考的微服务全栈示例。AI 集成—— 不是 Demo 级别的"Hello World",而是覆盖 Tool Calling、ReAct Agent、MCP Server 的完整方案gRPC 通信—— Spring Boot 原生支持,告别第三方 starter 的兼容性焦虑分布式事务。

武汉红喜 334

AgentScope实战训练营-Java开发HITL人机协作AI应用完整指南

本文手把手带你从零搭建一个基于 Spring Boot WebFlux + AgentScope + 通义千问的人机协作(HITL)AI 聊天应用。项目涵盖流式对话、工具调用、高危操作确认、对话中断、动态 MCP 工具接入、中英文双语界面等完整功能。文章从环境准备、pom.xml 配置、DTO 数据模型、Hook 机制、AgentService 核心服务、ChatController 接口到前端 HTML/CSS/JS 实现,逐一讲解每行代码的设计意图,并附带 REST API 接口说明、测试场景、常见问题

program哲学 713

RMBG-2.0与Spring Boot结合:构建企业级API服务

本文介绍了如何在星图GPU平台上自动化部署RMBG-2.0背景移除(内置模型版)v1.0镜像,快速构建企业级图片处理API服务。该方案将AI模型与Spring Boot后端结合,为电商等场景提供高效的批量商品图片背景移除能力,显著提升内容处理效率。

weixin_35755640的博客 879

MTK平台WiFi学习--Wi-Fi 连线/断线问题初步分析

摘要:本文详细介绍了MTK平台WiFi连接问题的日志分析方法。文章首先阐述了WiFi连接的标准流程,包括指令接收、BSSID选择、信道分配、认证关联、四次握手和DHCP获取等关键步骤。针对常见故障场景,如选网失败、信道申请失败、认证关联失败、四次握手失败等,提供了具体的日志分析方法和排查思路,包括识别关键日志、分析状态码、结合固件日志和抓包数据等。文章还特别强调了不同故障场景下需要收集的日志类型和分析要点,为WiFi连接问题的定位提供了一套系统化的解决方案。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 1591

uniapp - 应用软件在运行时,未见向用户告知权限申请的目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准(uniApp开发安卓APP上架应用市场审核被拒绝驳回,详细解决方案)

uniApp应用软件在运行时,未见向用户告知权限申请的目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准。uniapp vue2 vue3解决软件在运行时,未见向用户告知权限申请的目的,华为等上架被拒问题,关于华为应用市场上架需要同步告知使用权限的解决方案,uniApp应用软件在运行时,不符合华为应用市场审核标准。解决方案合集!app上架-您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(相机)等权限,不符合华为应用市场审核标准。华为应用市场审核新规(未同步告知权限申请的使用目

🏆 前端领域优质创作者 4164

从单体到微服务:Spring Boot 3.x 重构实战与5个核心挑战解析

本文详细解析了从单体架构向微服务架构转型过程中使用Spring Boot 3.x的实战经验,重点探讨了5个核心挑战及其解决方案。内容包括重构前的系统评估、微服务基础架构搭建、数据一致性处理、服务间通信优化等关键环节,为开发者提供了一套完整的软件架构升级方法论。

weixin_30572613的博客 381

pymol 动画简单制作,gif、mp4导出

参考: https://www.youtube.com/watch?v=G77K9Lro8js1、直接Movie下Program下,Camera Loop下Nutate下选择,这里选择30degover4 sec;如果要动画过渡自然,可以在这4sec后面再Append 1sec;如果需要两个视角,既可以再把窗口蛋白定位到比如配体,不用管中间过程怎么定位过去配体,再Program下,Camera Loop下Nutate下选择,这里选择30degover4 sec添加;最后如果要整体形成个循环播放,可以在这4s

weixin_42357472的博客 8437

5分钟快速上手Apache Dubbo:从零搭建你的第一个RPC微服务

本文带你5分钟快速上手 **Apache Dubbo**——一款强大的 Java RPC 和微服务框架。你将借助仓库自带的 Spring Boot 示例,从零搭建一个能真正跑通的服务提供方(Provider)和消费方(Consumer),体验服务注册、发现与远程调用的完整流程,新手也能轻松掌握。 --- ## 🧩 Apache Dubbo 是什么?为什么值得学? Apache Dubbo

gitblog_00183的博客 1050

VSCode 中搭建 Python 开发环境

**验证安装**:打开终端(CMD/PowerShell/终端),输入 `python --version`(Windows)或 `python3 --version`(macOS/Linux),显示版本号即成功。- **下载地址**:[Python 官网](https://www.python.org/downloads/)(选择对应系统的最新稳定版,推荐 3.8+)- **调试**:通过 `launch.json` 配置,设置断点后按 `F5` 启动,使用 `F10/F11` 控制流程。

寒寒豆豆软件公司的博客 2536

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spring AI 集成 MCP 协议实战:Java 开发者快速构建 AI 工具调用

MCP(Model Context Protocol)是一种标准化协议,用于统一大模型与外部工具、数据源的交互方式,解决 AI 落地中接口适配混乱的问题。其核心基于 JSON-RPC 2.0 通信,支持 Tools、Resources、Prompts 三种能力抽象,并通过 stdio 或 SSE 传输。在 Java 生态中,Spring AI 提供了对 MCP 的完整支持,开发者可基于 Spring Boot 快速将业务系统暴露为 MCP Server,或让 AI 应用作为 Client 调用外部工具。典型

weixin_34079177的博客 105

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Spring Boot vs Node.js 技术选型决策指南

在现代Web开发中,Spring Boot和Node.js并非简单对立的‘二选一’,而是面向不同技术场景的基础架构选择。其本质差异源于运行模型:Spring Boot依托JVM多线程与强类型生态,天然适配复杂业务逻辑、强一致性事务及长期维护系统;Node.js基于V8事件循环与非阻塞I/O,在高并发I/O密集型场景(如实时通信、API网关、快速原型)中具备响应式优势。技术价值体现在工程确定性(Spring Boot的分层架构、事务管理、诊断能力)与交付敏捷性(Node.js的轻量启动、丰富前端协同生态)的平

weixin_34277853的博客 156

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

基于Spring Boot与向量数据库构建企业级RAG系统:架构设计与工程实践

检索增强生成(RAG)是一种将信息检索与大型语言模型生成能力相结合的技术范式。其核心原理在于,系统首先从外部知识库中检索与用户查询相关的文档片段,然后将这些片段作为上下文提供给大模型,从而生成更准确、更具事实依据的答案,有效缓解了大模型的“幻觉”问题。这项技术的核心价值在于,它能够以相对可控的成本,将通用大模型的能力与特定领域的私有知识相结合,构建出懂业务的专属智能体。在应用场景上,RAG技术广泛应用于企业智能客服、内部知识库问答、辅助决策分析等领域。本文聚焦于如何为中小企业构建一个稳定、可扩展且易于维护的

weixin_33681778的博客 434

EvoMaster 白盒测试进阶:从零编写 Driver 深度挖掘 Java/Kotlin 应用缺陷

EvoMaster 白盒测试是让 Java/Kotlin 应用缺陷无所遁形的关键路径。作为全球首个开源的 AI 驱动系统级测试用例自动生成(Fuzzing)工具,EvoMaster 支持 REST、GraphQL、gRPC、Thrift 等 API 的白盒与黑盒测试。在白盒模式下,你需要为被测系统(SUT)编写一个 Driver 控制程序,由它负责启动、重置、停止应用并加载代码插桩。本文将手把手带

gitblog_00981的博客 498

REST与GraphQL生产选型实战:数据耦合度与客户端灵活性的工程权衡

API范式选择本质是数据交付方式的设计决策。REST基于统一接口与无状态约束,通过URI资源建模和HTTP缓存实现高运维确定性;GraphQL则以强类型Schema和嵌套查询提升客户端灵活性,但将复杂度转移至服务端解析层。二者核心差异不在语法,而在对数据耦合度、团队协作模式与可观测性成本的系统性权衡。真实项目中,高频标准化交互(如登录、Webhook)适合REST,而动态聚合场景(如多源商品详情、运营报表)更适配GraphQL。本文结合电商、SaaS与IoT三类落地案例,揭示如何依据数据关系图、变更频率、压

搜索 360

Spring AI MCP协议:统一AI工具调用的标准实践

MCP(Model Calling Protocol)是一种面向AI工程化的轻量级模型调用协议,基于JSON-RPC 2.0设计,旨在解决大模型与外部工具间协议不统一、编排碎片化、能力解耦难等核心问题。其原理是通过标准化的服务发现(listTools)、结构化参数描述(JSON Schema)和语义清晰的动作调用(如getWeather),让LLM像调用HTTP API一样调度真实业务能力。技术价值在于降低胶水代码成本、提升工具可发现性与可观测性,并天然融入Spring Boot生命周期、安全体系与监控生态

weixin_29253711的博客 334
上一篇: Base62编码生成6位不重复短码的背后设计
下一篇: 那个号称对标 Spring的国产框架 Solon,到底行不行?
智_永无止境
博客等级 码龄10年 803粉丝 404原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值