SpringCloud - feign服务调用

一. Feign的概念

Spring Cloud Netflix的微服务都是以HTTP接口的形式暴露的,所以可以用Apache的HttpClient或Spring的RestTemplate去调用
而Feign是一个使用起来更加方便的HTTP客户端,它用起來就好像调用本地方法一样,完全感觉不到是调用的远程方法
Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。
Feign会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。
Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。
总起来说,Feign具有如下特性:
可插拔的注解支持,包括Feign注解和JAX-RS注解;
支持可插拔的HTTP编码器和解码器;
支持Hystrix和它的Fallback;
支持Ribbon的负载均衡;
支持HTTP请求和响应的压缩

二. 使用Feign

核心思想:
1. 消费方和服务方都必须注册到eureka注册中心
2. 谁是消费方就在谁那进行配置

pom.xml

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

application.yml

ribbon:
  eureka:
    enabled: true
  ReadTimeout: 60000
  ConnectTimeout: 60000
#feign的配置,连接超时及读取超时配置
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic

启动类

@SpringBootApplication
//@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class StudentApplication {

    public static void main(String[] args) {
        SpringApplication.run(StudentApplication.class,args);
    }
    
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

调用服务方接口 jwxt-student/src/main/java/com/jwxt/client/TestClient.java

@FeignClient(name = "JWXT-TEACHER")
public interface UserClient {

    @RequestMapping(value = "/general/findGenerals",method = RequestMethod.GET,name = "PROFILE")
    public Result findGenerals();
}

JSON转换工具类

public class JSONUtils {

    public static<T> List<T> ObjectToList(Object o,Class<T> clazz){
        if(o == null) throw new NullArgumentException("参数为空");
        try{
            String string = JSON.toJSONString(o);
            List<T> list = JSONArray.parseArray(string, clazz);
            return list;
        }catch (Exception e){
            throw new ClassCastException(e.getMessage());
        }
    }
}

使用 com.jwxt.exam.controller.TestController

@RestController
public class StudentExamController {

    @Autowired
    UserClient userClient;

    @RequestMapping("/info")
    public void test01(){
        Result result = userClient.findGenerals();
        Object data = result.getData();
        List<GeneralVo> generalVos = JSONUtils.ObjectToList(data, GeneralVo.class);
        for (GeneralVo generalVo : generalVos) {
            System.out.println(generalVo.toString());
        }
    }
}

三. Feign的工作原理

1、在开发微服务应用时,我们会在主程序入口添加 @EnableFeignClients 注解开启对 Feign Client 扫描加载处理。根据 Feign Client 的开发规范,定义接口并加 @FeignClients 注解。
2、当程序启动时,会进行包扫描,扫描所有 @FeignClients 的注解的类,并将这些信息注入 Spring IOC 容器中。当定义的 Feign 接口中的方法被调用时,通过JDK的代理的方式,来生成具体的 RequestTemplate。当生成代理时,Feign 会为每个接口方法创建一个 RequetTemplate 对象,该对象封装了 HTTP 请求需要的全部信息,如请求参数名、请求方法等信息都是在这个过程中确定的。
3、然后由 RequestTemplate 生成 Request,然后把 Request 交给 Client 去处理,这里指的 Client 可以是 JDK 原生的 URLConnection、Apache 的 Http Client 也可以是 Okhttp。最后Client 被封装到 LoadBalanceclient 类,这个类结合 Ribbon 负载均衡发起服务之间的调用。

四. @FeignClient 注解

name:指定 Feign Client 的名称,如果项目使用了 Eureka,name 属性会作为微服务的名称,用于服务发现。
url:url 一般用于调试,可以手动指定 @FeignClient 调用的地址。
decode404:当发生404错误时,如果该字段为 true,会调用 decoder 进行解码,否则抛出 FeignException。
configuration:Feign 配置类,可以自定义 Feign 的 Encoder、Decoder、LogLevel、Contract。
fallback:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback 指定的类必须实现 @FeignClient 标记的接口。
fallbackFactory:工厂类,用于生成 fallback 类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码。
path:定义当前 FeignClient 的统一前缀

五. Feign参数绑定

@PathVariable

/**

  • 在服务提供者我们有一个方法是用直接写在链接,SpringMVC中用的@PathVariable
  • 这里边和SpringMVC中有些有一点点出入,SpringMVC中只有一个参数而且参数名的话是不用额外指定参数名的,而feign中必须指定
    */
    @RequestMapping(value = “/greet/{dd}”,method = RequestMethod.GET)
    String greetFeign(@PathVariable(“dd”) String dd);

@RequestParam
/**

  • 这里说下@RequestParam 注解和SpringMVC中差别也是不大,区别在于Feign中的是参数进入URL或请求体中,
  • 而SpringMVC中是参数从请求体中到方法中
  • @param ids id串,比如“1,2,3”
  • @return
    */
    @RequestMapping(value = “/users”,method = RequestMethod.GET)
    public List getUsersByIds(@RequestParam(“ids”) List ids);

@RequestHeader
/**

  • 这里是将参数添加到Headers中
  • @param name 参数
    */
    @RequestMapping(value = “/headers”)
    String getParamByHeaders(@RequestHeader(“name”) String name);

@RequestBody
/**

  • 调用服务提供者的post方法,接收回来再被服务提供者丢回来
  • @param user User对象
    */
    @RequestMapping(value = “/user”, method = RequestMethod.POST)
    User getUserByRequestBody(@RequestBody User user)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值