当前位置: 首页 > news >正文

OpenFeign详解

OpenFeign是什么?

OpenFeign:

OpenFeign是Spring Cloud 在Feign的基础上支持了SpringMVC的注解,如@RequesMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

Feign:

Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。

Feign是在2019就已经不再更新了,通过maven网站就可以看出来,随之取代的是OpenFeign,从名字上就可以知道,他是Feign的升级版。

@FeignClient

使用OpenFeign就一定会用到这个注解,@FeignClient属性如下:

  • name:指定该类的容器名称,类似于@Service(容器名称)
  • url: url一般用于调试,可以手动指定@FeignClient调用的地址
  • decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  • path: 定义当前FeignClient的统一前缀,当我们项目中配置了server.context-path,server.servlet-path时使用

远程调用接口当中,一般我们称提供接口的服务为提供者,而调用接口的服务为消费者。而OpenFeign一定是用在消费者上。

OpenFeign使用

OpenFeign 常规远程调用

所谓常规远程调用,指的是对接第三方接口,和第三方并不是微服务模块关系,所以肯定不可能通过注册中心来调用服务。
第一步:导入OpenFeign的依赖

第二步:启动类需要添加@EnableFeignClients

第三步:提供者的接口

@RestController
@RequestMapping("/test")
public class FeignTestController {@GetMapping("/selectPaymentList")public CommonResult<Payment> selectPaymentList(@RequestParam int pageIndex, @RequestParam int pageSize) {System.out.println(pageIndex);System.out.println(pageSize);Payment payment = new Payment();payment.setSerial("222222222");return new CommonResult(200, "查询成功, 服务端口:" + payment);}@GetMapping(value = "/selectPaymentListByQuery")public CommonResult<Payment> selectPaymentListByQuery(Payment payment) {System.out.println(payment);return new CommonResult(200, "查询成功, 服务端口:" + null);}@PostMapping(value = "/create", consumes = "application/json")public CommonResult<Payment> create(@RequestBody Payment payment) {System.out.println(payment);return new CommonResult(200, "查询成功, 服务端口:" + null);}@GetMapping("/getPaymentById/{id}")public CommonResult<Payment> getPaymentById(@PathVariable("id") String id) {System.out.println(id);return new CommonResult(200, "查询成功, 服务端口:" + null);}
}

第四步:消费者调用提供者接口

@FeignClient(name = "feignTestService", url = "http://localhost/8001")
public interface FeignTestService {@GetMapping(value = "/payment/selectPaymentList")CommonResult<Payment> selectPaymentList(@RequestParam int pageIndex, @RequestParam int pageSize);@GetMapping(value = "/payment/selectPaymentListByQuery")CommonResult<Payment> selectPaymentListByQuery(@SpringQueryMap Payment payment);@PostMapping(value = "/payment/create", consumes = "application/json")CommonResult<Payment> create(@RequestBody Payment payment);@GetMapping("/payment/getPaymentById/{id}")CommonResult<Payment> getPaymentById(@PathVariable("id") String id);
}

@SpringQueryMap注解

spring cloud项目使用feign的时候都会发现一个问题,就是get方式无法解析对象参数。其实feign是支持对象传递的,但是得是Map形式,而且不能为空,与spring在机制上不兼容,因此无法使用。spring cloud在2.1.x版本中提供了@SpringQueryMap注解,可以传递对象参数,框架自动解析。

OpenFeign 微服务使用步骤

微服务之间使用OpenFeign,肯定是要通过注册中心来访问服务的。提供者将自己的ip+端口号注册到注册中心,然后对外提供一个服务名称,消费者根据服务名称去注册中心当中寻找ip和端口。

第一步:导入OpenFeign的依赖

第二步:启动类需要添加@EnableFeignClients

第三步:作为消费者,想要调用提供者需要掌握以下

CLOUD-PAYMENT-SERVICE是提供者的服务名称。消费者要想通过服务名称来调用提供者,那么就一定需要配置注册中心当中的服务发现功能。假如提供者使用的是Eureka,那么消费者就需要配置Eureka的服务发现,假如是consul就需要配置consul的服务发现。

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {@GetMapping(value = "/payment/get/{id}")CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}

第四步:提供者的接口,提供者可以是集群

@RestController
@Slf4j
public class PaymentController {@Autowiredprivate PaymentMapper paymentMapper;@Value("${server.port}")private String serverPort;@GetMapping(value = "/payment/get/{id}")public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {Payment payment = paymentMapper.selectById(id);log.info("*****查询结果:{}", payment);if (payment != null) {return new CommonResult(200, "查询成功, 服务端口:" + serverPort, payment);} else {return new CommonResult(444, "没有对应记录,查询ID: " + id + ",服务端口:" + serverPort, null);}}
}

