1. 回顾

  前文的示例中是使用RestTemplate实现REST API调用的,代码大致如下:

@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
}

  由代码克制,我们是使用拼接字符串的方式构造URL的,该URL只有一个参数。

  然而在现实中,URL往往有多个参数。如果这时还使用这种方式构造URL,那么就会变得很低效,并且难以维护。

2. Feign简介

  Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可帮助我们更加便捷、优雅地调用HTTP API。

  在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者

  JAX-RS注解等。

  Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。

3. 为服务消费者整合Feign

  > 复制项目 microservice-consumer-movie,将ArtifactId修改为 microservice-consumer-movie-feign

  > 添加Feign的依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

  > 创建一个Feign接口,并添加@FeignClient注解

package com.itmuch.cloud.microserviceconsumermoviefeign.feign;

import com.itmuch.cloud.microserviceconsumermoviefeign.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "microservice-provider-user")
public interface UserFeignClient { @GetMapping(value = "/{id}")
User findById(@PathVariable("id") Long id); }

  @FeignClient注解中的microservice-provider-user是一个任意的客户端名称,用于创建Ribbon负载均衡器。在本例中,由于使用了Eureka,

  所以Ribbon会把microservice-provider-user解析成Eureka Server服务注册表中的服务。

  如果不想使用Eureka,也可使用service.ribbon.listOfServers属性配置服务器列表

  也可使用url属性指定请求的URL(URL可以是完整的URL或主机名),例如

  @FeignClient(name = "microservice-provider-user", url = "http://localhost:8000/")

  > 修改Controller代码,让其调用Feign接口

package com.itmuch.cloud.microserviceconsumermoviefeign.controller;

import com.itmuch.cloud.microserviceconsumermoviefeign.feign.UserFeignClient;
import com.itmuch.cloud.microserviceconsumermoviefeign.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; @RestController
public class MovieController { @Autowired
private UserFeignClient userFeignClient; @GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.userFeignClient.findById(id);
} }

  > 修改启动类,添加@EnableFeignClients注解

package com.itmuch.cloud.microserviceconsumermoviefeign;

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.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class MicroserviceConsumerMovieFeignApplication { public static void main(String[] args) {
SpringApplication.run(MicroserviceConsumerMovieFeignApplication.class, args);
} @Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

  > 启动 microservice-discovery-eureka

  > 启动两个以上的 microservice-provider-user 实例

  > 启动 microservice-consumer-movie-feign

  > 多次访问 http://localhost:8010/user/1,在各个实例的控制台下都可看见类似日志

Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.balance as balance3_0_0_, user0_.name as name4_0_0_, user0_.username as username5_0_0_ from user user0_ where user0_.id=?
2018-03-27 17:48:19.468 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2018-03-27 17:48:19.480 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([age2_0_0_] : [INTEGER]) - [20]
2018-03-27 17:48:19.481 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([balance3_0_0_] : [NUMERIC]) - [100.00]
2018-03-27 17:48:19.481 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name4_0_0_] : [VARCHAR]) - [张三]
2018-03-27 17:48:19.481 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([username5_0_0_] : [VARCHAR]) - [account1]

4. 总结

  以上结果说明,本文实现了声明式的REST API调用,同时还实现了客户端侧的负载均衡。

  下文将讲解自定义Feign配置,敬请期待~~~

5. 参考

  周立 --- 《Spring Cloud与Docker微服务架构与实战》

SpringCloud系列十:使用Feign实现声明式REST调用的更多相关文章

  1. SpringCloud系列-利用Feign实现声明式服务调用

    上一篇文章<手把手带你利用Ribbon实现客户端的负载均衡>介绍了消费者通过Ribbon调用服务实现负载均衡的过程,里面所需要的参数需要在请求的URL中进行拼接,但是参数太多会导致拼接字符 ...

  2. 6.使用Feign实现声明式REST调用

                        使用Feign实现声明式REST调用 6.1. Feign简介 Feign是一个声明式的REST客户端,它的目的就是让REST调用更加简单. Feign提供了H ...

  3. SpringCloud学习笔记(3):使用Feign实现声明式服务调用

    简介 Feign是一个声明式的Web Service客户端,它简化了Web服务客户端的编写操作,相对于Ribbon+RestTemplate的方式,开发者只需通过简单的接口和注解来调用HTTP API ...

  4. spring cloud 入门系列五:使用Feign 实现声明式服务调用

    一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ...

  5. SpringCloud(四):使用Feign实现声明式服务调用

    一.Feign介绍Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解 ...

  6. springCould:使用Feign 实现声明式服务调用

    一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ...

  7. Spring Cloud Feign声明式服务调用(转载)+遇到的问题

    转载:原文 总结: 1.pom添加依赖 2.application中填写正确的eureka配置 3.启动项中增加注解 @EnableFeignClients 4.填写正确的调用接口 通过原文使用Fei ...

  8. springcloud-feign组件实现声明式的调用

    11.使用feign实现声明式的调用 使用RestTemplate+ribbon已经可以完成对服务端负载均衡的调用,为什么还要使用feign? @RequestMapping("/hi&qu ...

  9. SpringCloud 源码系列(6)—— 声明式服务调用 Feign

    SpringCloud 源码系列(1)-- 注册中心 Eureka(上) SpringCloud 源码系列(2)-- 注册中心 Eureka(中) SpringCloud 源码系列(3)-- 注册中心 ...

随机推荐

  1. SNMP OID批量枚举工具

    SNMP OID批量枚举工具   SNMP信息包含大量的系统.设备信息.这些信息均使用OID方式表示.由于OID编号规则复杂,不便于记忆.为了快速通过OID批量获取指定信息,Kali Linux新增了 ...

  2. Android中的MVC,MVP和MVVM

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha MVC,MVP,MVVM的区别 #MVC 软件可以分为三部分 视图(View):用户界面 ...

  3. Codeforces 919 E Congruence Equation

    题目描述 Given an integer xx . Your task is to find out how many positive integers nn ( 1<=n<=x1&l ...

  4. 【分块】【常数优化】【Orz faebdc】洛谷 P1083 NOIP2012提高组 借教室

    分块90分. By AutSky_JadeK [重点在下面] #include<cstdio> #include<cmath> using namespace std; #de ...

  5. 【set】bzoj3715 [PA2014]Lustra

    对每种属性开一个set,只要某个厂家符合该属性的最值,就加进set,最后判断是否有某个厂家在4个set里都存在即可. #include<cstdio> #include<set> ...

  6. Eclipse编辑jsp卡死解决方案

    使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...

  7. 如何使用 vimdiff 来 git diff

    git config --global diff.tool vimdiffgit config --global difftool.prompt falsegit config --global al ...

  8. IDEA中添加类的创建者信息

    创建方法: 1. 使用快捷键(ctrl + alt + s),在弹出框中左边侧选择 Editor -> File and Code Templates,左边侧相应会更新 右边侧选择 Class, ...

  9. android应用开发-从设计到实现 2-8 组件与经常使用模式

    组件与经常使用模式 前面已经比較全面的介绍了Material Design相关的设计哲学.设计原理和方法论. 这一章開始,我们将看看这些原理是怎样在安卓系统其中得到实践的. 一个应用并非全然从什么都没 ...

  10. JMS两种消息模型

    前段时间学习EJB.接触到了JMS(Java消息服务),JMS支持两种消息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即点对点和公布订阅模型. ...