【SpringCloud】(一文通)优雅实现远程调用-OpenFeign

news2024/9/20 17:29:14

目 录

  • 一. RestTemplate存在问题
  • 二. OpenFeign介绍
  • 三. 快速上手
    • 3.1 引入依赖
    • 3.2 添加注解
    • 3.3 编写 OpenFeign 的客户端
    • 3.4 远程调用
    • 3.5 测试
  • 四. OpenFeign 参数传递
    • 4.1 传递单个参数
    • 4.2 传递多个参数
    • 4.3 传递对象
    • 4.4 传递JSON
  • 五. 最佳实践
    • 5.1 Feign 继承方式
      • 5.1.1 创建⼀个Module
      • 5.1.2 引入依赖
      • 5.1.3 编写接口
      • 5.1.4 打Jar包
      • 5.1.5 服务提供方
      • 5.1.6 服务消费方
      • 5.1.7 测试
    • 5.2 Feign 抽取方式
      • 5.2.1 创建⼀个module
      • 5.2.2 引入依赖
      • 5.2.3 编写API
      • 5.2.4 打Jar包
      • 5.2.5 服务消费方使用 product-api
      • 5.2.6 测试
  • 六. 服务部署

一. RestTemplate存在问题

观察远程调用的代码

public OrderInfo selectOrderById(Integer orderId) {
	OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
	String url = "http://product-service/product/"+ orderInfo.getProductId();
	ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
	orderInfo.setProductInfo(productInfo);
	return orderInfo;
}

虽说 RestTemplate 对HTTP封装后, 已经比直接使用 HTTPClient 简单方便很多, 但是还存在⼀些问题.

  1. 需要拼接URL, 灵活性高, 但是封装臃肿, URL复杂时, 容易出错.
  2. 代码可读性差, 风格不统⼀.

微服务之间的通信方式, 通常有两种: RPC 和 HTTP.

在 SpringCloud 中, 默认是使用 HTTP 来进行微服务的通信, 最常用的实现形式有两种:

  • RestTemplate
  • OpenFeign

二. OpenFeign介绍

OpenFeign 是⼀个声明式的 Web Service 客户端. 它让微服务之间的调用变得更简单, 类似 controller 调用service, 只需要创建⼀个接口,然后添加注解即可使用 OpenFeign.

OpenFeign 的前身

Feign 是 Netflix 公司开源的⼀个组件.
• 2013年6月, Netflix 发布 Feign的第⼀个版本 1.0.0
• 2016年7月, Netflix 发布 Feign的最后⼀个版本 8.18.0
2016年,Netflix 将 Feign 捐献给社区
• 2016年7月 OpenFeign 的首个版本 9.0.0 发布,之后⼀直持续发布到现在

可以简单理解为 Netflix Feign 是OpenFeign 的祖先, 或者说 OpenFeign 是Netflix Feign 的升级版.OpenFeign 是 Feign 的⼀个更强大更灵活的实现

Spring Cloud Feign

Spring Cloud Feign 是 Spring 对 Feign 的封装, 将 Feign 项目集成到 Spring Cloud 生态系统中.

受 Feign 更名影响,Spring Cloud Feign 也有两个 starter

  • spring-cloud-starter-feign
  • spring-cloud-starter-openfeign

由于 Feign 的停更维护, 对应的, 我们使用的依赖是 spring-cloud-starter-openfeign

OpenFeign 官方文档:点击跳转
Spring Cloud Feign文档:点击跳转

三. 快速上手

3.1 引入依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

3.2 添加注解

在 order-service 的启动类添加注解 @EnableFeignClients , 开启 OpenFeign 的功能.

@EnableFeignClients
@SpringBootApplication
public class OrderServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(OrderServiceApplication.class, args);
	}
}

3.3 编写 OpenFeign 的客户端

基于 SpringMVC 的注解来声明远程调用的信息

import com.bite.order.model.ProductInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {
	@RequestMapping("/{productId}")
	ProductInfo getProductById(@PathVariable("productId") Integer productId);
}

