美文网首页
feignClient的实现原理(1)

feignClient的实现原理(1)

作者: 牧羊人刘俏 | 来源:发表于2019-11-21 16:15 被阅读0次

    1 如何的使用feignClient
    如要使用feignClient,必须开启对feignClient的支持,如在启动类加上配置如下

    @SpringBootApplication
    @EnableFeignClients
    public class CrmApplication {
       public static void main(String[] args) {
         
           SpringApplication.run(CrmApplication.class, args);
       }
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    

    如上 feignClient 只能配置在类上面,且可以在运行时通过反射拿到注解信息。简单的说下clients属性的用法。
    clients
    设置由@FeignClient注解修饰的类列表。如果clients不是空数组,则不通过类路径自动扫描功能来加载FeignClient。
    如下

    @EnableFeignClients(clients = {SchedualServiceHi.class, SchedualServiceHi2.class})
    

    在EnableFeignClients的注解上面,import了另外一个bean FeignClientsRegistrar
    FeignClientsRegistrar 实现了ImportBeanDefinitionRegistrar,ImportBeanDefinitionRegistrar提供了动态注册bean的能力,等于说除了spring本身的一般的通过配置文件注册bean的流程,开放了一个hook的口子,让用户自己去注册bean。
    所有实现了该接口的类的都会被ConfigurationClassPostProcessor处理,ConfigurationClassPostProcessor实现了BeanFactoryPostProcessor接口,所以ImportBeanDefinitionRegistrar中动态注册的bean是优先于依赖其的bean初始化的,也能被aop、validator等机制处理。(后面会专门的对BeanFactoryPostProcessor进行介绍)

    在FeignClientsRegistrar中的

    @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata,
                BeanDefinitionRegistry registry) {
            registerDefaultConfiguration(metadata, registry);
            registerFeignClients(metadata, registry);
        }
    

    这个方法就是用来注册相应的bean的,调用了两个方法
    //注册默认配置
    registerDefaultConfiguration(metadata, registry);与
    //注册所有的feignClient beanDefinition
    registerFeignClients(metadata, registry);
    先看registerDefaultConfiguration(metadata, registry),此方法用来注册默认配置,如在EnableFeignClients里面配置的defaultConfiguration属性,如果配置了,就会进行加载注册,
    registerDefaultConfiguration会将其配置信息封装成一个FeignClientSpecification注册到容器中,
    该对象非常重要,包含FeignClient需要的重试策略,超时策略,日志等配置,如果某个服务没有设置,则读取默认的配置。
    接着执行registerFeignClients(metadata, registry),方法主要是扫描类路径,对所有的FeignClient生成对应的 BeanDefinition,其中又执行了
    registerClientConfiguration(registry, name,attributes.get("configuration"));
    这个方法是对每个feignClient自己配置的configuration进行注册。而
    registerFeignClient(registry, annotationMetadata, attributes);方法会将定义的feignClient注册到容器中。跟进去可以看到
    BeanDefinitionBuilder definition = BeanDefinitionBuilder
    .genericBeanDefinition(FeignClientFactoryBean.class);
    spring会将FeignClient注册成一个FeignClientFactoryBean.class,这个是最关键的,注册成了一个FactoryBean而不是普通的bean。
    上面是FeignClient的注册的过程,那什么时候实例化呢,当然是在我们getBean的时候,发现是个FeignClientFactoryBean,那spring会调用getObject()来返回一个对象。
    所以接下来我们只需要看FeignClientFactoryBean.class的getObject()是如何的返回对象就可以了。

    相关文章

      网友评论

          本文标题:feignClient的实现原理(1)

          本文链接:https://www.haomeiwen.com/subject/bbdtwctx.html