作为Spring Cloud的子项目之一,Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式,为微服务架构下服务之间的调用提供了解决方案。首先,利用了OpenFeign的声明式方式定义Web服务客户端;其次还更进一步,通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。

  OpenFeign 可以使消费者将提供者提供的服务名伪装为接口进行消费,消费者只需使用“Service 接口+ 注解”的方式。即可直接调用 Service 接口方法,而无需再使用 RestTemplate 了。其实原理还是使用RestTemplate,而通过Feign(伪装)成我们熟悉的习惯。

  GitEgg框架除了新建Fegin服务之外,还定义实现了消费者Fegin-api,在其他微服务调用的时候,只需要引入Fegin-api即可直接调用,不需要在自己重复开发消费者调用接口。

1、在GitEgg-Platform工程的子工程gitegg-platform-cloud中引入spring-cloud-starter-openfeign依赖,重新install GitEgg-Platform工程,然后GitEgg-Cloud项目需要重新在IDEA中执行Reload All Maven Projects。

<!--?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactid>GitEgg-Platform</artifactid>
<groupid>com.gitegg.platform</groupid>
<version>1.0-SNAPSHOT</version>
</parent>
<modelversion>4.0.0</modelversion> <artifactid>gitegg-platform-cloud</artifactid>
<name>${project.artifactId}</name>
<version>${project.parent.version}</version>
<packaging>jar</packaging> <dependencies>
<!-- Nacos 服务注册发现-->
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-starter-alibaba-nacos-discovery</artifactid>
</dependency>
<!-- Nacos 分布式配置-->
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-starter-alibaba-nacos-config</artifactid>
</dependency>
<!-- OpenFeign 微服务调用解决方案-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
</dependencies> </project>

我们从系统架构设计方面考虑,GitEgg-Cloud下的gitegg-service作为业务逻辑处理模块,gitegg-service-api作为微服务统一对外提供接口的模块,这里在测试的时候需要用到两个微服务之间的调用,我们这里在gitegg-service下gitegg-service-base里面新建测试代码,和gitegg-service-system之间相互调用。注意,这里需要说明,gitegg-service-api并不是继承gitegg-service做业务扩展,而是对外提供接口的抽象,比如现在有A、B、C三个系统A、B都需要调用C的同一个方法,如果按照业务逻辑来罗列代码的话,那么就需要在A和B中写相同的调用方法来调用C,这里我们抽出来一个api模块,专门存放调用微服务C的调用方法,在使用时,A和B只需要引入C的jar包即可直接使用调用方法。

2、在gitegg-service-system-api工程中,引入SpringBoot,SpringCloud,Swagger2的依赖,新建ISystemFeign.java和ApiSystemDTO.java,作为OpenFeign调用微服务的公共方法:

<!--?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactid>GitEgg-Cloud</artifactid>
<groupid>com.gitegg.cloud</groupid>
<version>1.0-SNAPSHOT</version>
</parent>
<modelversion>4.0.0</modelversion> <artifactid>gitegg-service-api</artifactid>
<name>${project.artifactId}</name>
<version>${project.parent.version}</version>
<packaging>pom</packaging>
<modules>
<module>gitegg-service-base-api</module>
<module>gitegg-service-bigdata-api</module>
<module>gitegg-service-system-api</module>
</modules> <dependencies>
<!-- gitegg Spring Boot自定义及扩展 -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-boot</artifactid>
</dependency>
<!-- gitegg Spring Cloud自定义及扩展 -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-cloud</artifactid>
</dependency>
<!-- gitegg swagger2-knife4j -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-swagger</artifactid>
</dependency>
</dependencies> </project>
package com.gitegg.service.system.api.feign;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.service.system.api.dto.ApiSystemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam; @FeignClient(name = "gitegg-service-system")
public interface ISystemFeign { /**
* OpenFeign测试Get
*
* @param id
* @return
*/
@GetMapping("/system/api/by/id")
Result<object> querySystemById(@RequestParam("id") Long id); /**
* OpenFeign测试Post
*
* @param apiSystemDTO
* @return ApiSystemDTO
*/
@PostMapping("/system/api/by/dto")
Result<apisystemdto> querySystemByDto(@RequestBody ApiSystemDTO apiSystemDTO);
}
package com.gitegg.service.system.api.dto;

import lombok.Data;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; @Data
public class ApiSystemDTO { @NotNull
@Min(value = 10, message = "id必须大于10")
@Max(value = 150, message = "id必须小于150")
private Long id; @NotNull(message = "名称不能为空")
@Size(min = 3, max = 20, message = "名称长度必须在3-20之间")
private String name; }

2、在gitegg-service-system工程中,修改SystemController.java,添加需要被微服务调用的方法:

package com.gitegg.service.system.controller;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.service.system.dto.SystemDTO;
import com.gitegg.service.system.service.ISystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @RestController
@RequestMapping(value = "system")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Api(tags = "gitegg-system")
@RefreshScope
public class SystemController { private final ISystemService systemService; @Value("${spring.datasource.maxActive}")
private String nacosMaxActiveType; @GetMapping(value = "list")
@ApiOperation(value = "system list接口")
public Object list() {
return systemService.list();
} @GetMapping(value = "page")
@ApiOperation(value = "system page接口")
public Object page() {
return systemService.page();
} @GetMapping(value = "exception")
@ApiOperation(value = "自定义异常及返回测试接口")
public Result<string> exception() {
return Result.data(systemService.exception());
} @PostMapping(value = "valid")
@ApiOperation(value = "参数校验测试接口")
public Result<systemdto> valid(@Valid @RequestBody SystemDTO systemDTO) {
return Result.data(systemDTO);
} @PostMapping(value = "nacos")
@ApiOperation(value = "Nacos读取配置文件测试接口")
public Result<string> nacos() {
return Result.data(nacosMaxActiveType);
} @GetMapping(value = "api/by/id")
@ApiOperation(value = "Fegin Get调用测试接口")
public Result<object> feginById(@RequestParam("id") String id) {
return Result.data(systemService.list());
} @PostMapping(value = "api/by/dto")
@ApiOperation(value = "Fegin Post调用测试接口")
public Result<object> feginByDto(@Valid @RequestBody SystemDTO systemDTO) {
return Result.data(systemDTO);
}
}

3、参照gitegg-service-system工程,在gitegg-service-base工程下,引入gitegg-service-system-api依赖,新建BaseController.java、GitEggBaseApplication.java、bootstrap.yml作为服务调用方:

pom.xml:

    <dependencies>
<!-- gitegg-service-system 的fegin公共调用方法 -->
<dependency>
<groupid>com.gitegg.cloud</groupid>
<artifactid>gitegg-service-system-api</artifactid>
<version>${project.parent.version}</version>
</dependency>
</dependencies>

BaseController.java:

package com.gitegg.service.base.controller;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.service.system.api.dto.ApiSystemDTO;
import com.gitegg.service.system.api.feign.ISystemFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @RestController
@RequestMapping(value = "base")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Api(tags = "gitegg-base")
@RefreshScope
public class BaseController { private final ISystemFeign systemFeign; @GetMapping(value = "api/by/id")
@ApiOperation(value = "Fegin Get调用测试接口")
public Result<object> feginById(@RequestParam("id") Long id) {
return Result.data(systemFeign.querySystemById(id));
} @PostMapping(value = "api/by/dto")
@ApiOperation(value = "Fegin Post调用测试接口")
public Result<object> feginByDto(@Valid @RequestBody ApiSystemDTO systemDTO) {
return Result.data(systemFeign.querySystemByDto(systemDTO));
} }

GitEggBaseApplication.java:

package com.gitegg.service.base;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan; /**
* gitegg-base 启动类
*/
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.gitegg")
@ComponentScan(basePackages = "com.gitegg")
@MapperScan("com.gitegg.*.*.mapper")
@SpringBootApplication
public class GitEggBaseApplication { public static void main(String[] args) {
SpringApplication.run(GitEggBaseApplication.class,args);
} }

bootstrap.yml:

server:
port: 8002
spring:
application:
name: gitegg-service-base
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
prefix: gitegg-service-system
group: DEFAULT_GROUP
enabled: true

4、分别启动gitegg-service-base和gitegg-service-system项目,打开浏览器,访问http://127.0.0.1:8002/doc.html(这里gitegg-service-base的端口设置为8002,所以访问gitegg-service-base的服务进行测试),在页面左侧菜单分别点击Fegin Get调用测试接口和Fegin Post调用测试接口,可以查看微服务调用成功



本文源码在https://gitee.com/wmz1930/GitEgg 的chapter-11分支。