@FeignClient 注解作用在接口上, 参数说明:

  • name/value:指定 FeignClient 的名称, 也就是微服务的名称, 用于服务发现, Feign 底层会使用
    Spring Cloud LoadBalance 进行负载均衡. 也可以使用 url 属性指定⼀个具体的 url.

  • path: 定义当前FeignClient的统⼀前缀.

3.4 远程调用

修改远程调用的方法

@Autowired
private ProductApi productApi;
/**
* Feign实现远程调⽤
* @param orderId
*/
public OrderInfo selectOrderById(Integer orderId) {
	OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
	ProductInfo productInfo = productApi.getProductById(orderInfo.getProductId());
	orderInfo.setProductInfo(productInfo);
	return orderInfo;
}

代码对比:

在这里插入图片描述

3.5 测试

启动服务, 访问接口, 测试远程调用: http://127.0.0.1:8080/order/1

在这里插入图片描述

可以看出来, 使用 Feign 也可以实现远程调用.

Feign 简化了与 HTTP 服务交互的过程, 把 REST 客户端的定义转换为Java接口, 并通过注解的方式来声明请求参数,请求方式等信息, 使远程调用更加方便和间接.

四. OpenFeign 参数传递

通过观察, 我们也可以发现, Feign 的客户端和服务提供者的接口声明非常相似
上面例子中, 演示了 Feign 从 URL 中获取参数, 接下来演示下 Feign 参数传递的其他方式

4.1 传递单个参数

服务提供方 product-service

@RequestMapping("/product")
@RestController
public class ProductController {
	@RequestMapping("/p1")
	public String p1(Integer id){
		return "p1接收到参数:"+id;
	}
}

Feign 客户端

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {
	@RequestMapping("/p1")
	String p1(@RequestParam("id") Integer id);
}

注意: @RequestParam 做参数绑定, 不能省略

服务消费方 order-service

@RequestMapping("/feign")
@RestController
public class TestFeignController {
	@Autowired
	private ProductApi productApi;
	
	@RequestMapping("/o1")
	public String o1(Integer id){
		return productApi.p1(id);
	}
}

测试远程调用:http://127.0.0.1:8080/feign/o1?id=5

在这里插入图片描述

4.2 传递多个参数

使用多个 @RequestParam 进行参数绑定即可

服务提供方 product-service

@RequestMapping("/p2")
public String p2(Integer id,String name){
	return "p2接收到参数,id:"+id +",name:"+name;
}

Feign 客户端

@RequestMapping("/p2")
String p2(@RequestParam("id")Integer id,@RequestParam("name")String name);

服务消费方 order-service

@RequestMapping("/o2")
public String o2(@RequestParam("id")Integerid,@RequestParam("name")String name){
	return productApi.p2(id,name);
}

测试远程调用:http://127.0.0.1:8080/feign/o2?id=5&name=zhangsan

在这里插入图片描述

4.3 传递对象

服务提供方 product-service

@RequestMapping("/p3")
public String p3(ProductInfo productInfo){
	return "接收到对象, productInfo:"+productInfo;
}

Feign 客户端

@RequestMapping("/p3")
String p3(@SpringQueryMap ProductInfo productInfo);

服务消费方 order-service

@RequestMapping("/o3")
public String o3(ProductInfo productInfo){
	return productApi.p3(productInfo);
}

测试远程调用:http://127.0.0.1:8080/feign/o3?id=5&productName=zhangsan

在这里插入图片描述

4.4 传递JSON

服务提供方 product-service

@RequestMapping("/p4")
public String p4(@RequestBody ProductInfo productInfo){
	return "接收到对象, productInfo:"+productInfo;
}

Feign 客户端

@RequestMapping("/p4")
String p4(@RequestBody ProductInfo productInfo);

服务消费方 order-service

@RequestMapping("/o4")
public String o4(@RequestBody ProductInfo productInfo){
	System.out.println(productInfo.toString());
	return productApi.p4(productInfo);
}

