前言

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

在Spring Cloud中使用Feign

在了解了如何单独使用Feign后,再学习在Spring Cloud中使用Feign,将会有非常大的帮助。虽然Spring Cloud对Feign进行了封装,但万变不离其宗,只要了解其内在原理,使用起来就可以得心应手。在开始本节的讲解前,先准备Spring Cloud 的测试项目。测试案例主要有以下三个项目。

➢spring-feign-server: Eureka 服务器端项目,端口为8761,代码目录为codes)05)5.3\spring- feign-server。

➢spring-feign-provider: 服务提供者,代码目录为codes05.3)springfeign-provider,该项目可以在控制台中根据输入的端口号启动多个实例,启动8080与8081这两个端口,该项目提供以下两个REST服务。

●第一个地址为/person/ {personld)的服务,请求后返回Person 实例,Person的message属性为HTTP请求的URL。

●第二个地址为hello的服务,返回“Hello World"字符串。

➢spring-feign-invoker: 服务调用者项目,对外端口为9000,代码目录为codes(05\5.3\spring feign-invoker,本节的例子主要在该项目下使用Feign。

Spring Cloud整合Feign

为服务调用者( spring feign-ivoker)的pom.xml文件加入以下依赖:

org. spr ingf ramework. cloud

spr ing-cloud-starter-feign

在服务调用者的启动类中,打开Feign开关,请见代码清单5-18。

代码清单5-18;

codes(0515.3lspring-feign-invokerlsrclmainjavalorglcrazyiticloudInvokerApplication.java

aSpringBootApplication

BEnableEurekaclient

eEnableFeignClients

public class InvokerApplication {

public static void main(Stringll args) (

SpringApplicat ion.run (InvokerApplication.class,args);

接下来,编写客户端接口,与直接使用Feign类似,代码清单5-19所示为服务端接口。

代码清单5-19:

codes)0515.3spring-feign-invokerisrclmainjavalrg’crazyitcloud\PersonClient.java

aFeignClient (“spring-feign-provider”) //声明调用的服务名称

public interface Personclient {

CRequestMapping (method = RequestMethod.GET, value= “/he1lo”)

String hello();

与单独使用Feign 不同的是,接口使用了@FeignClient注解来修饰,并且声明了需要

调用的服务名称,本例的服务提供者名称为spring-feign-provider. 另外,接口方法使用了

@RequestMapping来修饰,根据5.2.7节的介绍可知,通过编写“翻译器(Contract)", 可

以让Feign知道第三方注解的含义,Spring Cloud也提供翻译器,会将@RequcstMapping注

解的含义告知Feign,因此我们的服务接口就可以直接使用该注解。

除了方法的@RequestMapping注解外,默认还支持@RequestParam. @RequestHeader.

@PathVariable这3个参数注解,也就是说,在定义方法时,可以使用以下方式定义参数:

@RequestMapping (method州RequestMethod. GET, value = “/he11o/ (name)”)

String hello (aPathVariable(“name”) String name);

需要注意的是,使用了SpringCloud的“翻译器”后,将不能再使用Feign的默认注解。

接下来,在控制器中调用接口方法,请见代码清单5-20。

代码清单5-20:

codes\0515
3Ispring-feign-invoke’srcimainjavalorgcrazitclocdnvokorCorolriava

@RestController

@Configuration

public class InvokerController {

QAutowired

private PersonClient personclient;

@RequestMapping (value = “/invokeHello”, method= RequestMethod.GET)

public string invokeHellol) {

return personClient. hello();

在控制器中,为其注入了PersonClient的Bean,不难看出,客户端实例的创建及维护,

Spring容器都帮我们实现了。查看本例的效果,请按以下步骤操作:

➢启动Eureka服务器( spring feign-server)。

➢启动两个服务提供者(spring feign-provider),在控制台中分别输入8080与8081端口。

➢启动一个服务调用者(spring feign-invoker),端口为9000。

➢在浏览器中输入htt:c/host,9000/inkelo可以看到服务提供者的hello服务被调用。

默认配置

SpringCloud为Feign的使用提供了各种默认属性,例如前面讲到的注解翻译器(Contract)、Feign 客户端。默认情况下,Spring 将会为Feign的属性提供以下的Bean。

➢解码器(Decoder) : Bean 名称为feignDecoder, ResponseEntityDecoder 类。

➢编码器(Encoder) : Bean 名称为feignEncoder, SpringEncoder 类。

➢日志(Logger) : Bean名称为feignLogger, SIf4jI ogger类。

➢注解翻译器(Contract) : Bean 名称为feignContract, SpringMveContract 类。

➢Feign 实例的创建者(Feign. Builder) : Bean名称为feignBuider, HystrixFeign. Builder类。Hystrix 框架将在后面章节中讲述。

➢Feign 客户端(Client) : Bean 名称为feignClient, LoadBalancerFeignClient 类。一般情况下,Spring 提供的这些Bean已经足够我们使用。

5.3.4 自定义配置

如果需要使用自已提供的Feign实现,可以在Spring的配置类中返回对应的Bean,下

面自定义一个简单的注解翻译器,代码清单5-22是一一个配置类。

代码清单52

s151-3rplsgn-fgigninovorerrainivalagrgyayitcloudocontractMtyCofg java

gConfiguration

public class MyConfig {

返回一个自定义的注解翻译器

/

aBean

public Contract feignContract() 1

return new MyContract();

配置类中返回了一个MyContract实例,MyContract 是我们自定义的“翻译器”,实现请见代码清单5-23。

代码清单5-23:

codsl53-siin-ieigivovoersrcainijaoglgcrazytloudcontractMyContractjava

自定义Contract

@author杨恩雄

public class MyContract extends Spr ingMvcContract

用于处理方法级的注解

protected void processAnnotat ionOnMe thod (MethodMetadata data,

Annotation annotation, Method method) (

//调用父类的方法,让其支持@RequestMapping注解

super .procea sAnnotationOnMethod (data, annotation, method);

1/是MyUrl注解才进行处理

if (MyUrl,class . isInstance (annotation))

//获取注解的实例

MyUrl myUrIAnn = method. getAnnotation (MyUr1.class);

11获取配置的HTTP方法

String httpMethod - myUrlAnn. method();

//获取服务的url

String url- myUr1Ann.ur10;

//将值设置到模板中

data.cemplate () .method (httpMethod) ;

data.template() append(url);

在前面的章节中,我们也实现过自定义的Contract,与前面实现的Contract不同的是,本例的MyContract继承了SpringMvcContract,在重写poesotatinOonMethordo方法时,调用了父类的processAnnotationOnMethod.简单点说,我们实现的这个Contract, 除了支持Spring的注解外,还支持我们自定义的@MyUrl注解。@MyUrl注解与前面章节中介绍的一致,请见代码清单5-24。

代码清单5-24:

cods0515./sping-geigninvoversrcrmainjavalorglcrayiticlodldcontrartryUrijava

@Target (METHOD)

@Retention (RUNTIME)

publlc einterface MyUrl (临

//定义url与method属性

String url();

String method();

可选配置

Spring 为这些配置提供了默认的Bean。除了这些配置外,还有如下的配置,Spring 并没有提供默认的Bean。

➢Logger.Level: 接口日志的记录级别,相当于调用了Feign.Builder 的logLevel方法,

➢Retryer: 重试处理器,相当于调用了Feign.Builder 的retryer方法。

➢ErrorDecoder: 异常解码器,相当于调用了Feign. Builder的errorDecoder 方法。

➢Request.Options: 设置请求的配置项,相当于调用了Feign Builder的options方法。

➢Collection: 设置请求拦截器,相当于调用了Feign.Builder 的

requestInterceptors方法。

➢SetterFactory: 该配置与Hystrix框架相关,将在后面章节详细讲述。

以上的配置,如果没有提供对应的Bean,则不会被设置。在此需要注意的是请求拦截器,由于可以设置多个请求拦截器,在创建Bean 时也可以创建多个,返回类型需要为RequestInterceptor或者实现类。要设置多个请求拦截器。

压缩配置

Feign支持对请求和响应进行压缩处理,默认使用GZIP进行压缩,压缩操作在Feign

的请求拦截器中实现。可以在配置文件中加入以下配置。

➢figncoresonrcquest. enabled:设置为true开启请求压缩。

➢figncompesson.response. enabled:设置为true开启响应压缩。

➢figncoreson.requestmimne types:数据类型列表,默认值为textxml, aplcatinxoml,

application/json。

➢fig.compessoneguestsmin-repuest-size: 设置请求内容的最小阈值,默认值为2048。