SpringCloud微服务实战——搭建企业级开发框架(十一):集成OpenFeign用于微服务间调用的更多相关文章

  1. SpringCloud微服务实战——搭建企业级开发框架(四十二):集成分布式任务调度平台XXL-JOB,实现定时任务功能

      定时任务几乎是每个业务系统必不可少的功能,计算到期时间.过期时间等,定时触发某项任务操作.在使用单体应用时,基本使用Spring提供的注解即可实现定时任务,而在使用微服务集群时,这种方式就要考虑添 ...

  2. SpringCloud微服务实战——搭建企业级开发框架(四十一):扩展JustAuth+SpringSecurity+Vue实现多租户系统微信扫码、钉钉扫码等第三方登录

      前面我们详细介绍了SSO.OAuth2的定义和实现原理,也举例说明了如何在微服务框架中使用spring-security-oauth2实现单点登录授权服务器和单点登录客户端.目前很多平台都提供了单 ...

  3. SpringCloud微服务实战——搭建企业级开发框架(二):环境准备

    这里简单说明一下在Windows系统下开发SpringCloud项目所需要的的基本环境,这里只说明开发过程中基础必须的软件,其他扩展功能(Docker,k8s,MinIO,XXL-JOB,EKL,Ke ...

  4. SpringCloud微服务实战——搭建企业级开发框架(三十四):SpringCloud + Docker + k8s实现微服务集群打包部署-Maven打包配置

      SpringCloud微服务包含多个SpringBoot可运行的应用程序,在单应用程序下,版本发布时的打包部署还相对简单,当有多个应用程序的微服务发布部署时,原先的单应用程序部署方式就会显得复杂且 ...

  5. SpringCloud微服务实战——搭建企业级开发框架(四十四):【微服务监控告警实现方式一】使用Actuator + Spring Boot Admin实现简单的微服务监控告警系统

      业务系统正常运行的稳定性十分重要,作为SpringBoot的四大核心之一,Actuator让你时刻探知SpringBoot服务运行状态信息,是保障系统正常运行必不可少的组件.   spring-b ...

  6. SpringCloud微服务实战——搭建企业级开发框架(三十六):使用Spring Cloud Stream实现可灵活配置消息中间件的功能

      在以往消息队列的使用中,我们通常使用集成消息中间件开源包来实现对应功能,而消息中间件的实现又有多种,比如目前比较主流的ActiveMQ.RocketMQ.RabbitMQ.Kafka,Stream ...

  7. SpringCloud微服务实战——搭建企业级开发框架(三十七):微服务日志系统设计与实现

      针对业务开发人员通常面对的业务需求,我们将日志分为操作(请求)日志和系统运行日志,操作(请求)日志可以让管理员或者运营人员方便简单的在系统界面中查询追踪用户具体做了哪些操作,便于分析统计用户行为: ...

  8. SpringCloud微服务实战——搭建企业级开发框架(九):使用Nacos发现、配置和管理微服务

    Nacos是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台,Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置 ...

  9. SpringCloud微服务实战——搭建企业级开发框架(二十三):Gateway+OAuth2+JWT实现微服务统一认证授权

      OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发token(令牌),使得第三方应用可以使用该token(令牌)在限定时间.限定 ...

随机推荐

  1. Oracle体系结构二

  2. 深度探索-Redis复制

    1.前言 本文介绍了Redis复制的主要流程和设计思想.通过本文的阅读,您大致能理解复制在软件架构方面的通用思想.在阅读本文之前,希望读者首先对Redis有一定的认识,对Redis的事件类型.和事件处 ...

  3. 改Jupyter Notebook的默认工作路径?

    如何更改Jupyter Notebook的默认工作路径? 1.在cmd中输入命令使Jupyter产生配置文件:Jupyter_notebook_config.py jupyter notebook - ...

  4. Vue组件封装之无限滚动列表

    无限滚动列表:分为单步滚动和循环滚动两种方式 <template> <div class="box" :style="{width:widthX,hei ...

  5. 学习PHP中的国际化功能来查看货币及日期信息

    做为一门在世界范围内广泛使用的编程语言,国际化能力往往是衡量一个编程语言是否能够大范围流行的重要内容.特别是对于 PHP 这种以 Web 页面编程为主战场的语言来说,国际化能力更是重中之重.在 PHP ...

  6. 使用fiddler抓包模拟器及配置fiddler过滤

    一. 安装fiddler https://www.telerik.com/fiddler 二. 配置fiddler,一下的ip要根据自己电脑情况设置 然后重启Fiddler,一定要重启!!! 三.配置 ...

  7. PHP文件包含漏洞小结

    参考链接:https://chybeta.github.io/2017/10/08/php文件包含漏洞/ 四大漏洞函数 PHP文件包含漏洞主要由于四个函数引起的: include() include_ ...

  8. genymotion从本地拖拽apk到模拟器失败,报错“An error occured while deploying the file……”-解决方案

    前两篇已经讲过genymotion的安装了,但genymotion构建的安卓模拟器的界面比较简洁,什么软件都没.那么我们进行测试之前,先将需要测试的apk安装到模拟器中,一般来说,直接将apk文件从本 ...

  9. 【Vue】淘气三千问之 data为什么是函数而不是对象?这河狸吗

    朋友,当你提出以上问题的时候建议你先去复习下原型链的知识 但是我好人做到底直接就讲了吧,我们先看一下下面的这段代码: function Component () { this.data = this. ...

  10. 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 百篇博客分析OpenHarmony源码 | v43.02

    百篇博客系列篇.本篇为: v43.xx 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪里 ...