zoukankan      html  css  js  c++  java
  • SpringCloud系列十:使用Feign实现声明式REST调用

    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微服务架构与实战》

     

  • 相关阅读:
    12 Overlap Graphs
    11 Mortal Fibonacci Rabbits
    10 Consensus and Profile
    09 Finding a Motif in DNA
    08 Translating RNA into Protein
    07Mendel's First Law
    大数据面试题目录
    大数据面试题以及答案整理(一)
    工作流调度器之Azkaban
    VI编辑
  • 原文地址:https://www.cnblogs.com/jinjiyese153/p/8659050.html
Copyright © 2011-2022 走看看