一、openfeign的自动配置
所有文章
https://www.cnblogs.com/lay2017/p/11908715.html
正文
openfeign是一种声明式的webservice客户端调用框架。你只需要声明接口和一些简单的注解,就能像使用普通的Bean一样调用远程服务。本文将了解一下openfeign自动配置相关的东西,看看都做了哪些东西。
@EnableFeignClients开启openfeign
首先,我们从@EnableFeignClients这个开关注解开始了解。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients { // ...省略配置
}
这个注解导入了一个类FeignClientsRegistrar,这个类实现了ImportBeanDefinitionRegistrar接口,该接口用于向Bean容器种注册添加BeanDefinition。
为此,我们跟进FeignClientsRegistrar的registerBeanDefinitions方法,看看它注册了哪些东西。
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 注册默认配置
registerDefaultConfiguration(metadata, registry);
// 注册FeignClient接口的Bean
registerFeignClients(metadata, registry);
}
1、registerDefaultConfiguration方法将会读取@EnableFeignClients接口的属性,如果存在自定义配置类那么就会被注册到容器中。
2、registerFeignClients则会扫描所有注解了@FeignClient的接口,然后像spring本地Bean一样地注册到容器中。
扫描@FeignClient注解的接口
我们重点关注registerFeignClients方法,跟进代码
public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
ClassPathScanningCandidateComponentProvider scanner = getScanner();
scanner.setResourceLoader(this.resourceLoader);
Set<String> basePackages;
// 获取扫描路径
// 扫描所有路径,默认情况下扫描启动类下的路径
for (String basePackage : basePackages) {
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
// 遍历扫描到的FeignClient的Bean
for (BeanDefinition candidateComponent : candidateComponents) {
if (candidateComponent instanceof AnnotatedBeanDefinition) {
// verify annotated class is an interface
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
String name = getClientName(attributes);
// 注册FeignClient的配置
registerClientConfiguration(registry, name, attributes.get("configuration"));
// 注册FeignClient
registerFeignClient(registry, annotationMetadata, attributes);
}
}
}
}
方法中的核心逻辑就是扫描类路径,获取BeanDefinition,然后遍历进行注册。
跟进registerFeignClient注册方法
private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
String className = annotationMetadata.getClassName();
// 生成FeignClientFactoryBean这个BeanDefinition构造器
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
// 将@FeignClient的注解属性添加到builder
definition.addPropertyValue("url", getUrl(attributes));
definition.addPropertyValue("path", getPath(attributes));
String name = getName(attributes);
definition.addPropertyValue("name", name);
String contextId = getContextId(attributes);
definition.addPropertyValue("contextId", contextId);
definition.addPropertyValue("type", className);
definition.addPropertyValue("decode404", attributes.get("decode404"));
definition.addPropertyValue("fallback", attributes.get("fallback"));
definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
String alias = contextId + "FeignClient";
AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
// ...
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[] { alias });
// 注册
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
}
这里值得注意的是genericBeanDefinition方法最终生成的其实是FeignClientFactoryBean,registerBeanDefinition方法注册进容器的也是FeignClientFactoryBean。
而FeignClientFactoryBean向上直接实现了FactoryBean接口

