简单介绍
Feign 是一个声明式的 Web Service 客户端。它的出现使开发 Web Service 客户端变得很简单。使用 Feign 只需要创建一个接口加上对应的注解,比如:@FeignClient 注解。 Feign 有可插拔的注解,包括 Feign 注解和 AX-RS 注解。Feign 也支持编码器和解码器,Spring Cloud Open Feign 对 Feign 进行增强支持 Spring Mvc 注解,可以像 Spring Web 一样使用 HttpMessageConverters 等。
Feign 是一种声明式、模板化的 HTTP 客户端。在 Spring Cloud 中使用 Feign,可以做到使用 HTTP 请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问 HTTP 请求。接下来介绍一下 Feign 的特性,具体如下:
可插拔的注解支持,包括 Feign 注解和AX-RS注解。
支持可插拔的 HTTP 编码器和解码器。
支持 Hystrix 和它的 Fallback。
支持 Ribbon 的负载均衡。
支持 HTTP 请求和响应的压缩。Feign 是一个声明式的 WebService 客户端,它的目的就是让 Web Service 调用更加简单。它整合了 Ribbon 和 Hystrix,从而不需要开发者针对 Feign 对其进行整合。Feign 还提供了 HTTP 请求的模板,通过编写简单的接口和注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。Feign 会完全代理 HTTP 的请求,在使用过程中我们只需要依赖注入 Bean,然后调用对应的方法传递参数即可。
feign入门案列
在上次博文中介绍了Ribbon,这次简单介绍一下Feign的入门案列
搭建服务和注册中心参考:Springcloud之Ribbon中服务于注册中心搭建
1 application.yml配置文件:
server:
port: 8083
spring:
application:
name: feign-demo
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
feign:
hystrix:
enabled: true
2 pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gj</groupId>
<artifactId>cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>feign</name>
<description>Feign的使用</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>cn.gjing</groupId>
<artifactId>tools-starter-feign</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3 启动类添加注解@EnableFeignClients@EnableEurekaClient@EnableCircuitBreaker
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
4 编写FeignTestService
name属性表示调用服务名字,fallback表示调用失败返回结果的处理类
@FeignClient(name = "demo",fallback = FeignTestFallbackImpl.class)
public interface FeignTestService {
@RequestMapping(value = "/test", method = RequestMethod.GET)
Map<String,Object> test();
@RequestMapping(value = "test4", method = RequestMethod.GET)
String test2(@RequestParam("param1") String param1);
@RequestMapping(value = "/test3", method = RequestMethod.POST)
Integer test3(@RequestParam("id") Integer id);
}
5 编写调用服务失败fallback类FeignTestServiceImpl
@Component
public class FeignTestFallbackImpl implements FeignTestService {
@Override
public Map<String, Object> test() {
// TODO: 2019/7/3 这里就实现回退后的处理咯
Map<String,Object> map = new HashMap<>(16);
map.put("code", "回退了");
return map;
}
@Override
public String test2(String param1) {
return null;
}
@Override
public Integer test3(Integer id) {
return null;
}
}
6 编写FeignTestController
@RestController
public class FeignTestController {
@Resource
private FeignTestService feignTestService;
@GetMapping("/test")
public String test() {
return feignTestService.test().toString();
}
@GetMapping("/test2")
public ResponseEntity test2() {
String test2 = feignTestService.test2("你好");
return ResponseEntity.ok(test2);
}
@GetMapping("/test3")
public ResponseEntity test3() {
Integer test3 = feignTestService.test3(1);
return ResponseEntity.ok(test3);
}
}
测试
在demo服务项目工程中Controller添加:
@GetMapping("/test")
public String testFegin() {
return "success fegin";
}
1 启动注册中心 demo服务 feign服务 访问localhost:8083/test
发现调用demo服务失败了然后调用fallback处理类,原因出在哪里,想思考的同学可以停留一下再往后面看
下面来解决这个问题:在demo服务中/test路径访问返回的是一个String类型,改为Map类型就可以了
简单总结
Fegin相比Ribbon调用服务方式显得更加简单,但是没有那么灵活。因为Ribbon自己构建http请求,显得复杂,但是灵活,看别人写的调用服务路径也不是那么好理解,鬼知道调用的什么。
Ribbon调用服务参考:RIBBON