前言

由上文我们知道针对某一个Feign接口,我们可以给他设置特定的配置类。那如果现在有一个服务,我们只想对A服务配置一个拦截器拦截请求而不影响其他服务,那应该怎么做呢?

一、feign接口配置

由前面的文章我们知道了feign的代理过程以及调用过程。现在我们看一下feign都有哪些配置?

  • @FeignClient可配置属性列表
属性 值类型 含义
value string 服务名,无论是否有URL,服务名称都不能为空,它可以设置为属性值${server_name}这种形式
name string 同value
qualifier string 指定feign接口在容器中的bean实例名称(我们知道每一个feign接口最终都会向容器注入一个实例),等同于@Qualifier
url string 绝对URL或可解析主机名(协议是可选的)
decode404 boolean 是否应该解码404而不是抛出假异常
fallback class 指定一个会退类(比如发生未处理的异常后)。回退类必须实现feign接口,并注册到容器。
fallbackFactory class 为指定的外部客户机接口定义回退工厂。回退工厂必须实现FallbackFactory接口,此工厂接口返回一个feign接口对应的回滚类。回退工厂必须注册到容器。
path string 指定相对路径
primary boolean,默认true 当容器中存在同名的bean的实现,以当前代理对象的bean为主。
configuration class 当前feign接口的配置类,他会将配置类注册到当前feign对象的容器中(非应用程序的上下文环境)
  • 配置是何时被加载的

这里直接上核心代码(FeignClientsRegistrar.registerClientConfiguration)

        // name @FeignClient的name属性值
// configuration @FeignClient的class对象
private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
Object configuration) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(FeignClientSpecification.class);
builder.addConstructorArgValue(name);
builder.addConstructorArgValue(configuration);
registry.registerBeanDefinition(
name + "." + FeignClientSpecification.class.getSimpleName(),
builder.getBeanDefinition());
}

由上面的代码我们知道,他是将@FeignClient对象的configuration属性对应的配置类作为成员FeignClientSpecification的属性注入到应用上下文。那看到这里我们就会产生一个疑问:configuration对应的配置类到底什么时候被初始化呢?最终发现在为@FeignClient生成代理对象的时候,他初始化了FeignClient对应的配置。如下(NamedContextFactory.createContext):


// 在获取一个@FeignClient接口对应的代理对象前,先为其创建Context对象
protected AnnotationConfigApplicationContext createContext(String name) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
if (this.configurations.containsKey(name)) {
for (Class<?> configuration : this.configurations.get(name)
.getConfiguration()) {
// 注册配置
context.register(configuration);
}
}
for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
if (entry.getKey().startsWith("default.")) {
for (Class<?> configuration : entry.getValue().getConfiguration()) {
// 注册配置
context.register(configuration);
}
}
}
context.register(PropertyPlaceholderAutoConfiguration.class,
this.defaultConfigType);
// 为context注册环境变量
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
this.propertySourceName,
Collections.<String, Object>singletonMap(this.propertyName, name)));
if (this.parent != null) {
// Uses Environment from parent as well as beans
context.setParent(this.parent);
// jdk11 issue
// https://github.com/spring-cloud/spring-cloud-netflix/issues/3101
context.setClassLoader(this.parent.getClassLoader());
}
context.setDisplayName(generateDisplayName(name));
context.refresh();
return context;
}

显然,在为@FeignClient接口的代理对象创建了Context后,将配置初始化到了该Context。这里可以明确的是每一个@FeignClient只要name属性不一致,那么他们将拥有不同的上下文。

二、feign调用的沙箱设计思路

在现实中的sandbox,是一种儿童玩具,类如KFC中一个装满小球的容器,儿童可以在随意玩耍,起到保护儿童的作用。(也可以理解为一种安全环境)。同样在网络技术中也是一种按照安全策略限制程序行为的执行环境。在feign的调用过程中,针对不同的服务为其创建一个上下文,我们可以将这个上下文理解为sandbox。执行调用所需要的资源是从各自的沙箱环境中取。整体的职责分工如下图所示。

从中我们可以看到,我们最终调用的执行器来源是来自沙箱,而沙箱的配置可以各不相同,创建不同的Client,这给了我们决定不同的服务怎样去调用高度的自主权。也解决了文章开篇提出的问题。

三、小结

至此,feign调用暂时告一段落。由于后续要花时间做一个开源框架,文章的书写便只能告一段落了。

