一、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 ...
随机推荐
- PHP如何实现静态的链式调用
Db::table('**')->where('***','***')->order('***')->find('**'); 想这种应该怎么实现 public function ta ...
- Python3基础 bool True为1 False为0
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- Flutter修改应用图标及图标
应用名称是需要在 Android 和 iOS 中分别调整的:Android 是在 AndroidManifest.xml 中修改:iOS 则是在 Info.plist 中修改的: 如果需要更改应用的 ...
- Java extract amplitude array from recorded wave
转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-extract-amplitude-array-from.html Extra ...
- 简单明了的注解,读取CLASS中的注解
/***********注解声明***************/ /** * 水果名称注解 * @author peida * */ @Target(ElementType.FIELD) @Reten ...
- 基于jsplumb插件制作可拖拽、保存流程图、重绘保存后的流程图总结
1.重点参考博文 https://blog.csdn.net/j_bean/article/details/78092647 2.关键点总结 1)实现可视区域图形画满后,拖动整个画布的效果 a.最好不 ...
- Python - 在CentOS7.5系统中安装Python3
注意:以下内容均使用root用户执行操作. 1-确认信息 # uname -a Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu ...
- Linux终极shell-zsh的完美配置方案!——oh-my-zsh
Zsh 介绍 Zsh 兼容 Bash,据传说 99% 的 Bash 操作 和 Zsh 是相同的 Zsh 官网:http://www.zsh.org/ 先看下你的 Linux支持哪些 shell:cat ...
- ip网络
- 一个unsigned int 数的二进制表示中有多少个1
这是一道面试题可以用以下的一些方案.第一种是很容易想到的采用循环的方式并且与1进行位与运算,具体代码如下. 1unsigned int GetBitNumOfOne_ByLoop1(unsigned ...