FactoryBean接口是spring开放出来的,用于自定义Bean的生成过程。也就是说,spring将会通过调用FeignClientFactoryBean的getObject来获取@FeignClient注解的接口对应的Bean对象。
总结
openfeign的自动配置过程逻辑相对比较简单,就是扫描了一下@FeignClient注解的接口,然后生成FeignClientFactoryBean的BeanDefinition给注册到容器当中。而具体的Bean对象,将会通过调用FeignClientFactoryBean的getObject方法来获取。
一、openfeign的自动配置的更多相关文章
- 企业IT管理员IE11升级指南【15】—— 代理自动配置脚本
企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...
- 学记:为spring boot写一个自动配置
spring boot遵循"约定优于配置"的原则,使用annotation对一些常规的配置项做默认配置,减少或不使用xml配置,让你的项目快速运行起来.spring boot的神奇 ...
- 网络连接详细信息出现两个自动配置ipv4地址
问题:网络连接详细信息出现两个自动配置ipv4地址,一个是有效地址,一个是无效地址. 解决办法:先将本地连接ip设置成自动获取,然后点击开始——>运行——>输入cmd,回车,进入命令行界面 ...
- python环境变量自动配置脚本(setx使用)
前言 setx不是windows系统自带的工具,需要到微软官网下载,但是有的系统也会自带.(是官方提供的,可放心食用) set和setx都可以用来配置环境变量.他们的不同点在于,set只是临时的修改环 ...
- 使用脚本自动配置matlab安装libsvm和随机森林工具箱
前言 支持向量机(SVM)和随机森林 都是用于分类的机器学习算法. 这里我需要对网上的工具箱在matlab中进行配置. 效果演示: 1.双击运行“自动配置.bat” 2.matlab会自动启动,手动配 ...
- 转-IE浏览器自动配置代理脚本-Proxy.PAC文件及PAC相关语法
用笔记本上网时,往返家里和单位,因为单位是用的代理上网,家里是直接连接.因此每次都要修改IE的代理设置,虽然是个小事,但是每次都要修改总是有点烦 ,于是参考GOOGLE,写了一个自动配置代理的脚本.这 ...
- Windows下Apache服务器中自动配置二级子域名
今天我们介绍的这个办法,只需要简单修改 httpd-vhosts.conf 文件,配合 .htaccess 文件即可实现自动配置二级域名. 我们这里以 wpchina.com 为例,以下代码中的 wp ...
- [win]AD域组策略wifi自动配置
http://wenku.baidu.com/link?url=MC950wliAZNeVUJ2M6Y1VTi5faqo7kG374fyBjW57r0qyLJkBZLg5ypiql4RFywQ8q7y ...
- spring boot实战(第十三篇)自动配置原理分析
前言 spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷,本篇讲利用RabbitMQ的自动配置为例讲分析下Spring Boot中的自动配置原理. 在上一篇末尾讲述了Spring ...
随机推荐
- IDEA优化配置,提高启动和运行速度
IDEA优化配置,提高启动和运行速度 参考链接:https://blog.csdn.net/riju4713/article/details/83217013,http://www.pc0359. ...
- vue的vuex在使用...mapState 和...mapGetter报错的解决方案
from:https://blog.csdn.net/ysterling/article/details/88145765 采用mapState 和mapGetter,在页面使用时报错,这是因为bab ...
- QTableView加载数据
void VCAdmin::searchAllUser() { strID_Index = ""; if (NULL == vcManageDatabaseObj) { vc_ad ...
- 函数和宏实现打印的增强myprintf
函数和宏实现打印的增强
- 123457123456#0#-----com.tym.myNewShiZi45--前拼后广--识字tym
com.tym.myNewShiZi45--前拼后广--识字tym
- 多个wav音频文件合并(连接)成一个文件
场景:一段声音从浏览器麦克风缓冲上一段一段发给服务器,按照时间戳生成很多文件. 目的:把他们按时间顺序连到一个时间轴上. 命令如下: ffmpeg -f concat -i list.txt out. ...
- k8s中实现永久无法删除一个pod---也就是在deployment.yaml中定义副本数量
参照:https://www.cnblogs.com/effortsing/p/10486960.html 这里面的deployment.yaml对应的pod就是永久无法删除的
- [MySQL]MySQL数据库中如何查询分组后每组中的最后一条记录?
原文地址:https://codedefault.com/s/how-can-i-retrieve-the-last-record-in-each-group-mysql 问题描述 比如,在MySQL ...
- C++标准模板库Stand Template Library(STL)简介与STL string类
参考<21天学通C++>第15和16章节,在对宏和模板学习之后,开启对C++实现的标准模板类STL进行简介,同时介绍简单的string类.虽然前面对于vector.deque.list等进 ...
- EM算法概念
EM算法是一种非常经典的alternative optimizing算法.alternative optimizing的思想就是对于一个最优化问题,可以计算分为两步或者参数分为两个,就可以随机任意的选 ...