组件-Feign

197 阅读2分钟

Feign 介绍

Feign 是 http 请求的轻量级客户端的组件框架,基于 restFul 风格,对 httpClient 进行了封装,达到简单实用这样效果。
内部即使是借助JDK的动态代理实现。
spring cloud 对 Feign 进行了封装,实用起来更方便。

spring cloud feign 实用姿势

1、spring boot 启动类上加上 @EnableFeignClients 注解。 maven 依赖如下 :

 <!-- sping cloud 整合 feign 的 maven 依赖包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>

2、对要调用的远程http服务,进行接口定义,如下

// 定义远程接口服务 feign 方式
@FeignClient( name="服务提供方名称",url="${api.github.host}")
public interface CommentServer{

    @PostMapping("/goods/comment")
    int submit(Comment c);// 提交评论

}


3、像使用本地的spring ioc 中的 bean一样直接使用

//使用 CommentServer
@Service(value="goodsAgt")
public GoodsAgtImpl implement GoodsAgt{

    @Autowired
    private CommentServer cs
    
    public void comment(Comment c){
    
       cs.submit(c);
    }
}

sping cloud feign 原理

参考上述的例子,在 GoodsAgtImpl 中,直接使用 @Autowired 方式依赖到 CommentServer 。我们知道 java 中接口是不可以实例化的,如何能这么玩?
借助了jdk的动态代理(InvocationHandler),生成了动态代理类。在动态代理中的,封装了http请求,调用了远程的CommentServer#submit 服务。

spring cloud feign 启动和调用远程过程如下 :

1-1-1-1-feign-调用过程.png

1、spring boot 项目启动时候要装在feign组件,这个和spring boot 其他自动装配一样 在 spring.factories 中。feign的自动装配类是@FeignAutoConfiguration ,启动时候回注册 FeignContext ,内部是为每个feignclient 创建一个 spring ioc 容器

springCloud 工程启动时候,执行spingCloud的自动装配,springCloud 整合 feign 的自动装配位,如下图:

1-1-1-1-springCloud-feign-自动装配.png

2、feign 启动类注解 @EnableFeignClients ,会启动feign . @EnableFeignClients 源码如下:

package org.springframework.cloud.netflix.feign;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({FeignClientsRegistrar.class})  // 这里是核心,FeignClientsRegistrar 实现了 ImportBeanDefinitionRegistrar 接口
public @interface EnableFeignClients {
    String[] value() default {};

    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<?>[] defaultConfiguration() default {};

    Class<?>[] clients() default {};
}

3、spring boot 项目启动时候 会扫描标记了@FeignClient 注解的接口,会把这些接口,然后通过jdk 的动态代理生成代理类,最后注册到spring IOC 容器中。

4、调用远程的服务,从spring IOC 容器中拿到远程服务的代理类,执行远程调用(基于http协议),调用过程有编码和解码的过程。feign 在远程调用时候赋值均衡是使用了ribbon 组件,基于客户端的负载均衡 。

5、远程调用的结果

参考 : 1、 cloud.spring.io/spring-clou…