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

前言

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

使用 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. 学习LXC(Linux 容器)技术

    安装LXC.LXD.zfs 测试机器为ubuntu sudo apt-get install lxc lxd zfsutils-linux -y 创建LXD的zfs存储池 sudo lxd init ...

  2. #Powerbi 1分钟学会利用AI,为powerbi报表进行高端颜色设计

    在BI报表的设计中,配色方案往往成为一大难题,一组切合主题.搭配合理的颜色设计往往能为我们的报表,加分不少. 今天,就介绍一个AI配色的网站,利用AI为pbi报表进行配色设计. 一:网站网址 http ...

  3. Pandas:在DataFrame中添加一行,并设置行索引

    解决方案 效果图 参考链接 https://blog.csdn.net/Caiqiudan/article/details/107788525

  4. 69.9K Star,最强开源内网穿透工具:frp

    作为一名开发者,有很多场景需要用到内网穿透,比如:我们在接入一些大平台做第三方应用时,在本地开发微信公众号工具的时候需要让微信平台能否访问到本地提供的接口.除此之外,还有很多其他场景,也会用到,比如: ...

  5. [selenium]点击元素出现的obscure问题

    前言 我们一般使用如下方式点击元素: elem = driver.find_element(...) elem.click() # 或者使用带等待条件的方式 elem = WebDriverWait( ...

  6. springboot整合nacos和dubbo

    0. 源码 源码: gitee 1. 版本 java: 1.8.0_281 nacos: 2.1.2 2. 创建项目 创建一个简单的springboot或者maven项目, 或者代码库(gitee/g ...

  7. C++算法之旅、04 基础篇 | 第一章

    常用代码模板1--基础算法 - AcWing ios::sync_with_stdio(false) 提高 cin 读取速度,副作用是不能使用 scanf 数据输入规模大于一百万建议用scanf 快速 ...

  8. 了解JAVA内存模型(JMM)

    1.概述 我们常说的JMM指的是Java内存模型(Java Memory Model,JMM),主要用于控制Java程序解决线程间如何通信和数据同步,JMM规范了多线程访问共享内存时的 可见性.有序性 ...

  9. 2-MySQL基本语法

    上文说到,数据库的安装和连接,接下来将给大家讲解MySQL数据库的基本语法及数据的类型 1.基本语法 (1).查看当前所有数据库 : show databases; (2).创建数据库 create ...

  10. SpringBoot使用@Async注解8大坑点

    前言 SpringBoot中,@Async注解可以实现异步线程调用,用法简单,体验舒适. 但是你一定碰到过异步调用不生效的情况,今天,我就列出90%的人都可能会遇到的8大坑点. 正文 1.未启用异步支 ...