专栏首页battcn一起来学Spring Cloud(F版) | 第三篇:注解式HTTP请求Feign

一起来学Spring Cloud(F版) | 第三篇:注解式HTTP请求Feign

文章第一时间送达到您的手中!

Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态)。使用Spring Cloud开发人员可以快速地完成实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工作

Feign

注解式的 Feign 使得 Java HTTP 客户端编写更方便。Feign 灵感来源于安卓网络编程框架 RetrofitJAXRS-2.0WebSocket,支持可插拔编码器和解码器,降低 HTTP API 的复杂度,通过最少的资源和代码来实现和 HTTP API 的连接。通过可定制的解码器和错误处理,可以编写任意的HTTP API。Spring Cloud Feign封装了 Ribbon 这一组件,所以在使用 Feign 同时还能提供负载均衡的功能,这一切只需要一个 @FeignClient即可完成。

早期版本的 FeignSpring Cloud 团队集成在 spring-cloud-netflix 子项目下,但如今 Spring Cloud团队将 Spring Cloud Feign 独立成一个单独的 spring-cloud-openfeign 项目

Try

准备三个工程,分别是 eureka-serverorder-serverproduct-server

Eureka Server

详情参考第一章,或从文末的 GITHUB 链接获取对应篇幅的完整代码

Product Server

一个普通的 Eureka Client 即可,详情参考上一章,或从文末的 GITHUB 链接获取对应篇幅的完整代码

Order Server

这个例子也是在上一章的基础之上做了扩展

依赖

对比上一章,此处多了一个 spring-cloud-starter-openfeign 的依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>

配置文件

src/main/resources 目录下创建一个 bootstrap.yml 的文件,写上 eureka 相关配置信息

server:
  port: 7072
spring:
  application:
    name: order-server
eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
  client:
    service-url:
      defaultZone: http://localhost:7071/eureka/

ProductClient 接口

创建一个 ProductClient ,是不是感觉和 XxxxService 看起来类似(用法都类似),都是接口文件只不过在这个文件的上方多了一个 @FeignClient 注解,多种写法,总有一款适合你

  • name:指定 FeignClient 的名称,该属性会作为微服务的名称,用于服务发现
  • value:同 name 字段互通
  • serviceId:指定服务ID,每个注册到注册中心上的客户端都会有对应的 serviceId 一般是 spring.application.name,与 namevalue 互通
  • url: 一般用于调试,可以指定一个详细地址(http://localhost:8080/products)
  • path: 请求统一路径,可以看成 @RequestMapping("/products")
  • decode404:404 错误时,调用 decoder 进行解码,否则抛出 FeignException
  • fallback:发生错误时,回调 hystrix 类/方法(后面会详细介绍)
package com.battcn.api;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @author Levin
 * @since 2018/9/26 0026
 */
@FeignClient(name = "product-server/products", decode404 = true)
//@FeignClient(name = "products", url = "http://localhost:7073/products")
//@FeignClient(value = "product", serviceId = "product-server", path = "/products", decode404 = true)
public interface ProductClient {

    /**
     * 根据产品ID查询产品信息
     *
     * @param productId ID
     * @return 查询结果
     */
    @GetMapping("/{product_id}")
    String selectProductById(@PathVariable("product_id") Long productId);
}

OrderController

直接使用 @Autowired 注入进去即可,然后调用就好了,对比较 Ribbon 这里我们看不到 RestTemplate 的代码了,也无需自己做解码映射,Spring Cloud Feign 默认都替我们实现好了,我们只需要遵循既定的标准即可

package com.battcn.controller;

import com.battcn.api.ProductClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Levin
 * @since 2018/9/26 0026
 */
@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private ProductClient productClient;


    @GetMapping
    public String query() {
        return this.productClient.selectProductById(10L);
    }
}

主函数

通过 @EnableFeignClients 注解开启对 Feign 的支持,用习惯 Dubbo 的朋友喜欢将 API 打包成独立的 JAR ,这个时候需要指定 basePackage 属性。

package com.battcn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author Levin
 */
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

}

总结

目前很多大佬都写过关于 Spring Cloud 的教程了,如有雷同,请多多包涵,本教程基于最新的 spring-cloud:Finchley.SR1 编写…

本文分享自微信公众号 - battcn(battcn),作者:唐亚峰

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载

    Ribbon 是 Netflix 开源的基于 HTTP 和 TCP 的客户端负载均衡器框架,目前也已被 SpringCloud 团队集成在 spring-clo...

    battcn
  • 一起来学SpringBoot | 第九篇:整合Lettuce Redis

    SpringBoot 除了支持常见的ORM框架外,更是对常用的中间件提供了非常好封装,随着 SpringBoot2.x的到来,支持的组件越来越丰富,也越来越成熟...

    battcn
  • 一起来学SpringBoot | 第六篇:整合SpringDataJpa

    上一篇介绍了 SpringJdbcTemplate的使用,对比原始的 JDBC而言,它更加的简洁。但随着表的增加,重复的CRUD工作让我们苦不堪言,这时候 Sp...

    battcn
  • 一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载

    Ribbon 是 Netflix 开源的基于 HTTP 和 TCP 的客户端负载均衡器框架,目前也已被 SpringCloud 团队集成在 spring-clo...

    battcn
  • springBoot系列教程04:mybatis及druid数据源的集成及查询缓存的使用

    首先说下查询缓存:查询缓存就是相同的数据库查询请求在设定的时间间隔内仅查询一次数据库并保存到redis中,后续的请求只要在时间间隔内都直接从redis中获取,不...

    肖哥哥
  • springMVC

    springmvc中有专用于页面跳转的controller,不会对请求做任何处理,直接跳转页面:     <!-- 对处理请求的controller进行映射 -...

    yawn
  • SpringCloud gateway全局异常处理,以及后台的服务异常response的异常包装

    gateway自己服务的全局异常处理,参考这篇https://segmentfault.com/a/1190000016854364?utm_source=ta...

    天涯泪小武
  • 资源读取配置 原

    南郭先生
  • springboot2.0 添加全局异常拦截,防止详细的异常信息返回到客户端

    zcqshine
  • 解决PKIX问题:unable to find valid certification path to requested target【X509TrustManager】

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

    奋飛

扫码关注云+社区

领取腾讯云代金券