一、OpenFegin 介绍
Feign是一个声明性的Web服务客户端。 它使编写Web服务客户端变得更容易。 要使用Feign,请创建一个界面并对其进行注释。 它具有可插入的注释支持,包括Feign注释和JAX-RS注释。 Feign还支持可插拔编码器和解码器。 Spring Cloud增加了对Spring MVC注释的支持,并使用了Spring Web中默认使用的相同HttpMessageConverters。 Spring Cloud集成了Ribbon和Eureka,在使用Feign时提供负载均衡的http客户端。
二、将OpenFegin应用到项目中
添加依赖到项目中:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
新建一个FeignClient类
1 package com.zwjk.cloud.fegin; 2 3 import com.zwjk.cloud.entity.User; 4 import org.springframework.cloud.openfeign.FeignClient; 5 import org.springframework.web.bind.annotation.GetMapping; 6 import org.springframework.web.bind.annotation.PathVariable; 7 import org.springframework.web.bind.annotation.PostMapping; 8 import org.springframework.web.bind.annotation.RequestBody; 9 10 /** 11 * @author : Jixiaohu 12 * @Date : 2019-04-12. 13 * @Time : 16:50. 14 * @Description : 15 */ 16 @FeignClient("microservice-provider-user") 17 public interface UserFeignClient { 18 //@PathVariable得设置value 19 @GetMapping("/simple/{id}") 20 User findById(@PathVariable("id") Long id); //@PathVariable得设置value 21 22 @PostMapping("/user") 23 User postUser(@RequestBody User user); 24 25 // 该请求不会成功,只要参数是复杂对象,即使指定了是GET方法,feign依然会以POST方法进行发送请求。 26 @GetMapping("/get-user") 27 User getUser(User user); 28 }
在movie的controller中。使用feign调用user微服务提供的接口
1 package com.zwjk.cloud.controller; 2 3 import com.zwjk.cloud.entity.User; 4 import com.zwjk.cloud.fegin.UserFeignClient; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.annotation.Value; 7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.RestController; 10 import org.springframework.web.client.RestTemplate; 11 12 /** 13 * @author : Jixiaohu 14 * @Date : 2019-04-11. 15 * @Time : 9:38. 16 * @Description : 17 */ 18 @RestController 19 public class MovieController { 20 21 @Autowired 22 private UserFeignClient userFeignClient; 23 24 @GetMapping("/movie/{id}") 25 public User findById(@PathVariable Long id) { 26 return this.userFeignClient.findById(id); 27 } 28 29 @GetMapping("/test") 30 public User testPost(User user) { 31 return this.userFeignClient.postUser(user); 32 } 33 34 @GetMapping("/test-get") 35 public User testGet(User user) { 36 return this.userFeignClient.getUser(user); 37 } 38 39 40 }
1 package com.zwjk.cloud.controller; 2 3 import com.zwjk.cloud.entity.User; 4 import com.zwjk.cloud.repository.UserRepository; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.web.bind.annotation.*; 7 8 /** 9 * @author : Jixiaohu 10 * @Date : 2019-04-11. 11 * @Time : 9:08. 12 * @Description : 13 */ 14 @RestController 15 public class UserController { 16 17 @Autowired 18 private UserRepository userRepository; 19 20 @GetMapping("/simple/{id}") 21 public User findById(@PathVariable Long id) { 22 return this.userRepository.getUserById(id); 23 } 24 25 @PostMapping("/user") 26 public User postUser(@RequestBody User user) { 27 return user; 28 } 29 30 // 该请求不会成功 31 @GetMapping("/get-user") 32 public User getUser(User user) { 33 return user; 34 } 35 }
访问地址:http://localhost:8010/movie/1
查看结果返回:
这边需要注意的是,在feignClient中,注释表明的说明。
这里,就简单实现了使用feignClient调用服务接口。
下面看一下,如何复写默认的FeignClientsConfihuration
https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.1.0.RELEASE/single/spring-cloud-openfeign.html#spring-cloud-feign-overriding-defaults
官方文档中,有这样的说明
Spring Cloud的Feign支持的核心概念是指定客户端的概念。 每个feign客户端都是一组组件的一部分,这些组件一起工作以按需联系远程服务器,并且该集合具有一个名称,您可以使用@FeignClient注释将其作为应用程序开发人员提供。 Spring Cloud使用FeignClientsConfiguration按需为每个命名客户端创建一个新的集合作为ApplicationContext。 这包含(除其他外)feign.Decoder,feign.Encoder和feign.Contract。 可以使用@FeignClient批注的contextId属性覆盖该集合的名称。
Spring Cloud允许您通过使用@FeignClient声明其他配置(在FeignClientsConfiguration之上)来完全控制假装客户端。 例:
@FeignClient(name = "stores", configuration = FooConfiguration.class) public interface StoreClient { //.. }
这边有个警告,跟ribbon的自定义配置一样,自定义的配置,需要放在扫描包的外部,查看一下怎么写,https://github.com/OpenFeign/feign
下面看一下代码:
1 package com.zwjk.cloud.fegin; 2 3 import com.zwjk.cloud.entity.User; 4 import com.zwjk.config.UserConfiguration; 5 import feign.Param; 6 import feign.RequestLine; 7 import org.springframework.cloud.openfeign.FeignClient; 8 9 /** 10 * @author : Jixiaohu 11 * @Date : 2019-04-12. 12 * @Time : 16:50. 13 * @Description : 14 */ 15 @FeignClient(name = "microservice-provider-user", configuration = UserConfiguration.class) 16 public interface UserFeignClient { 17 //@PathVariable得设置value 18 @RequestLine("GET /simple/{id}") 19 User findById(@Param("id") Long id); //@PathVariable得设置value 20 21 }
1 package com.zwjk.config; 2 3 import feign.Contract; 4 import feign.Logger; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 8 /** 9 * @author : Jixiaohu 10 * @Date : 2019-04-13. 11 * @Time : 10:20. 12 * @Description : 13 */ 14 @Configuration 15 public class UserConfiguration { 16 17 @Bean 18 public Contract feignContract() { 19 return new feign.Contract.Default(); 20 } 21 22 @Bean 23 Logger.Level feignLoggerLevel() { 24 return Logger.Level.FULL; 25 } 26 }
其他的不需要修改,下面看一下目录结构:
UserConfiguretion需要放在外面。