测试远程调用:http://127.0.0.1:8080/feign/o4

在这里插入图片描述

五. 最佳实践

最佳实践, 其实也就是经过历史的迭代, 在项目中的实践过程中, 总结出来的最好的使用方式.

通过观察, 我们也能看出来, Feign 的客户端与服务提供者的 controller 代码非常相似

Feign 客户端

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {
	@RequestMapping("/{productId}")
	ProductInfo getProductById(@PathVariable("productId") Integer productId);
}

服务提供方 Controller

@RequestMapping("/product")
@RestController
public class ProductController {

	@RequestMapping("/{productId}")
	public ProductInfo getProductById(@PathVariable("productId") Integer productId){
		//...
	}
}

有没有⼀种方法可以简化这种写法呢?

5.1 Feign 继承方式

Feign 支持继承的方式, 我们可以把⼀些常见的操作封装到接口里.

我们可以定义好⼀个接口, 服务提供方实现这个接口, 服务消费方编写Feign 接口的时候, 直接继承这个接口

具体参考: Spring Cloud OpenFeign Features :: Spring Cloud Openfeign

5.1.1 创建⼀个Module

接口可以放在⼀个公共的 Jar 包里, 供服务提供方和服务消费方使用

在这里插入图片描述

5.1.2 引入依赖

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
</dependencies>

5.1.3 编写接口

复制 ProductApi, ProductInfo 到 product-api 模块中

import com.bite.model.ProductInfo;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

public interface ProductInterface {
	@RequestMapping("/{productId}")
	ProductInfo getProductById(@PathVariable("productId") Integer productId);
	
	@RequestMapping("/p1")
	String p1(@RequestParam("id") Integer id);
	
	@RequestMapping("/p2")
	String p2(@RequestParam("id")Integer id,@RequestParam("name")String name);
	
	@RequestMapping("/p3")
	String p3(@SpringQueryMap ProductInfo productInfo);
	
	@RequestMapping("/p4")
	String p4(@RequestBody ProductInfo productInfo);
}

目录结构如下:

在这里插入图片描述

5.1.4 打Jar包

通过 Maven 打包

在这里插入图片描述

观察 Maven 本地仓库, Jar 包是否打成功

[INFO] Installing D:\Git\spring-cloud\spring-cloud-feign2\productapi\target\product-api-1.0-SNAPSHOT.jar to 
D:\Maven\.m2\repository\org\example\product-api\1.0-SNAPSHOT\product-api-1.0-
SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.796 s
[INFO] Finished at: 2024-01-03T19:31:35+08:00
[INFO] ------------------------------------------------------------------------

在这里插入图片描述

5.1.5 服务提供方

服务提供方实现接口 ProductInterface

@RequestMapping("/product")
@RestController
public class ProductController implements ProductInterface {
	@Autowired
	private ProductService productService;
	
	@RequestMapping("/{productId}")
	public ProductInfo getProductById(@PathVariable("productId") Integer productId){
	System.out.println("收到请求,Id:"+productId);
		return productService.selectProductById(productId);
	}
	
	@RequestMapping("/p1")
	public String p1(Integer id){
		return "p1接收到参数:"+id;
	}
	
	@RequestMapping("/p2")
	public String p2(Integer id,String name){
		return "p2接收到参数,id:"+id +",name:"+name;
	}
	@RequestMapping("/p3")
	public String p3(ProductInfo productInfo){
		return "接收到对象, productInfo:"+productInfo;
	}
	
	@RequestMapping("/p4")
	public String p4(@RequestBody ProductInfo productInfo){
		return "接收到对象, productInfo:"+productInfo;
	}

}

5.1.6 服务消费方

服务消费方继承 ProductInterface

import com.bite.api.ProductInterface;
import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi extends ProductInterface {
	//...
}

5.1.7 测试

试远程调用:http://127.0.0.1:8080/order/1

在这里插入图片描述

5.2 Feign 抽取方式

