1. 程式人生 > >微服務通訊之feign的配置隔離

微服務通訊之feign的配置隔離

### 前言 由上文我們知道針對某一個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 (M