作为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. 洛谷P1160——队列安排(双向链表)

    题目描述 一个学校里老师要将班上N个同学排成一列,同学被编号为1-N,他采取如下的方法: 1.先将1号同学安排进队列,这时队列中只有他一个人: 2.2-N号同学依次入列,编号为i的同学入列方式为:老师 ...

  2. 1.24学习总结——HTML常见标签

    HTML 标签简写及全称 下表列出了 HTML 标签简写及全称: 标签 英文全称 中文说明 a Anchor 锚 abbr Abbreviation 缩写词 acronym Acronym 取首字母的 ...

  3. java面向对象编程(上)

    java面向对象学习的三条主线 1.Java类及类的成员:属性.方法.构造器.代码块.内部类 2.面向对象的三大特征:封装性.继承性.多态性.(抽象性) 3.其它关键字:this.super.stat ...

  4. 软件测试从业者必备的Linux命令(完整篇)

    观点: 关于Linux,测试从业者,看这篇文章就够了 . 具体,往下看 : 网上关于Linux资料太多.太杂,学习没有重点,特别是对于没有基础的从业者,期望通过那些文档,去自学掌握Linux,可能性太 ...

  5. 直接取PHP二维数组里面的值

    具体是这样的,如下一个二维数组,是从库中读取出来的. $user = array( 0 => array( 'id'    => 1, 'name'  => '张三', 'email ...

  6. Uncaught TypeError: upload is not a function at HTMLInputElement.onclick

    js 中标签的id名称不能和方法名一样, <tr> <td><input type="button" id="login" val ...

  7. 使用Jmeter做接口测试(学生信息的6个接口)

    使用Jmeter做接口测试,案例中涉及到接口有:获取学生信息.登录.添加学生信息.学生金币充值.获取所有学生信息.文件上传. 一.获取学生信息(get请求) 服务器名称或IP:输入被请求服务器的名称或 ...

  8. three.js 材质翻转

    刚学.这个鸟玩意儿卡了半天,记录一下. var skyBox = new THREE.Mesh(skyGeometry, skyMaterial); //创建一个完整的天空盒,填入几何模型和材质的参数 ...

  9. Kafka分区策略

    Kafka分区策略 所谓分区策略是决定生产者将消息发送到哪个分区的算法.Kafka 为我们提供了默认的分区策略,同时它也支持你自定义分区策略. 常见的分区策略包含以下几种:轮询策略.随机策略 .按消息 ...

  10. MySQL where子句的使用

    MySQL WHERE 子句 我们知道从 MySQL 表中使用 SQL SELECT 语句来读取数据. 如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句中. 语法 以下是 ...