官方推荐 Feign 的使用方式为继承的方式, 但是企业开发中, 更多是把Feign接口抽取为⼀个独立的模块(做法和继承相似, 但理念不同).

操作⽅法:

将 Feign 的 Client 抽取为⼀个独立的模块, 并把涉及到的实体类等都放在这个模块中, 打成⼀个Jar. 服务消费⽅只需要依赖该Jar包即可. 这种方式在企业中比较常见, Jar 包通常由服务提供方来实现

5.2.1 创建⼀个module

在这里插入图片描述

5.2.2 引入依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

5.2.3 编写API

复制 ProductApi, ProductInfo 到 product-api 模块中

在这里插入图片描述

5.2.4 打Jar包

通过Maven打包

在这里插入图片描述

观察 Maven 本地仓库, Jar 包是否打成功

[INFO] Installing D:\Git\spring-cloud\spring-cloud-feign\productapi\target\product-api-1.0-SNAPSHOT.jar to 
D:\Maven\.m2\repository\org\example\product-api\1.0-SNAPSHOT\product-api-1.0-
SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.441 s
[INFO] Finished at: 2024-01-03T17:55:14+08:00
[INFO] ------------------------------------------------------------------------

在这里插入图片描述

5.2.5 服务消费方使用 product-api

  1. 删除 ProductApi, ProductInfo

  2. 引入依赖

<dependency>
	<groupId>org.example</groupId>
	<artifactId>product-api</artifactId>
	<version>1.0-SNAPSHOT</version>
</dependency>

修改项目中 ProductApi, ProductInfo 的路径为 product-api 中的路径

  1. 指定扫描类: ProductApi

在启动类添加扫描路径

@EnableFeignClients(basePackages = {"com.bite.api"})

完整代码如下:

@EnableFeignClients(basePackages = {"com.bite.api"})
@SpringBootApplication
public class OrderServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(OrderServiceApplication.class, args);
	}
}

也可以指定需要加载的 Feign 客户端

@EnableFeignClients(clients = {ProductApi.class})

5.2.6 测试

测试远程调用:http://127.0.0.1:8080/order/1

在这里插入图片描述

六. 服务部署

  1. 修改数据库, Nacos等相关配置

  2. 对两个服务进行打包

Maven打包默认是从远程仓库下载的, product-api 这个包在本地, 有以下解决方案:

  • 上传到 Maven 中央仓库(参考: 如何发布 Jar 包到 Maven 中央仓库, 比较麻烦)[不推荐]
  • 搭建 Maven 私服, 上传 Jar 包到私服[企业推荐]
  • 从本地读取 Jar 包[个人学习阶段推荐]

前两种方法比较复杂, 咱们使用第三种方式

修改 pom 文件

<dependency>
	<groupId>org.example</groupId>
	<artifactId>product-api</artifactId>
	<version>1.0-SNAPSHOT</version>
	<!-- scope 为system. 此时必须提供systemPath即本地依赖路径. 表⽰maven不会去中央
	仓库查找依赖 不推荐使⽤-->
	<scope>system</scope>
	<systemPath>D:/Maven/.m2/repository/org/example/product-api/1.0-
	SNAPSHOT/product-api-1.0-SNAPSHOT.jar</systemPath>
</dependency>


//....
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<includeSystemScope>true</includeSystemScope>
			</configuration>
		</plugin>
	</plugins>
</build>

把D:/Maven/.m2/repository 改为本地仓库的路径

  1. 上传 jar 到Linux服务器
  2. 启动 Nacos

启动前最好把 data 数据删除掉.

  1. 启动服务
#后台启动order-service, 并设置输出⽇志到logs/order.log
nohup java -jar order-service.jar >logs/order.log &

#后台启动product-service, 并设置输出⽇志到logs/order.log
nohup java -jar product-service.jar >logs/product-9090.log &

#启动实例, 指定端⼝号为9091
nohup java -jar product-service.jar --server.port=9091 >logs/product-9091.log &

观察 Nacos 控制台

在这里插入图片描述

  1. 测试

