公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。

前言

在前几个教程中我们已经看到:

使用 RestTemplate 的 Spring Boot 微服务通信示例

使用 WebClient 的 Spring Boot 微服务通信示例

在本教程中,我们将学习如何使用 Spring Cloud Open Feign库在多个微服务之间进行 REST API 调用(同步通信)。

Spring Cloud Open Feign 概述

Feign通过可插拔的注解支持(包括Feign注解和JAX-RS注解)使编写Web服务客户端变得更加容易。此外,Spring Cloud还添加了对Spring MVC注解的支持,并使用与Spring Web中使用的相同的HttpMessageConverters。

使用Feign的一个很大的优点是,我们除了接口定义之外,不需要编写任何调用服务的代码。

例如

package io.wz.userservice.service;

import io.wz.userservice.dto.DepartmentDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "DEPARTMENT-SERVICE", url = "http://localhost:8080")
public interface APIClient {
@GetMapping(value = "/api/departments/{id}")
DepartmentDto getDepartmentById(@PathVariable("id") String departmentId);
}

我们将构建什么?

下面将创建两个微服务,例如部门服务用户服务,并且我们将使用 Spring Cloud Open Feign用户服务部门服务 进行 REST API 调用 ,以获取特定的用户部门。

基础配置

参考以下教程创建 部门服务 和 用户服务 微服务:

使用 RestTemplate 的 Spring Boot 微服务通信示例。

第一步:将Spring cloud open feign Maven依赖添加到User-Service中

打开 user-service项目 的 pom.xml文件 并添加以下依赖项:

	<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

这是添加Spring cloud open feign依赖后的完整pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.wz</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-service</name>
<description>user-service</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.4</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<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>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build> </project>

第2步:使用@EnableFeignClients启用Feign Client

package io.wz.userservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication
@EnableFeignClients
public class UserServiceApplication { public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}

请注意,@EnableFeignClients 注解启用组件扫描声明它们是 Feign 客户端的接口。

第3步:创建feign API客户端

让我们创建一个名为 APIClient的接口 并添加以下代码:

package io.wz.userservice.service;

import io.wz.userservice.dto.DepartmentDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "DEPARTMENT-SERVICE", url = "http://localhost:8080")
public interface APIClient {
@GetMapping(value = "/api/departments/{id}")
DepartmentDto getDepartmentById(@PathVariable("id") String departmentId);
}

我们使用@FeignClient注解声明一个Feign客户端

@FeignClient(value = "DEPARTMENT-SERVICE")

@FeignClient注解中传递的 value 参数是强制的,而使用 URL 参数时,我们指定了 API的URL。

@FeignClient(value = "DEPARTMENT-SERVICE", url = "http://localhost:8080")

此外,由于该接口是 Feign 客户端,因此我们可以使用 Spring Web注解来声明我们想要访问的 API。

第4步:更改getUser方法以调用APIClient

首先注入 APIClient 然后使用它:

  DepartmentDto departmentDto = apiClient.getDepartmentById(user.getDepartmentId());

下面是使用Feign客户端的UserServiceImpl的完整代码,供大家参考:

package io.wz.userservice.service.impl;

import lombok.AllArgsConstructor;
import io.wz.userservice.dto.DepartmentDto;
import io.wz.userservice.dto.ResponseDto;
import io.wz.userservice.dto.UserDto;
import io.wz.userservice.entity.User;
import io.wz.userservice.repository.UserRepository;
import io.wz.userservice.service.APIClient;
import io.wz.userservice.service.UserService;
import org.springframework.stereotype.Service; @Service
@AllArgsConstructor
public class UserServiceImpl implements UserService { private UserRepository userRepository; private APIClient apiClient; @Override
public User saveUser(User user) {
return userRepository.save(user);
} @Override
public ResponseDto getUser(Long userId) { ResponseDto responseDto = new ResponseDto();
User user = userRepository.findById(userId).get();
UserDto userDto = mapToUser(user); DepartmentDto departmentDto = apiClient.getDepartmentById(user.getDepartmentId());
responseDto.setUser(userDto);
responseDto.setDepartment(departmentDto); return responseDto;
} private UserDto mapToUser(User user){
UserDto userDto = new UserDto();
userDto.setId(user.getId());
userDto.setFirstName(user.getFirstName());
userDto.setLastName(user.getLastName());
userDto.setEmail(user.getEmail());
return userDto;
}
}

现在运行两个微服务并进行测试。

测试:启动两个微服务

首先启动部门服务项目,然后启动用户服务项目。

一旦两个项目都启动并在不同的端口上运行。接下来,我们调用 Get User REST API 来测试 user-service REST API 对Department-service 的 调用 。

