SpringCloud中的Feign服务间的调用详解
作者:卷不动躺不平的粥
一、Feign 的简介
Feign 可以帮助我们实现面向接口编程,就直接调用其他服务,简化开发。
Feign 是一个声明式的 REST 客户端,它能让 REST 调用更加简单。Feign 供了 HTTP 请求的模板,通过编写简单的接口和插入注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。
而 Feign 则会完全代理 HTTP 请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。
Spring Cloud 对 Feign 进行了封装,使其支持 SpringMVC 标准注解和 HttpMessageConverters。Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡。
二、Feign 的简单使用
2.1 导入相关依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2.2 添加 @EnableFeignClients 注解
在启动类上加 @EnableFeignClients 注解,如果你的 Feign 接口定义跟你的启动类不在同一个包名下,还需要制定扫描的包名 @EnableFeignClients(basePackages=“com.fangjia.api.client”),代码如下所示。
@EnableEurekaClient @SpringBootApplication @EnableFeignClients public class CustomerApplication { public static void main(String[] args) { SpringApplication.run(CustomerApplication.class,args); } }
2.3 创建一个接口,并且和 search 模块做映射
@FeignClient 注解:这个注解标识当前是一个 Feign 的客户端,value 属性是对应的服务名称,也就是你需要调用哪个服务中的接口。
//指定服务名称 @FeignClient("SEARCH") public interface SearchClient { //value -> 目标服务的请求路径,method -> 映射请求方式 @RequestMapping(value = "/search",method = RequestMethod.GET) public String search(); }
定义方法时直接复制接口的定义即可,当然还有另一种做法,就是将接口单独抽出来定义,然后在 Controller 中实现接口。
2.4 测试使用
定义之后可以直接通过注入 SearchClient 来调用。
@Autowired private SearchClient searchClient; @GetMapping("/customer") public String customer() { String result = searchClient.search(); return result; }
三种方式对比:
RestTemplate 方式:
String result = restTemplate.getForObject(url+"search", String.class);
RestTemplate 整合 Ribbon方式:
String result = restTemplate.getForObject("//SEARCH/search", String.class);
Feign 方式:
String result = searchClient.search();
三、Feign 的传递参数方式
3.1 Feign 的注意事项
- 如果你传递的参数,比较复杂时,默认会采用 POST 的请求方式。
- 传递单个参数时,推荐使用 @PathVariable (Restful 风格),如果传递的单个参数比较多,这里也可以采用 @RequestParam ,不要省略 value 属性。
- 传递对象信息时,统一采用 json 的方式,添加 @RequestBody 。
- Client接口必须采用 @RequestMapping 。
3.2 使用
3.2.1 给服务的提供者和消费者编写实体类
@Data @AllArgsConstructor @NoArgsConstructor public class Customer { private Integer id; private String name; private Integer age; }
3.2.2 准备服务提供者的接口
在 Search 模块中编写三个接口。
@GetMapping("/search/{id}") public Customer findById(@PathVariable Integer id){ return new Customer(id,"张三",23); } @GetMapping("/getCustomer") public Customer getCustomer(@RequestParam Integer id, @RequestParam String name){ return new Customer(id,name,23); } @PostMapping("/save") public Customer save(@RequestBody Customer customer){ return customer; }
3.2.3 在 Search 模块中映射服务提供者的接口
@FeignClient(value = "SEARCH") public interface SearchClient { @RequestMapping(value = "/search/{id}", method = RequestMethod.GET) public Customer findById(@PathVariable(value = "id") Integer id); @RequestMapping(value = "/getCustomer", method = RequestMethod.GET) public Customer getCustomer(@RequestParam(value = "id") Integer id, @RequestParam(value = "name") String name); //这里参数复杂,会自动转化成POST请求 @RequestMapping(value = "/save", method = RequestMethod.GET) public Customer save(@RequestBody Customer customer); }
四、Feign 的 Fallback
Fallback可以帮助我们在使用Feign去调用另一个服务时,如果出现了问题,走服务降级,返回一个错误的数据,避免功能因为一个服务出现问题,全部失效。
4.1 Fallback的使用
4.1.1 自定义 FeignClient 接口
创建一个POJO类,实现自定义 FeignClient 接口
@Component public class SearchClientFallBack implements SearchClient { @Override public String search() { return "search出现问题了!!!"; } @Override public Customer findById(Integer id) { return null; } @Override public Customer getCustomer(Integer id, String name) { return null; } @Override public Customer save(Customer customer) { return null; } }
4.1.2 指定自定义的POJO类
在 FeignClient 接口中,通过 @FeignClient 的 fallback 属性指定自定义的POJO类。
@FeignClient(value = "SEARCH",fallback = SearchClientFallBack.class) public interface SearchClient { ......... }
4.1.3 修改配置文件
# fallback feign: hystrix: enabled: true
4.2 遇到的问题(FallBackFactory)
当 Search 模块出现问题时,错误的信息会返回给前端,但是服务的调用者无法知道具体的错误信息是什么,通过 FallBackFactory 的方式去解决这个问题。
4.2.1 创建 POJO 类实现 FallBackFactory
- 创建一个类实现 FallbackFactory ,并在泛型中指定自定义的 FeignClient 。
- 注入自定义的 Fallback 。
- 在重写的方法中返回自定义的 Fallback 。
@Component public class SearchClientFallBackFactory implements FallbackFactory<SearchClient> { //注入Fallback @Autowired private SearchClientFallBack searchClientFallBack; @Override public SearchClient create(Throwable throwable) { throwable.printStackTrace(); return searchClientFallBack; } }
4.2.2 修改 FeignClient 中 @FeignClient 的属性
在 @FeignClient 的 fallbackFactory 属性中指定自定义的 fallbackFactory 。
@FeignClient(value = "SEARCH", /*fallback = SearchClientFallBack.class*/ fallbackFactory = SearchClientFallBackFactory.class ) public interface SearchClient { ......... }
到此这篇关于SpringCloud中的Feign服务间的调用详解的文章就介绍到这了,更多相关SpringCloud的Feign内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!