SpringCloud原理-OpenFeign篇(一、Hello OpenFeign项目示例)

文章目录

  • 前言
  • 正文
    • 一、项目结构
    • 二、服务调用链路说明
    • 三、Rpc调用链路说明
    • 四、项目代码
      • 4.1 client 模块中的feign接口
      • 4.2 client 中的rest接口
      • 4.3 client 中的启动类
      • 4.4 server中的rest接口
      • 4.5 server中的配置文件
    • 五、调试
  • 附录
    • 附1:本系列文章链接

前言

本篇是SpringCloud原理系列的 OpenFeign 模块的第一篇。主要内容是搭建一个极简的Spring Cloud OpenFeign 调用链路。

项目代码仓库地址:https://gitee.com/fengsoshuai/springcloud-openfeign-demo

正文

本次项目使用java 17,spring cloud 4.0.4,springboot 3.1.4。
maven 环境编译,idea开发。

一、项目结构

本次项目分为3个模块。
在这里插入图片描述
在这里插入图片描述

二、服务调用链路说明

在这里插入图片描述

  1. 使用IDEA/Postman/Apifox等工具进行触发client服务的接口
  2. client内部通过feign调用server接口
  3. server执行业务逻辑
  4. server返回执行结果到client
  5. client返回调用结果到触发方

三、Rpc调用链路说明

两个服务之间,使用远程调用。
基本都是需要URL,请求头,请求报文,请求方式(Get\Post 等)等基本信息的。
下图简单说明rpc调用时的链路。
在这里插入图片描述
其中,调用方,相当于发起远程调用的一方,对比本项目的话,相当于使用postman等工具触发后,client模块的操作。

只是特殊的一点在于,调用方中的红色虚线框内的部分,被openFeign 封装了,不再是我们手动去处理他们。而这也正是本系列研究的重点。

中间部分,就是形如 RestTemplate,WebClient的功能,只是发出请求,接受响应。

服务方,就是一个提供rest接口的普通应用。

四、项目代码

本文全部代码托管在gitte仓库中,地址已经在文章开头给出。
这里只粘贴出比较重要的几个文件。

4.1 client 模块中的feign接口

package org.feng.feigns;import org.feng.common.dto.HelloRequest;
import org.feng.common.dto.HelloResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;/*** hello-feign客户端接口** @version v1.0* @author: fengjinsong* @date: 2023年11月20日 21时25分*/
@FeignClient(name = "helloFeignClient", url = "http://localhost:10080")
public interface HelloFeignClient {@PostMapping("/hello/post")HelloResponse postHello(@RequestBody HelloRequest helloRequest);
}

4.2 client 中的rest接口

package org.feng.controller;import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.feng.common.dto.HelloRequest;
import org.feng.common.dto.HelloResponse;
import org.feng.feigns.HelloFeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import java.time.LocalDateTime;
import java.util.Objects;/*** HelloFeignClientController** @version v1.0* @author: fengjinsong* @date: 2023年11月20日 21时45分*/
@Slf4j
@RestController
@RequestMapping("/helloclient")
public class HelloFeignClientController {@Resourceprivate HelloFeignClient helloFeignClient;@PostMapping("/postHello")public HelloResponse postHello(@RequestBody HelloRequest helloRequest) {if(Objects.isNull(helloRequest.getLocalDateTime())){helloRequest.setLocalDateTime(LocalDateTime.now());}ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = requestAttributes.getRequest();String localAddr = request.getLocalAddr();int serverPort = request.getServerPort();helloRequest.setHost(localAddr);helloRequest.setPort(serverPort);log.info("helloRequest  {}", helloRequest);return helloFeignClient.postHello(helloRequest);}
}

4.3 client 中的启动类

指定扫描包为 org.feng.feigns

package org.feng;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableFeignClients(basePackages = "org.feng.feigns")
@SpringBootApplication
public class ClientApplication {public static void main(String[] args) {SpringApplication.run(ClientApplication.class, args);}}

4.4 server中的rest接口

package org.feng.controller;import lombok.extern.slf4j.Slf4j;
import org.feng.common.dto.HelloRequest;
import org.feng.common.dto.HelloResponse;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** openfeign 控制器** @author feng*/
@Slf4j
@RequestMapping("/hello")
@RestController
public class HelloOpenFeignController {@PostMapping("/post")public HelloResponse postHello(@RequestBody HelloRequest helloRequest) {log.info("request:{}", helloRequest);HelloResponse response = new HelloResponse();response.setTitle(helloRequest.getTitle());response.setLocalDateTime(helloRequest.getLocalDateTime());response.setFromHost(helloRequest.getHost());response.setFromPort(helloRequest.getPort());log.info("response: {}", response);return response;}
}

