SpringCloud学习笔记(五):通过Feign客户端让代码变得优雅

Feign的作用

Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。
Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。
Spring Cloud Feign具备可插拔的注解支持,支持Feign注解、JAX-RS注解和Spring MVC的注解。

使用Feign

引入依赖

要想使用Feign,首先要做的自然就是引入依赖了,我们在cargoAccesser模块中的pom.xml添加如下的依赖

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

导入依赖到我们的项目中,就可以着手使用Feign客户端了。

Feign客户端接口

我们在cargoAccesser模块下src/main/java下新建一个名为feign的包,cargoAccesser这个模块的微服务依赖于microservicefirst模块提供的app-cargo微服务。先前我们使用的是Rest模板的方式请求app-cargo的微服务,现在我们将使用一种更加优雅的方式。

在刚刚建立的feign包下新建一个接口,命名为CargoFeignClient。在接口名上加上@FeignClient(value = “app-cargo”)注解,声明这是一个FeignClient,并且服务地址为app-cargo。

在接口中声明一个queryCargoById方法,并且在方法上加上@RequestMapping(value="/cargo/{id}",method = RequestMethod.GET)注解,标记了API中对应接口方法的请求方式以及URL。

Feign客户端接口完整代码如下

package feign;

import entity.Cargo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(value = "app-cargo")//声明这是一个FeignClient,服务地址为app-cargo
public interface CargoFeignClient {

    @RequestMapping(value = "/cargo/{id}", method = RequestMethod.GET)
        //没错,就是和MVC注解一样!这个注解由@RequestLine增强而来。声明请求路径,方法为GET
    Cargo queryCargoById(@PathVariable("id") Long id);
}

使用Feign客户端调用微服务

原先我们在cargoAccesser模块中的CargoService中写了使用RestTemplate调用app-cargo的方法,之前我们的写法是这样的

        String cargoUrl = "http://app-cargo/cargo/{id}";
        Cargo cargo = this.restTemplate.getForObject(cargoUrl,Cargo.class,id);

在我们使用了FeignClient之后,我们可以用更加优雅的方式来实现这一功能。我们删掉原来这两行代码,在这个Service中新增一个CargoFeignClient成员变量,并开启自动注入。在执行调用请求的方法中,新增一行代码

Cargo cargo = cargoFeignClient.queryCargoById(id);

这样可以通过我们刚刚声明的FeignClient来实现调用,在IDEA中声明CargoFeignClient的自动注入会出现红线,但编译没有出现问题,我们可以通过注解忽略报错提示。

最后,我们在启动类上开启FeignClient,并标记扫描的包就可以启动cargoAccesser模块了。在启动类上添加如下的注解

@EnableFeignClients(basePackages ="feign")//启动Feign服务,指定扫描的包

启动服务,访问http://localhost:8095/cargoList/123,发现能正常调用app-cargo微服务。这样我们就完成了FeignClient的声明式API调用了。

熔断整合

在上一节我们使用了Hystrix阻止了服务雪崩,但是在每一个Service对应的方法下都要声明一个Fallback方法,这样我们的代码结构就会受到影响。本文开头引用的Feign简介部分提到,Feign整合了Hystrix,那么使用FeignClient也是可以让我们的熔断变得更加优雅的,具体实现步骤如下

新建fallback对应类

我们在模块下新建一个fallback包,在包下新建一个名为CargoServiceFallback的类,类上需要加上@Component注解,表示这个类是一个组件,这个类要实现我们声明的FeignClient接口,这个类就用来放调用app-cargo出错时的回调方法,完整代码如下

package fallback;

import entity.Cargo;
import feign.CargoFeignClient;
import org.springframework.stereotype.Component;

@Component
public class CargoServiceFallback implements CargoFeignClient {
    @Override
    public Cargo queryCargoById(Long id) {
        return new Cargo(id,"请求不到name","请求不到price");
    }
}

代码中的queryCargoById方法的内容与我们之前使用的fallback方法内容基本一致,就不做赘述了。

启动Hystrix

我们已经准备好对app-cargo服务的容错方法了,接下来我们要把刚刚做的事情让SpringBoot框架扫描到。
由于Feign是集成的Hystrix,因此要在yml文件中配置一下,告诉SpringBoot启动Feign的Hystrix。在yml中添加如下配置信息

feign:
  hystrix:
    enabled: true #启动熔断容错处理

然后在启动类上修改SpringBoot的包扫描路径,在其中添加一个fallback包就可以了

@SpringBootApplication(scanBasePackages={"controller","entity","service","fallback"})

测试

我们注释掉CargoService类queryCargoById上的@HystrixCommand注解,这个方法不再被我们添加的Hystrix组件管理了,而是被Feign集成的Hystrix组件控制。
我们启动app-cargo-list微服务,并且停止app-cargo微服务,访问http://localhost:8095/cargoList/123,发现Hystrix依然能够正常工作。我们的目标实现了!

本文引用了Feign简介与简单应用中的部分内容
引用原文作者为 cakincqm
如有侵权,请联系我处理

发布了6 篇原创文章 · 获赞 0 · 访问量 170
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览