Feign声明式服务调用
Feign是一种声明式、模板化的HTTP客户端(仅在Application Client中使用)。声明式调用是指,就像调用本地方法一样调用远程方法,无需感知操作远程http请求。
Spring Cloud的声明式调用, 可以做到使用 HTTP请求远程服务时能就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。Feign的应用,让Spring Cloud微服务调用像Dubbo一样,Application Client直接通过接口方法调用Application Service,而不需要通过常规的RestTemplate构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。
在使用Feign技术开发Spring Cloud微服务时,需要先抽取要注册发布的服务标准,将这套标准通过接口的形式定义出来。
在Application Service端开发中,依赖抽取的服务标准接口工程,并对接口给予实现。
在Application Client端开发中,依赖抽取的服务标准接口工程,并应用接口信息和Feign技术,实现远程服务的调用。
在整体微服务开发中,Eureka Server作为注册中心必不可少,注册中心的作用不变,仍旧是注册和发现服务。
一、Feign入门案例
1.1 创建服务标准工程
服务标准工程,是用于定义Application Service需要对外发布的服务标准接口的工程。这个工程中定义的接口需要使用SpringMVC中的注解来描述,所以工程依赖的资源必须有SpringMVC。在案例中,为了简化依赖复杂度,使用spring-boot中的spring-boot-starter-web资源依赖实现SpringMVC技术的导入。
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <parent> <groupId>com.yucong</groupId> <properties> <dependencies> <build> </project> |
定义的服务接口和普通的服务接口没有太大的区别,但是为了让Feign技术可以识别到服务的访问URL,需要使用SpringMVC注解@RequestMapping来描述接口中定义的方法,代表方法对外提供服务时监听的URL路径是什么。
/**
* 微服务标准。
* 是Application Service要提供的服务的标准。
* 也是Application Client要调用远程服务的标准。
* 就是一个普通的接口。
*/
public interface FirstFeignService { /**
* 测试GET请求的方法。
* 请求不传递任何的参数。
* 请求地址是 - /testFeign -> http://ip:port/testFeign
* @return
*/
@RequestMapping(value="/testFeign", method=RequestMethod.GET)
public List<String> testFeign();
}
1.2 创建Application Service 工程
服务提供者在开发的时候,需要实现服务标准工程中定义的服务接口,并注册服务到Eureka Server注册中心上,所以需要依赖的资源必须有eureka和服务标准接口。
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.yucong</groupId> <properties> <dependencyManagement> <dependencies> </dependencyManagement> <dependencies> <!-- web启动器。 springmvc相关内容 --> <dependency> <!-- spring cloud 默认配置启动器 --> <!-- 客户端依赖 --> <!-- 自定义的服务标准工程。 --> </dependencies> <build> </project> |
在Spring Cloud微服务架构中,服务是由Controller对外提供的,是基于HTTP协议发布的REST服务。所以实现服务接口的是控制器。注意,服务不代表服务层代码。
/**
* 自定义的服务控制器
* 对外提供服务的Application Service。
* 不能随便的定义服务了。如果想让Application Client可以通过Feign技术访问当前类型提供的服务,
* 则必须遵循服务标准。
*/
@RestController
public class TestFeignAppServiceController implements FirstFeignService { /**
* 因为当前的方法都是实现接口FirstFeignService中的方法。
* 而在接口中,已经将请求URL和方法耦合到一起了。
* 所以在当前的控制器中,不能重复定义@RequestMapping来约束请求URL。
*/
@Override
public List<String> testFeign() { List<String> result = new ArrayList<>(); result.add("test feign");
result.add("this is first spring cloud with feign"); return result;
} }
1.3 创建Application Client工程
服务消费者在开发的时候,需要在Eureka Server中发现可用服务,并通过Feign来实现远程服务调用。在这个过程中,需要依赖于服务标准工程中定义的服务接口。
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.yucong</groupId> <properties> <dependencyManagement> <dependencies> <dependency> <!-- spring cloud 默认配置启动器 --> <!-- 客户端依赖 --> <!-- feign启动器。封装了所有的feign相关资源的jar包。提供的是默认环境。 <!-- 服务标准工程。 --> <build> </project> |
在通过Feign来实现远程服务调用时,需要提供一个本地接口来继承服务标准工程提供的服务接口。这个本地接口不需要给予任何实现,在底层Spring容器会为这个接口提供一个基于JDK实现的代理对象,这个代理对象由Feign技术提供具体的HandlerInterceptor逻辑,实现远程的调用。实现过程类似通过代码调用LoadBalancerClient实现的Rest远程访问。
而本地接口继承服务标准接口后,需要提供注解@FeignClient,注解的属性name代表当前接口要调用的远程服务的应用命名。
/**
* 本地接口,继承服务标准接口。
* 在接口上增加注解@FeignClient,代表当前接口是一个Feign技术中的客户端。
* 需要发起远程的http请求。
* 注解有属性name - 代表当前的FeignClient在请求application service的时候,是调用哪一个服务?
* 所谓的哪一个服务,就是application service全局配置文件中的spring.application.name属性值。
*/
@FeignClient(name="test-feign-application-service")
public interface FirstClientFeignService extends FirstFeignService { }
控制器中可以像调用本地定义服务对象那样来调用远程服务。
/**
* Application Client中的控制器。是和用户直接交互的控制器。
* 像平时开发代码一样。调用本地的一个service接口。通过service接口远程访问Application Service。
*/
@RestController
public class TestFeignAppClientController { /**
* 本地定义的服务接口。用于实现远程调用application service的接口。
*/
@Autowired
private FirstClientFeignService service; /**
* 无参
*/
@GetMapping("/testFeign")
public List<String> testFeign(){
System.out.println(this.service.getClass().getName());
return this.service.testFeign();
} }
二、参数处理
在Feign处理远程服务调用时,传递参数是通过HTTP协议传递的,参数存在的位置是请求头或请求体中。请求头传递的参数必须依赖@RequestParam注解来处理请求参数,请求体传递的参数必须依赖@RequestBody注解来处理请求参数。
上述的要求是指Feign技术传递参数,也就是Application Client远程调用Application Service过程。
2.1 处理请求头传参
使用请求头传递参数时,定义的服务标准接口中,必须使用@RequestParam注解来描述方法参数,且注解属性value/name必须指定,代表从请求头中获取的请求参数命名是什么。
在默认环境中,使用请求头传递参数时,Application Service中的控制器无法使用SpringMVC中的自动对象封装能力。只能处理简单数据类型。如:数学类型,字符串类型,数组类型等。无法处理自定义对象类型。
2.2 处理请求体传参
使用请求体传递参数时,定义的服务标准接口中,必须使用@RequestBody注解来描述方法参数,因为Feign技术发起的POST请求,请求参数是使用JSON字符串来传递的,且form表单类型为RAW。
使用请求体传递参数时,Application Service中的控制器必须使用@RequestBody注解来描述方法参数,且RAW类型的form表单上传的是一个文本内容,只能转换为唯一的一个参数。
如果使用POST方式提交请求,并传递多个普通类型的参数时,Feign不会通过请求体传递参数,是通过请求头传递的参数。也就是请求路径为 : http://applicationserver:port/url?paramName=paramValue
Feign声明式服务调用的更多相关文章
- Spring Cloud Feign 声明式服务调用
目录 一.Feign是什么? 二.Feign的快速搭建 三.Feign的几种姿态 参数绑定 继承特性 四.其他配置 Ribbon 配置 Hystrix 配置 一.Feign是什么? 通过对前面Sp ...
- spring cloud 系列第4篇 —— feign 声明式服务调用 (F版本)
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.feign 简介 在上一个用例中,我们使用ribbon+restTem ...
- Spring Cloud Feign声明式服务调用(转载)+遇到的问题
转载:原文 总结: 1.pom添加依赖 2.application中填写正确的eureka配置 3.启动项中增加注解 @EnableFeignClients 4.填写正确的调用接口 通过原文使用Fei ...
- SpringCloud实战-Feign声明式服务调用
在前面的文章中可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率 ...
- 笔记:Spring Cloud Feign 声明式服务调用
在实际开发中,对于服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以我们通常会针对各个微服务自行封装一些客户端类来包装这些依赖服务的调用,Spring Cloud Feign 在此基础上做了进 ...
- SpringCloud无废话入门03:Feign声明式服务调用
1.Feign概述 在上一篇的HelloService这个类中,我们有这样一行代码: return restTemplate.getForObject("http://hello-servi ...
- Spring Cloud 2-Feign 声明式服务调用(三)
Spring Cloud Feign 1. pom.xml 2. application.yml 3. Application.java 4. Client.java 简化RestTemplate调 ...
- SpringCloud系列-利用Feign实现声明式服务调用
上一篇文章<手把手带你利用Ribbon实现客户端的负载均衡>介绍了消费者通过Ribbon调用服务实现负载均衡的过程,里面所需要的参数需要在请求的URL中进行拼接,但是参数太多会导致拼接字符 ...
- 声明式服务调用:Spring Cloud Feign
最近在学习Spring Cloud的知识,现将声明式服务调用:Spring Cloud Feign 的相关知识笔记整理如下.[采用 oneNote格式排版]
随机推荐
- Jmeter -- 脚本录制
步骤如下: 1. 添加http代理服务器(Add -> Non-TestElement -> HTTP(S)Test Script Recorder) 2. 对http代理进行配置,如下图 ...
- 关于SpringBoot跨域的问题
直接在启动类里面加这一段代码就行: @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource sourc ...
- laravel 中first和find区别(总结一)
检索单个模型/集合 除了从指定的数据表检索所有记录外,你也可以通过 find 或 first 方法来检索单条记录.这些方法不是返回一组模型,而是返回一个模型实例: // 通过主键取回一个模型... $ ...
- 微信小程序之生成二维码
最近项目中涉及到小程序的生成二维码,很是头疼,经过多次摸索,整理出了自己的一些思想方法,如有不足,欢迎指正. 首先完全按照小程序的结构依次填坑. pages--index.wxml <view ...
- Linux - 搭建Web项目(Django + nginx + uwsgi)
工作中碰到需要使用Django + nginx + uwsgi 搭建项目环境 1. 搭建基本环境 需要有python环境,不多做说明 需要安装nginx,不多做说明 需要安装uwsgi: yum in ...
- rest 参数与扩展运算符
rest 参数与扩展运算符 1.rest 参数 ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了.rest 参数搭配的变量是一个数组 ...
- 使用jQuery做简单的图片轮播效果
一.本特效主要用到的前端知识点 CSS中绝对定位(absolute)CSS实现垂直居中jQuery中简单的淡入淡出动画效果(fadeIn,fadeOut)定时器(setInterval,clear ...
- shell案例(6):1、创建用户 2、创建目录 3、创建文件 4、退出
脚本基本要求 1.创建用户2.创建目录3.创建文件4.退出 #!/bin/bash #author:zhiping.wang Check_error() { ] then echo "$1 ...
- 关于ansbile
YAML语法规则 规则一:缩进(一个缩进两空格,注意一定不用tab) 规则二:冒号(每个冒号后一定要有空格) 规则三:短横线 - (短横线后面要空格) 编写案例 ansible-playbook -- ...
- SQL server 自增主键重新从1开始
原文链接:http://blog.csdn.net/zhengjia0826/article/details/43149953 dbcc checkident('sys_common_switch', ...