第五步:然后我们启动注册中心以及两个提供者服务,启动后浏览器我们进行访问

使用OpenFeign,假如是根据服务名称调用,OpenFeign他本身就集成了ribbon自带负载均衡。

OpenFeign 超时控制

第一步:提供方接口,制造超时场景

@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeOut() {System.out.println("*****paymentFeignTimeOut from port: " + serverPort);//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return serverPort;
}

第二步:消费方接口调用

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService{@GetMapping(value = "/payment/feign/timeout")String paymentFeignTimeOut();
}

当消费方调用提供方时候,OpenFeign默认等待1秒钟,超过后报错
在这里插入图片描述
第三步:在消费者添加如下配置

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间ReadTimeout: 5000#指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeout: 5000

在openFeign高版本当中,我们可以在默认客户端和命名客户端上配置超时。OpenFeign 使用两个超时参数:

  • connectTimeout:防止由于服务器处理时间长而阻塞调用者。
  • readTimeout:从连接建立时开始应用,在返回响应时间过长时触发。

OpenFeign 日志打印

Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节。
说白了就是对Feign接口的调用情况进行监控和输出

日志级别:

  • NONE:默认的,不显示任何日志;
  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
  • FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

配置日志Bean:

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FeignConfig {@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}

YML文件里需要开启日志的Feign客户端

logging:level:# feign日志以什么级别监控哪个接口com.gzl.cn.service.PaymentFeignService: debug

OpenFeign 添加Header

以下提供了四种方式:

在@RequestMapping中添加

@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test(@RequestParam("names") String[] names);
}

在方法参数前面添加@RequestHeader注解

@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test(@RequestParam("names")@RequestHeader("Authorization") String[] names);
}

设置多个属性时,可以使用Map

@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test(@RequestParam("names") String[] names, @RequestHeader MultiValueMap<String, String> headers);
}

使用@Header注解

@FeignClient(name="custorm",fallback=Hysitx.class)
public interface IRemoteCallService {@RequestMapping(value="/custorm/getTest",method = RequestMethod.POST)@Headers({"Content-Type: application/json;charset=UTF-8"})List<String> test(@RequestParam("names") String[] names);
}

实现RequestInterceptor接口(拦截器)

@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate temp) {temp.header(HttpHeaders.AUTHORIZATION, "XXXXX");}
}

手动创建 Feign 客户端

@FeignClient无法支持同一service具有多种不同配置的FeignClient,因此,在必要时需要手动build FeignClient。

@FeignClient(value = “CLOUD-PAYMENT-SERVICE”)
以这个为例,假如出现两个服务名称为CLOUD-PAYMENT-SERVICE的FeignClient,项目直接会启动报错,但是有时候我们服务之间调用的地方较多,不可能将所有调用都放到一个FeignClient下,这时候就需要自定义来解决这个问题!

官网当中也明确提供了自定义FeignClient,以下是在官网基础上对自定义FeignClient的一个简单封装,供参考!

首先创建FeignClientConfigurer类,这个类相当于build FeignClient的工具类