微服务通信之feign的配置隔离的更多相关文章

  1. 微服务通信之feign的注册、发现过程

    前言 feign 是目前微服务间通信的主流方式,是springCloud中一个非常重要的组件.他涉及到了负载均衡.限流等组件.真正意义上掌握了feign可以说就掌握了微服务. 一.feign的使用 f ...

  2. 微服务通信之feign集成负载均衡

    前言 书接上文,feign接口是如何注册到容器想必已然清楚,现在我们着重关心一个问题,feign调用服务的时候是如何抉择的?上一篇主要是从读源码的角度入手,后续将会逐步从软件构架方面进行剖析. 一.R ...

  3. 如何将 Redis 用于微服务通信的事件存储

    来源:Redislabs作者:Martin Forstner 翻译:Kevin (公众号:中间件小哥) 以我的经验,将某些应用拆分成更小的.松耦合的.可协同工作的独立逻辑业务服务会更易于构建和维护.这 ...

  4. java架构之路-(微服务专题)feign的基本使用和nacos的配置中心

    上次回归: 上次我们说了ribbon的基本使用,包括里面的内部算法,算法的细粒度配置,还有我们自己如何实现我们自己的算法,主要还是一些基本使用的知识,还不会使用ribbon的小伙伴可以回去看一下上一篇 ...

  5. 【SpringCloud构建微服务系列】Feign的使用详解

    一.简介 在微服务中,服务消费者需要请求服务生产者的接口进行消费,可以使用SpringBoot自带的RestTemplate或者HttpClient实现,但是都过于麻烦. 这时,就可以使用Feign了 ...

  6. 「 从0到1学习微服务SpringCloud 」06 统一配置中心Spring Cloud Config

    系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现 「 从0到1学习微服务S ...

  7. 微服务通信之ribbon实现原理

    前言 上一篇我们知道了feign调用实现负载均衡是通过集成ribbon实现的.也较为详细的了解到了集成的过程.现在我们看一下ribbo是如何实现负载均衡的.写到这里我尚未去阅读源代码,我在这里盲猜一下 ...

  8. SpringCloud微服务(基于Eureka+Feign+Hystrix+Zuul)

    一.搭建注册中心 1.1.创建一个cloud-service项目 1.2:POM文件依赖 1 <?xml version="1.0" encoding="UTF-8 ...

  9. Spring cloud微服务安全实战-6-11sentinel之配置持久化

    规则的持久化问题.现在的规则都是在内存里的,我们要写一些代码来编一些规则.启动以后规则在内存里了.如果你配置里面有sentinel的dashboard,有流量经过客户端的时候,它会把规则同步给Dash ...

随机推荐

  1. 异步编程新方式async/await

    一.前言 实际上对async/await并不是很陌生,早在阮大大的ES6教程里面就接触到了,但是一直处于理解并不熟练使用的状态,于是决定重新学习并且总结一下,写了这篇博文.如果文中有错误的地方还请各位 ...

  2. Redis不重启的情况下 切换持久化模式

    确保redis版本在2.2以上 [root@localhost /]# redis-server -v Redis server v=4.0.10 sha=00000000:0 malloc=jema ...

  3. Shell Scripting 笔记

    Shell Scripting Tutorial Variables in the Bourne shell do not have to be declared, as they do in lan ...

  4. Kibana详细入门教程

    Kibana详细入门教程   目录 一.Kibana是什么 二.如何安装 三.如何加载自定义索引 四.如何搜索数据 五.如何切换中文 六.如何使用控制台 七.如何使用可视化 八.如何使用仪表盘 一.K ...

  5. 【API管理 APIM】APIM集成内部VNet时,常遇见的关于自定义DNS服务问题。

    问题描述 Azure 的APIM集成虚拟网络有两种方式,外部VNET, 内部VNET. 外部VNET,要求低,可以通过APIM访问VNET中的VM等资源,不需要配置自定义DNS服务器,这种方式下,AP ...

  6. Helium文档3-WebUI自动化-click点击

    前言 click点击方法在web UI自动化中使用频率非常高,此方法就是模拟鼠标左键单击动作 click入参说明 1.首先我们来分析一下click方法的代码 click(element):   &qu ...

  7. C# Timer用法及实例讲解

    摘自:http://www.cnblogs.com/xcsn/archive/2013/05/10/3070485.html 1.C# Timer用法及实例详解 http://developer.51 ...

  8. 操作系统OS基础

    OS: Operating System 操作系统,通用目的的软件程序 主要功能:硬件驱动 进程管理 内存管理 网络管理 安全管理 文件管理OS分类:服务器OS:CentOS,Ubuntu,Windo ...

  9. Ⅰ Introduction to Reinforcement Learning

    Dictum:  To spark, often burst in hard stone. -- William Liebknecht 强化学习(Reinforcement Learning)是模仿人 ...

  10. STC 核心板 入门记

    写在开始 STC核心板,它的软件十分全面,想要什么都有,非常适合新手入门. 上一次电赛刚结束,现在反正也啥也不太会,干脆学个这个吧. 顺便写篇博客记录一下. 记录第一次烧写 周四下单,周六到货.中午拿 ...