什么是 Feign?
与 Ribbon ⼀样,Feign 也是由 Netflix 提供的,Feign 是⼀个声明式、模版化的 Web Service 客户端, 它简化了开发者编写 Web 服务客户端的操作,开发者可以通过简单的接⼝和注解来调⽤ HTTP API, Spring Cloud Feign,它整合了 Ribbon 和 Hystrix,具有可插拔、基于注解、负载均衡、服务熔断等⼀ 系列便捷功能。 相⽐较于 Ribbon + RestTemplate 的⽅式,Feign ⼤⼤简化了代码的开发,Feign ⽀持多种注解,包括 Feign 注解、JAX-RS 注解、Spring MVC 注解等,Spring Cloud 对 Feing 进⾏了优化,整合了 Ribbon 和 Eureka,从⽽让 Feign 的使⽤更加⽅便。
Ribbon 和 Feign 的区别
Ribbon 是⼀个通⽤的 HTTP 客户端⼯具,Feign 是基于 Ribbon 实现的。
Feign 的特点
1、Feign 是⼀个声明式的 Web Service 客户端。
2、⽀持 Feign 注解、Spring MVC 注解、JAX-RS 注解。
3、Feign 基于 Ribbon 实现,使⽤起来更加简单。
4、Feign 集成了 Hystrix,具备服务熔断的功能。
0. 项目搭建(在原来的基础上进行项目的创建)
填写 ? 的项目创建信息
然后点击 next ?,选择 ? 的可选项
然后点击 next,再点击 Finish 键 完成项目的创建 ?
1. 项目配置
将 application.properties 通过快捷键 alt + shift + r 修改为 application.yml,并在其中填写下面的配置信息 ?
server:
port: 8050
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
启动类设置,打开 mr.s.feign 目录下的 SpringFeignApplication 启动类 ?
package mr.s.feign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class SpringFeignApplication {
public static void main(String[] args) {
SpringApplication.run(SpringFeignApplication.class, args);
}
}
2. 代码编写
- 实体类编写
在 mr.s.feign 下创建 entity 包,并在包内创建 Student 实体类 ?
package mr.s.feign.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private long id;
private String name;
private int age;
}
- 创建声明式接口
在 mr.s.feign 下创建 repository 包,并在其中创建 FeignProviderClient 接口 ?,这个代码有点小问题,fallback 会有问题,等到将下面的容错类创建了,就好了!!!
package mr.s.feign.repository;
import mr.s.feign.entity.Student;
import mr.s.feign.error.FeignError;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Collection;
@FeignClient(value = "provider",fallback = FeignError.class)
public interface FeignProviderClient {
@GetMapping("/student/findAll")
public Collection<Student> findAll();
@GetMapping("/student/index")
public String index();
}
- 为声明式接口写熔断类
在 mr.s.feign 包下创建 impl 包,并在该包下创建 FeignError 类 ?
package mr.s.feign.error;
import mr.s.feign.entity.Student;
import mr.s.feign.repository.FeignProviderClient;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class FeignError implements FeignProviderClient {
@Override
public Collection<Student> findAll() {
return null;
}
@Override
public String index() {
return "服务器维护中......";
}
}
- 编写控制器
在 mr.s.feign 下创建 controller 包,并在该包下创建 FeignHandler 控制器类 ?
package mr.s.feign.controller;
import mr.s.feign.entity.Student;
import mr.s.feign.repository.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
@RestController
@RequestMapping("/feign")
public class FeignHandler {
@Autowired
private FeignProviderClient feignProviderClient;
@GetMapping("/findAll")
public Collection<Student> findAll(){
return feignProviderClient.findAll();
}
@GetMapping("/index")
public String index(){
return feignProviderClient.index();
}
}