4.5 server中的配置文件

spring.application.name=openserver
server.port=10080

五、调试

启动server 和 client 服务。
在idea中触发client 的服务:

POST http://localhost:8080/helloclient/postHello
Content-Type: application/json{"title": "托尔斯泰"
}

响应报文如下:

{"fromHost": "127.0.0.1","fromPort": 8080,"title": "托尔斯泰","localDateTime": "2023-11-21T14:07:18.537384"
}

server中的服务,打印出来的日志如下:
在这里插入图片描述
以上就是通过onepfeign 进行rpc 调用的完整示例了。

可以看到,我们只在client中定义了接口,并没有实现。但是在调用时,没有报错,同时也调用到了server服务。而这,就是spring cloud 中的 openfeign 封装了远程调用,帮我们处理的部分,也是我们后续研究其原理的核心部分。

附录

附1:本系列文章链接

SpringCloud原理-OpenFeign篇(一、Hello OpenFeign项目示例)
SpringCloud原理-OpenFeign篇(二、OpenFeign包扫描和FeignClient的注册原理)
SpringCloud原理-OpenFeign篇(三、FeignClient的动态代理原理)

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

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

相关文章

示波器探头讲解及案例分享

示波器探头讲解 示波器探头 分为X1、X10档: X1档,表示被测量的信号没有经过衰减进入示波器 X10档,表示被测量的信号衰减10倍进入示波器(当示波器也设置为10X档,直接读数即可,但是当示波器设置为1X档&…

vue 目录树的展开与关闭

目录 1、翻页方法中控制目录树节点的展开与关闭2、搜索目录树节点名称控制节点的展开与关闭 <el-tree:data"data_option"ref"tree":props"defaultProps"node-click"handleNodeClick":default-expanded-keys"needExpandedKeys&…

1、开发工具介绍及软件安装

软件安装 百度网盘链接&#xff1a;https://pan.baidu.com/s/1J7sgXntt9eLNBhI1Dc6MsQ?pwd2023 提取码&#xff1a;2023 # 一 Keil5安装步骤&#xff1a; 激活&#xff1a; STC-ISP安装步骤&#xff1a; STC-ISP.exe安装即用 安装CH340_CH341驱动程序 所有学习课程和资源…

【vue】ant-design-vue的树结构实现节点增删改查

根据业务需要&#xff0c;实现树结构的节点新增编辑删除功能&#xff0c;主要逻辑是利用树节点的scopedSlots属性对其进行自定义改造&#xff0c;监听悬停事件在节点右侧出现增删改对应图标&#xff0c;点击图标出现弹窗表单对内容进行修改&#xff0c;具体代码如下&#xff1a…

蓝桥杯每日一题2023.11.23

题目描述 题目分析 本题使用递归模拟即可&#xff0c;将每一个大格子都可以拆分看成几个小格子&#xff0c;先将最开始的数字进行填入&#xff0c;使每一个对应小格子的值都为大格子对应的数&#xff0c;搜索找到符合要求的即可 &#xff08;答案&#xff1a;50 33 30 41&am…

Vue3+ts学习笔记2

<script setup lang"ts"> import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from vueonBeforeMount(()>{console.log(---挂载之前---) })onMounted(()>{console.log(---挂载---) })onBeforeUpdate(()>{consol…

Python爬取京东商品销售数据进行数据分析示例代码,以口红为例

文章目录 一、准备工作驱动安装模块使用与介绍 二、流程解析三、完整代码四、效果展示关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资…

git代码提交命令(如何提交代码)

# 提交暂存区到仓库区 $ git commit -m [message]# 提交暂存区的指定文件到仓库区 $ git commit [file1] [file2] ... -m [message]# 提交工作区自上次commit之后的变化&#xff0c;直接到仓库区 $ git commit -a# 提交时显示所有diff信息 $ git commit -v# 使用一次新的commit…

2023年中国钒铁产量及行业进出口现状分析[图]

钒铁&#xff0c;银白色块状&#xff0c;一般分为桶装或吨袋包装&#xff0c;根据钒含量的不同分为50钒铁&#xff08;FeV50&#xff09;和80钒铁&#xff08;FeV80&#xff09;,通过炉外法或电炉法冶炼生产&#xff0c;北方多以炉外法制取&#xff0c;南方多为电炉法生产。 钒…

Chrome浏览器将从2024年6月开始限制广告拦截器

虽然一年前&#xff0c;谷歌公司已经暂停推出新的“Manifest V3”扩插件展格式&#xff0c;原因是这种新格式会对 Chrome 中一些最受欢迎的扩展插件造成严重损害&#xff1b;一年后今天&#xff0c;Google 正在重新启动该计划&#xff0c;逐步淘汰 Chrome 扩展程序当前的 Manif…

Faster R-CNN源码解析(一)

目录 前言训练脚本(train_mobilenetv2.py)自定义数据集(my_dataset.py) 前言 Faster R-CNN 是经典的two-stage目标检测模型&#xff0c; 原理上并不是很复杂&#xff0c;也就是RPNFast R-CNN&#xff0c;但是在代码的实现上确实有很多细节&#xff0c;并且源码也非常的多&…

chatglm3部署使用

chatglm3部署使用 1.部署2.使用3.接入微信4.vue前端 1.部署 1.首先去github下载chatglm3代码。Huggingface下载模型一直失败&#xff0c;所以用阿里的魔塔社区下载。 git clone https://github.com/THUDM/ChatGLM3.git git clone https://www.modelscope.cn/ZhipuAI/chatglm3…

docker常见问题汇总

docker常见问题 ❓问题1&#xff1a;启动docker容器时&#xff0c;报错Unknown runtime specified nvidia. 当我启动一个容器时&#xff0c;运行以下命令&#xff1a; docker run --runtimenvidia 。。。。 后面一部分命令没写出来&#xff0c;此时报错的信息如下&#xff1a;…

python-opencv划痕检测

python-opencv划痕检测 这次实验&#xff0c;我们将对如下图片进行划痕检测&#xff0c;其实这个比较有难度&#xff0c;因为清晰度太差了。 我们做法如下&#xff1a; &#xff08;1&#xff09;读取图像为灰度图像&#xff0c;进行自适应直方图均衡化处理&#xff0c;增强图…

thingsboard3.6的mailConfigTemplateController错误

1、bug内容 使用3.6版本的tb代码进行打包生成boot的jar包,在启动的时候会报错mailConfigTemplateController bean初始化找不到文件路径。 Error creating bean with name mailConfigTemplateController defined in URL [jar:file:/D:/yuxinwei/AE/thingsboard/thingsboard-3…

nuxt3项目修改端口号

nuxt的默认端口号是3000 一、修改开发环境端口号 方式一&#xff1a;使用环境变量配置,设置&#xff08;PORT 或 NUXT_PORT&#xff09; # .env PORT3001 #http://localhost:3001/ NITRO_PORT3001 #http://localhost:3001/ 方式二&#xff1a;nuxt.config.ts里配置…

vue2.0+elementui集成file-loader之后图标失效问题

背景 跑vue2elementUI项目时&#xff0c;由于前端这边需要在本地存放xlsx模板文件&#xff0c;供用户下载模板文件&#xff0c;所以需要在webpack构建的时候增加file-loader进行解析xlsx文件打包。 vue版本2.x element-ui 版本 2.13.x 注意 npm i -D file-loader版本号给vue项…

操作系统 day12(调度算法的评价指标)

评价指标 CPU利用率 系统吞吐量 周转时间 带权周转时间 等待时间 响应时间

vue中属性的基本用法

v-for指令的用法 v-for指令用于重复输出当前元素。 案例&#xff1a;写一个新的组件页面&#xff1a;For.vue 当访问&#xff1a; /for时看到它。 场景1 遍历字符串数组输出每一个列表项元素&#xff1a; data: {nav: [京东超市,京东家电,秒杀,拍卖,京东生鲜,PLUS会员] } …

【python学习】中级篇-TCP编程Socket模块:客户端与服务端

客户端 创建一个基于TCP连接的Socket AF_INET指定使用IPv4协议 AF_INET6指定使用IPv6协议 # 导入socket库: import socket# 创建一个socket: s socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立连接: s.connect((www.sina.com.cn, 80))客户端要主动发起TCP连接 必…