访问接口: http://110.41.51.65:8080/order/1

观察远程调用的结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

马克思发生器有什么用_马克思发生器工作原理

马克思发生器&#xff08;Marx Generator&#xff09;是一种电气装置&#xff0c;用于产生高压脉冲电压。它由多个电容器组成&#xff0c;这些电容器依次连接在一系列开关之后。首先&#xff0c;每个电容器被并联充电至较低的电压。然后&#xff0c;这些电容器被开关依次串联&a…

C++过生日(我给我自己做的生日礼物)

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 引言…

电源自动测试系统:测试柜的组成与功能

为了提高电源测试的效率和安全性&#xff0c;电源自动化测试柜是电源ATE自动测试系统的重要设备&#xff0c;不仅对示波器、万用表等测试仪器起保护作用&#xff0c;更是在测试过程中降低了安全风险&#xff0c;方便了电源产品的自动化测试。 电源自动测试系统机柜 电源自动化测…

C++初学(15补充)

15.1、嵌套循环和二维数组 下面讨论如何使用嵌套for循环来处理二维数组。到目前为止&#xff0c;我们一直学的是一维数组&#xff0c;因为每一个数组都可以看作是一行数据。二维数组更像是一个表格——既有数据行也有数据列。C并没有提供二维数组类型&#xff0c;但是用户可以…

电池的入门

目录 化学电池主要参数电池种类常用电池 物理电池太阳能电池 化学电池 主要参数 1.容量 2.标称电压 3.内阻 4.充电终止电压 5.放点终止电压 电池种类 按能否充电分&#xff1a; 原电池&#xff08;Primary Cell&#xff09;&#xff1a;只能放电不能充电的电池&#xff0c…

FastGPT如何增减用户

背景 开源版本的FastGPT默认只有一个超级用户root&#xff0c;为了更好地管理应用和知识库&#xff0c;可以通过操作MongoDB数据库来增加新的用户和团队。 所需环境 已安装并运行的FastGPT实例MongoDB客户端工具&#xff08;如Mongo Shell或Robo 3T等&#xff09; 操作步骤…

一文带你了解React Hooks

目录 一、useState 二、useRef 三、useEffect 四、自定义Hook 五、Hooks使用规则 Hooks原意是“挂钩”&#xff0c;指将类组件中的部分功能直接可以挂钩到函数组件中&#xff0c;例如state、生命周期方法、副作用等功能。 为什么使用Hooks&#xff1f; 封装代码&#xff…

Harmony鸿蒙应用开发:解决Web组件加载本地资源跨域

鸿蒙开发文档中有一节 加载本地页面 提到了可以通过 $rawfile 方法加载本地 HTML 网页&#xff1a; Index.ets 1Web({ src: $rawfile("local.html"), controller: this.webviewController })但是如果在 local.html 中需要引用一些静态资源&#xff0c;例如图片、JS、…

STM32——TIM定时器的输入捕获功能

一、什么是输出比较与输入捕获&#xff1f; 可以看到&#xff1a; 输出比较OC是用于输出一定频率和占空比的PWM波形&#xff0c;可用于电机驱动进行调速等&#xff1b;而输入捕获IC是用于测量PWM波形的频率以及占空比等参数&#xff1b;和他们的名字相反&#xff0c;一个是比…

Datawhale AI夏令营第四期魔搭- AIGC文生图方向 task01笔记

目录 分任务1&#xff1a;跑通baseline 第一步——搭建代码环境 第二步——报名赛事 第三步——在魔搭社区创建PAI实例 分任务2&#xff1a;相关知识学习以及赛题理解 赛题理解&#xff1a; 文生图基本认识&#xff1a; 1. Diffusion Model(扩散模型) 2. LDMs&#x…

嵌入式Linux学习笔记

1.文件操作命令 2.VI编辑器的部分命令 3.Uboot命令设置环境变量 4. uboot 的顶层 Makefile的重点是“make xxx_defconfig”和“make”这两个命令 &#xff0c;分别如下&#xff1a; 5.在串口SecureCRT中利用uboot启动Linux内核的两种方式 6.Linux内核移植到开发板上也可以反…

