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()是如何的返回对象就可以了。
网友评论