FeignClient使用
在使用Spring Cloud开发微服务应用时中,各个微服务服务提供者都是以HTTP接口的形式对外提供服务,因此服务消费者在调用服务提供者时,通过HTTP Client的方式访问。当然我们可以使用JDK原生的`URLConnection`、`Apache的Http Client`、`Netty的异步HTTP Client`, Spring的`RestTemplate`去实现服务间的调用。Spring Cloud对Fegin进行了增强,使Fegin支持了Spring MVC的注解,并整合了Ribbon和Eureka,从而让Fegin的使用更加方便(在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验)。
一、FeignClient工作原理
总结来说,Feign的源码实现的过程如下:
- 首先通过@EnableFeignCleints注解开启FeignCleint
- 根据Feign的规则实现接口,并加@FeignCleint注解
- 程序启动后,会进行包扫描,扫描所有的@ FeignCleint的注解的类,并将这些信息注入到ioc容器中
- 当接口的方法被调用,通过jdk的代理,来生成具体的RequesTemplate
- RequesTemplate在生成Request
- Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp
- 最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡
工作原理参见:https://zhuanlan.zhihu.com/p/28593019
二、示例
FeignClient相当于Spring Cloud中的RPC,使用示例如下:
(1)Eureka-Server注册中心
application.yml配置如下:
#application.yml server: port: 1111 spring: application: name:eureka-server eureka: client: register-with-eureka: false fetch-registry: false server-url: defaultZone: http://localhost:${server.port}/eureka/
EurekaServerApplication配置如下:
@EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class,args) } }
(2)Eureka-Producer配置
定义远程服务HelloController
@RestController public class HelloController { @GetMapping("/hello") public String xxx(@RequstParam String name) { return "hello" + name + ", I'm eureka producer service!"; } }
Eureka-Client中application.yml配置
server: port: 1112 spring: application: name: eureka-producer eureka: client: server-url: defaultZone: http://localhost:1111/eureka/
EurekaProducerApplication
@EnableDiscoveryClient @SpringBootApplication public class EurekaProducerApplication { public static void main(String[] args) { SpringApplication.run(EurekaProducerApplication.class,args) } }
(3)Eureka-Consumer配置
Controller层服务配置如下:
@RestController public class ConsumerController { @Autowired HelloRemote helloRemote; @RequestMapping("/hello/{name}") public String hello(@PathVariable("name") String name) { return helloRemote.hello(name); } }
HelloRemote配置
@FeignClient(name="eureka-producer") public interface HelloRemote { @RequstMapping("/hello") String hello(@RequstParam(value="name") String name); }
application.yml文件配置
server: port: 1113 spring: application: name: eureka-consumer eureka: client: server-url: defaultZone: http://localhost:1111/eureka
EurekaConsumerApplication配置
@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class EurekaConsumerApplication { public static void main(String[] args) { SpringApplication.run(EurekaConsumerApplication.class,args) } }
参见:http://www.voidcn.com/article/p-kodllxvn-hr.html
http://xujin.org/sc/sc-fegin01/
http://www.cnblogs.com/jalja/p/7011439.html