常见错误导引 不锈钢螺钉的正确选购和使用分析

紧固件或螺钉是用于固定物体的机械工具。它们用于各种场景&#xff0c;从建造房屋、用具、玩具等。紧固件由多种材料制成&#xff0c;所有这些材料都有特定用途紧固件和用途。一些用于制造螺丝的材料包括不锈钢、铁、铜、铝和塑料。它通常会进行某种表面处理以提高其防锈性和/或…

day-40 合并区间

思路 将二维数组按照第一列升序排列&#xff0c;把intervals[0][0]作为第一个区间的起点&#xff0c;将 intervals[0][1]和intervals[1][0]进行比较&#xff0c;如果intervals[0][1]<intervals[1][0]&#xff0c;则不能合并&#xff0c;否则可以合并&#xff0c;将Math.max(…

绝对不能错过的60个Python日常高频写法总结!

一、 数字 1 求绝对值 绝对值或复数的模 In [1]: abs(-6)Out[1]: 62 进制转化 十进制转换为二进制&#xff1a; In [2]: bin(10)Out[2]: 0b1010十进制转换为八进制&#xff1a; In [3]: oct(9)Out[3]: 0o11十进制转换为十六进制&#xff1a; In [4]: hex(15)Out[4]: 0xf…

[ICS] 物理安全

工业控制系统安全气泡类比 这个理念是&#xff0c;为了防御那些无法更新到最新安全控制措施的旧系统&#xff0c;或者由于设备资源有限而无法处理安全控制措施的系统&#xff0c;帮助可视化这种设备的安全策略可以将它们放置在一个肥皂泡或玻璃泡中。泡中的系统和设备彼此信任…

Spring Cloud Stream与Kafka(一)

Spring Cloud Stream与Kafka&#xff08;一&#xff09; ​ 在实际开发过程中&#xff0c;消息中间件用于解决应用解耦&#xff0c;异步消息&#xff0c;流量削峰等问题&#xff0c;实现高可用、高性能、可伸缩和最终一致性架构。不同的消息中间件实现方式不同&#xff0c;内部…

遥感反演保姆级教程:SPSS筛选因子之后如何采用python建模和反演整个研究区?(以反演生物量为例)

SPSS筛选因子之后如何采用python建模和反演整个研究区?&#xff08;以反演生物量为例&#xff09; 引言 在遥感数据分析中&#xff0c;因子筛选和建模是关键步骤。筛选出与目标变量&#xff08;如生物量&#xff09;显著相关的因子&#xff0c;不仅可以提高模型的预测精度&a…

编程世界的平衡术:日常编码与自我提升的和谐共生

前言 在快速迭代的编程世界中&#xff0c;程序员的角色日益复杂且充满挑战&#xff0c;他们不仅是代码的编织者&#xff0c;更是技术进步的推动者。面对日常编码工作的繁重与个人成长的迫切需求&#xff0c;寻找两者之间的平衡点成为了每位程序员必须深思的问题。以下是我的详细…

C++初学者指南-5.标准库(第二部分)–特殊容器

C初学者指南-5.标准库(第二部分)–特殊容器 pair<A , B> 包含两个相同或不同类型的值 tuple<A , B> C11 包含许多相同或不同类型的值 optional C17 包含一个类型为 T 的值或没有值 variant<A,B,C,…> C17 包含一个类型为A、B或C的值…… any C17 包含任…

《花100块做个摸鱼小网站! 》第四篇—前端应用搭建和完成第一个热搜组件

⭐️基础链接导航⭐️ 服务器 → ☁️ 阿里云活动地址 看样例 → &#x1f41f; 摸鱼小网站地址 学代码 → &#x1f4bb; 源码库地址 一、前言 在本系列文章的早期章节中&#xff0c;我们已经成功地购买了服务器并配置了MySQL、Redis等核心中间件。紧接着&#xff0c;我们不仅…