获取用户 REST API:

请注意,响应结果包含用户的部门。 这表明我们已成功使用APIClient从用户服务 到 部门服务进行 REST API 调用 。

结论

在本教程中,我们学习了如何使用 Spring Cloud Open Feign在多个微服务之间进行 REST API 调用(同步通信)。

源码下载:github gitee

微服务系列-Spring Boot使用Open Feign 微服务通信示例的更多相关文章

  1. 构建微服务:Spring boot

    构建微服务:Spring boot 在上篇文章构建微服务:Spring boot 提高篇中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jp ...

  2. spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法

    spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...

  3. Spring Boot 和 Docker 实现微服务部署

    Spring boot 开发轻巧的微服务提供了便利,Docker 的发展又极大的方便了微服务的部署.这篇文章介绍一下如果借助 maven 来快速的生成微服务的镜像以及快速启动服务. 其实将 Sprin ...

  4. 构建微服务:Spring boot 入门篇

    什么是Spring Boot Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而 ...

  5. 微服务下 Spring Boot Maven 工程依赖关系管理

    单体 Spring Boot Maven 工程 最基本的 pom.xml 包含工程信息.Spring Boot 父工程.属性配置.依赖包.构建插件 <?xml version="1.0 ...

  6. Spring boot学习1 构建微服务:Spring boot 入门篇

    Spring boot学习1 构建微服务:Spring boot 入门篇 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...

  7. Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务

    Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具:Spr ...

  8. 深入学习微框架:Spring Boot(转)

    转:http://www.infoq.com/cn/articles/microframeworks1-spring-boot/ 相关参考: https://spring.io/guides/gs/s ...

  9. Spring boot 零配置开发微服务

    2018年12月29日星期六 体验Spring boot 零配置开发微服务 1.为什么要用Spring  boot? 1.1 简单方便.配置少.整合了大多数框架 1.2 适用于微服务搭建,搭建的微服务 ...

  10. spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求 有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧, 但是细想想 ...

随机推荐

  1. iframe与主窗口通信

    1. 引言 <iframe> 元素是 HTML 中的一个标签,用于在当前页面中嵌入另一个页面 使用 <iframe> 可以实现以下功能: 嵌入其他网页:可以将其他网页嵌入到当前 ...

  2. java文件共享实现方案

    写在前面,由于项目要求负载,又不想大动干戈采用比较贵的设备和高大上的框架,经过一番研究,想使用文件共享方式实现文件的跨服务器访问.本方案采用了jcifs和smbj框架,若想用,请自行查找资源.此为初步 ...

  3. 彻底搞懂Vue针对数组和双向绑定(MVVM)的处理方式

    欢迎关注我的博客:https://github.com/wangweianger/myblog Vue内部实现了一组观察数组的变异方法,例如:push(),pop(),shift()等. Object ...

  4. 关于reids免安装的使用与注意事项

    redis是我们现在常用的缓存数据库.可是redis官方网站只提供linux版本,而我们又习惯在windows系统上使用开发工具,这又怎么办呢? 幸好微软官方也提供了windows版本,方便根据实际需 ...

  5. vscode+gdb 配置

    到这个网址下载 mingw c语言环境 https://sourceforge.net/projects/mingw-w64/files/mingw-w64/ 我是windows64 位,直接下载这个 ...

  6. 交换分区swap的创建与管理

    前言 swap分区是linux系统中一块特殊的硬盘空间,当实际内存不够用的时候,系统会按照一定的算法将部分不用的数据放在swap分区中,从而为当前运行的程序腾出足够的内存空间.好处在于避免内存资源不足 ...

  7. shell命令-lsof

    前言 lsof是系统管理常用命令,其名指的是list open files,列出打开的文件,而在linux系统,一切皆文件. centos7安装:yum install -y lsof 获取网络信息 ...

  8. 通过python,将excel中的数据写入二维列表

    需求:读取Excel表中数据,每行数据放在一个列表中,再把所有列表都存入到一个列表中,形成二维列表. 实现方法:导入可在Python处理Excel表格数据的模块. excel表: 方法一:xlwing ...

  9. IDA的使用-1

    IDA的使用-1 主要收集我自己需要掌握的或者以前不知道的 开始界面 重载文件 在我们逆向过程中被文件修改过,这个时候需要我们重载一下,比如说开发过程中加点代码之类的 下面是加载额外文件,这个文件和我 ...

  10. [ABC128D] equeue

    2023-01-14 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 暴力,贪心 解题思路 由题意可以得出,数据只有 \(n \leq 50,k ...