import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;@Import(FeignClientsConfiguration.class)
public class FeignClientConfigurer {private Decoder decoder;private Encoder encoder;private Client client;private Contract contract;public FeignClientConfigurer(Decoder decoder, Encoder encoder, Client client, Contract contract) {this.decoder = decoder;this.encoder = encoder;this.client = client;this.contract = contract;}public RequestInterceptor getUserFeignClientInterceptor() {return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate requestTemplate) {// 添加header}};}public <T> T buildAuthorizedUserFeignClient(Class<T> clazz, String serviceName) {return getBasicBuilder().requestInterceptor(getUserFeignClientInterceptor())//默认是Logger.NoOpLogger.logger(new Slf4jLogger(clazz))//默认是Logger.Level.NONE(一旦手动创建FeignClient,全局配置的logger就不管用了,需要在这指定).logLevel(Logger.Level.FULL).target(clazz, buildServiceUrl(serviceName));}private String buildServiceUrl(String serviceName) {return "http://" + serviceName;}protected Feign.Builder getBasicBuilder() {return Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract);}
}

使用工具类的方法创建多个FeignClient配置

import com.gzl.cn.service.FeignTest1Service;
import feign.Client;
import feign.Contract;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FeignClientConfiguration extends FeignClientConfigurer {public FeignClientConfiguration(Decoder decoder, Encoder encoder, Client client, Contract contract) {super(decoder, encoder, client, contract);}@Beanpublic FeignTest1Service feignTest1Service() {return super.buildAuthorizedUserFeignClient(FeignTest1Service.class, "CLOUD-PAYMENT-SERVICE");}// 假如多个FeignClient在这里定义即可
}

其中,super.buildAuthorizedUserFeignClient()方法中,第一个参数为调用别的服务的接口类,第二个参数为被调用服务在注册中心的service-id。

public interface FeignTest1Service {@GetMapping(value = "/payment/get/{id}")CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}

使用的时候正常注入使用即可

@Resource
private FeignTest1Service feignTest1Service;

Feign 继承支持

Feign 通过单继承接口支持样板 API。这允许将常用操作分组到方便的基本接口中。

UserService.java

public interface UserService {@RequestMapping(method = RequestMethod.GET, value ="/users/{id}")User getUser(@PathVariable("id") long id);
}

UserResource.java

@RestController
public class UserResource implements UserService {
}

UserClient.java

package project.user;@FeignClient("users")
public interface UserClient extends UserService {}

Feign 和Cache集成

如果@EnableCaching使用注解,CachingCapability则创建并注册一个 bean,以便您的 Feign 客户端识别@Cache*其接口上的注解:

public interface DemoClient {@GetMapping("/demo/{filterParam}")@Cacheable(cacheNames = "demo-cache", key = "#keyParam")String demoEndpoint(String keyParam, @PathVariable String filterParam);
}

您还可以通过 property 禁用该功能feign.cache.enabled=false

注意feign.cache.enabled=false只有在高版本才有

OAuth2 支持

可以通过设置以下标志来启用 OAuth2 支持:

feign.oauth2.enabled=true

当标志设置为 true 并且存在 oauth2 客户端上下文资源详细信息时,将OAuth2FeignRequestInterceptor创建一个类 bean。在每个请求之前,拦截器解析所需的访问令牌并将其作为标头包含在内。有时,当为 Feign 客户端启用负载平衡时,您可能也希望使用负载平衡来获取访问令牌。为此,您应该确保负载均衡器位于类路径 (spring-cloud-starter-loadbalancer) 上,并通过设置以下标志显式启用 OAuth2FeignRequestInterceptor 的负载均衡:

feign.oauth2.load-balanced=true

注意feign.cache.enabled=false只有在高版本才有

相关文章:

OpenFeign详解

OpenFeign是什么&#xff1f; OpenFeign&#xff1a; OpenFeign是Spring Cloud 在Feign的基础上支持了SpringMVC的注解&#xff0c;如RequesMapping等等。OpenFeign的FeignClient可以解析SpringMVC的RequestMapping注解下的接口&#xff0c;并通过动态代理的方式产生实现类&am…...

python多线程网络编程

背景 使用过flask框架后&#xff0c;我对request这个全局实例非常感兴趣。它在客户端发起请求后会保存着所有的客户端数据&#xff0c;例如用户上传的表单或者文件等。那么在很多客户端发起请求时&#xff0c;服务器是怎么去区分不同的request对象呢&#xff1f;当查看了大量的…...

BFS-走迷宫

题目描述 给定一个 NM 的网格迷宫 G。G 的每个格子要么是道路,要么是障碍物(道路用 1 表示,障碍物用 0 表示)。 已知迷宫的入口位置为 (x1,y1),出口位置为 (x2...

【蓝牙mesh】Lower协议层介绍

【蓝牙mesh】Lower协议层介绍 Lower层简介 Lower协议层用于处理网络层以下的功能&#xff0c;包括节点的广播、重传、路由和网络拓扑等&#xff0c;是实现蓝牙mesh网络的关键协议之一。其中Lower协议层中最主要的一部分工作就是mesh数据的分片和组包。 Lower层是将Upper层发过…...

Java-重排序,happens-before 和 as-if-serial 语义

目录1. 如何解决重排序带来的问题2. happens-before1. 如何解决重排序带来的问题 对于编译器&#xff0c;JMM 的编译器重排序规则会禁止特定类型的编译器重排序。对于处理器重排序&#xff0c;JMM 的处理器重排序规则会要求编译器在生成指令序列时&#xff0c;插入特定类型的内…...

Nginx安装及介绍

前言&#xff1a;传统结构上(如下图所示)我们只会部署一台服务器用来跑服务&#xff0c;在并发量小&#xff0c;用户访问少的情况下基本够用但随着用户访问的越来越多&#xff0c;并发量慢慢增多了&#xff0c;这时候一台服务器已经不能满足我们了&#xff0c;需要我们增加服务…...

【华为OD机试模拟题】用 C++ 实现 - 寻找路径 or 数组二叉树(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明寻找路径 or 数组二叉树题目输入输出描述示例一输入输出示例二输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过…...

LINUX学习记录

回顾系列&#xff1a;两天的时间&#xff08;2023.2.24-2023.2.25&#xff09;重新学了遍Linux基础课&#xff0c;收获非常多&#xff0c;以前只会一些简单的Linux命令&#xff0c;对shell&#xff0c;git&#xff0c;管道&#xff0c;复杂Linux命令都不熟悉&#xff0c;学完之…...

华为OD机试用Python实现 -【狼羊过河 or 羊、狼、农夫过河】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲狼羊过河 or 羊、狼、农夫过河题目描述输入描述输出描述说明示例一输入输出说明Python 代码实现代码实现思路华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址…...

【SAP Abap】X-DOC:SAP ABAP 语法更新之Open SQL

SAP ABAP 语法更新之Open SQL1、前言2、演示1、前言 自从 SAP 推出 SAP ON HANA&#xff0c;与之相随的 AS ABAP NW 7.40 版本以后&#xff0c;ABAP 语法也有了较多的更新&#xff0c;本篇对 Open Sql的语法更新部分做一个DEMO演示。 NW 7.40 以前 OpenSQL 的限制&#xff1a…...

leetcode 困难 —— 数组中的逆序对(分治法)

题目&#xff1a; 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组&#xff0c;求出这个数组中的逆序对的总数。 题解&#xff1a; ① 我最开始想的蠢方法&#xff08;会超时&#xff0c;可跳过&#xff…...

02.24:图片的风格转换

Github网址&#xff1a;https://github.com/lengstrom/fast-style-transfer 在anaconda prompt中切换环境命令&#xff1a;activate 环境名 列出所有环境名&#xff1a;conda info --envs 安装环境&#xff1a;conda create -n 环境名 pythonx.x.x 删除某环境&#xff1a;co…...

[SSD综述 1.3] SSD及固态存储技术半个世纪发展史

在我们今天看来&#xff0c;SSD已不再是个新鲜事物。这多亏了存储行业的前辈们却摸爬滚打了将近半个世纪&#xff0c;才有了SSD的繁荣&#xff0c; 可惜很多前辈都没有机会看到。所有重大的技术革新都是这样&#xff0c;需要长期的技术积累&#xff0c;一代一代的工程师们默默的…...

PAT 1023 组个最小数(分数20)题目有bug

目录 题目描述&#xff1a; 题目讲解&#xff1a; 框架构建&#xff1a; 代码部分&#xff1a; 一个bug&#xff1a; 题目描述&#xff1a; 给定数字 0-9 各若干个。你可以以任意顺序排列这些数字&#xff0c;但必须全部使用。目标是使得最后得到的数尽可能小&#xff08;…...

QML 中的 5 大布局

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在 QML 中,可以通过多种方式对元素进行布局 - 手动定位、坐标绑定定位、锚定位(anchors)、定位器和布局管理器。 说到 anchors,可能很多人都不太了解,它是 QML 中一个非常重要的概念,主要提供了一种相…...

使用Python进行数据分析——线性回归分析

大家好&#xff0c;线性回归是确定两种或两种以上变量之间互相依赖的定量关系的一种统计分析方法。根据自变量的个数&#xff0c;可以将线性回归分为一元线性回归和多元线性回归分析。一元线性回归&#xff1a;就是只包含一个自变量&#xff0c;且该自变量与因变量之间的关系是…...

我眼中的柔宇科技

关注、星标公众号&#xff0c;直达精彩内容来源&#xff1a;技术让梦想更伟大作者&#xff1a;李肖遥很早就知道了柔宇科技&#xff0c;当时是因为知道创始人刘自鸿&#xff0c;23岁清华本硕毕业&#xff0c;26岁获斯坦福大学电子工程博士学位&#xff0c;历时不超过3年&#x…...

Allegro如何快速把视图居中显示操作指导

Allegro如何快速把视图居中显示操作指导 用Allegro进行PCB设计的时候,为了方便检查和设计,时常需要将视图居中显示。一般地,会使用鼠标的中键进行放大和缩小,或者使用Zoom in和Zoom out来调整视图 Allegro还支持快速将视图居中 具体操作如下 点击View...

搜索相关功能

一、进入搜索页面 1.1 在pages下创建搜索页面为&#xff1a;search 1.2 在index.vue中点击进入搜素页面 onNavigationBarButtonTap(e){if(e.floatleft){uni.navigateTo({url:/pages/search/search})}},1.3 在pages.json中配置搜索页面头部 {"path" : "pages/…...

【从零开始制作 bt 下载器】一、了解 torrent 文件

【从零开始制作 bt 下载器】一、了解 torrent 文件写作背景了解 torrent 文件认识 bencodepython 解析 torrent 文件解密 torrent 文件结尾写作背景 最先开始是朋友向我诉说使用某雷下载结果显示因为版权无法下载&#xff0c;找其他的下载器有次数限制&#xff0c;于是来询问我…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...