Feign
是一个声明式 Web
服务客户端。它使编写 Web
服务客户端更容易。要使用 Feign
,请创建一个接口并对其进行注释。它具有可插入的注释支持,包括 Feign
注释和 JAX-RS
注释。Feign
还支持可插拔的编码器和解码器。Spring Cloud
添加了对Spring MVC
注释的支持,并支持使用HttpMessageConvertersSpring Web
中默认使用的注释。Spring Cloud
集成了 Ribbon
和 Eureka
,以及 Spring Cloud LoadBalancer
,在使用 Feign
时提供负载均衡的http
客户端。
Feign
旨在使编写Java Http
客户端变得更容易。
前面在使用Ribbon+ RestTemplate
时,利用RestT emplate
对http
请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多 处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以, Feign
在此基础上做了进一步封装, 由他来帮助我们定义和实现依赖服务接口的定义。在Feign
的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao
接口上面标注Mapper注解现在是一个微服务接口上面标注一个Feign
注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon
时,自动封装服务调用客户端的开发量。
Feign
集成了Ribbon
,利用Ribbon
维护了Payment
的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon
不同的是,通过feign
只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloudartifactId>
<groupId>org.examplegroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>cloud-consumer-feign-order8080artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.examplegroupId>
<artifactId>SpringCloudartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.examplegroupId>
<artifactId>Cloud-api-commonsartifactId>
<version>1.0-SNAPSHOTversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.examplegroupId>
<artifactId>Cloud-api-commonsartifactId>
<version>1.0-SNAPSHOTversion>
<scope>compilescope>
dependency>
dependencies>
project>
server:
port: 8080
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
package com.example.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain8080 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain8080.class, args);
}
}
package com.example.springcloud.service;
import com.example.springcloud.entities.CommonResult;
import com.example.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
package com.example.springcloud.controller;
import com.example.springcloud.entities.CommonResult;
import com.example.springcloud.entities.Payment;
import com.example.springcloud.service.PaymentFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
return paymentFeignService.getPaymentById(id);
}
}