openfeigin配置相关
http请求client配置
默认情况下使用使用的HttpURLConnection,这样可以使用Apache HttpClient和OkHttp。在FeignAutoConfiguration自动装配类中会进行条件装配。
@Configuration(proxyBeanMethods = false)@ConditionalOnClass(ApacheHttpClient.class)@ConditionalOnMissingBean(CloseableHttpClient.class)@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)@Conditional(HttpClient5DisabledConditions.class)protected static class HttpClientFeignConfiguration {@Bean@ConditionalOnMissingBean(HttpClientConnectionManager.class)public HttpClientConnectionManager connectionManager(ApacheHttpClientConnectionManagerFactory connectionManagerFactory,FeignHttpClientProperties httpClientProperties) {//HttpClientConnection连接信息final HttpClientConnection连接信息Manager connectionManager = connectionManagerFactory.newConnectionManager(httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(),httpClientProperties.getMaxConnectionsPerRoute(), httpClientProperties.getTimeToLive(),httpClientProperties.getTimeToLiveUnit(), this.registryBuilder);this.connectionManagerTimer.schedule(new TimerTask() {@Overridepublic void run() {connectionManager.closeExpiredConnections();}}, 30000, httpClientProperties.getConnectionTimerRepeat());return connectionManager;}@Beanpublic CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,HttpClientConnectionManager httpClientConnectionManager,FeignHttpClientProperties httpClientProperties) {RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(httpClientProperties.getConnectionTimeout()).setRedirectsEnabled(httpClientProperties.isFollowRedirects()).build();this.httpClient = httpClientFactory.createBuilder().setConnectionManager(httpClientConnectionManager).setDefaultRequestConfig(defaultRequestConfig).build();return this.httpClient;}@Bean@ConditionalOnMissingBean(Client.class)public Client feignClient(HttpClient httpClient) {return new ApacheHttpClient(httpClient);}}
开启httpclient要在配置文件中配置feign.httpclient.enabled: true,除此之外还要添加对应的jar包依赖
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>
httpclient相关的配置都被封装在FeignHttpClientProperties类中。可以配置连接超时时间,连接池信息等。
OkHttpClient连接配置信息同理,也是在自动装配类里进行条件装配。feign.okhttp.enabled要配置成true,同时添加相关依赖
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>
@FeignClient注解配置
属性 | 说明 | 示例 |
---|---|---|
name | 指定 FeignClient 的名字(在 Ribbon/Eureka/Nacos 里作为服务名使用),也是 feign.client.config.<name> 的 key | @FeignClient(name = "userservice") |
value | name 的别名(和 name 作用相同) | @FeignClient(value = "userservice") |
url | 直连模式时指定调用地址(不走服务发现) | @FeignClient(name = "user", url = "http://localhost:8080") |
path | 为所有方法统一加上路径前缀 | @FeignClient(name = "user", path = "/api/v1") |
fallback | 熔断降级时指定的回退实现类(必须实现当前接口) | @FeignClient(name = "user", fallback = UserClientFallback.class) |
fallbackFactory | 降级工厂,可以根据异常类型返回不同的回退实现 | @FeignClient(name = "user", fallbackFactory = UserClientFallbackFactory.class) |
configuration | 指定当前客户端的专属配置类(Bean 定义:日志级别、编码器、解码器、拦截器等) | @FeignClient(name = "user", configuration = UserFeignConfig.class) |
primary | 是否作为 @Primary Bean 注册到 Spring 容器,默认 true | @FeignClient(name = "user", primary = false) |
contextId | 用于区分同一个 name 下的多个 FeignClient Bean,防止冲突 | @FeignClient(name = "user", contextId = "userApiV2") |
configuration 如果不指定,默认会使用FeignClientsConfiguration中的配置。
FeignContext
Spring Boot 启动时会加载 FeignAutoConfiguration
,其中定义了一个 FeignContext
Bean。
会为每个 FeignClient 创建一个子容器,FeiginContext内部有一个Map<String, AnnotationConfigApplicationContext> contexts
来存储每个FeignClient的配置容器信息,其中key是FeignClient 的contextId或name。
在FeignClientFactoryBean中getTarget()方法创建FeignClient 代理实例时,会创建对应的context
FeiginContext.getInstance(contextId, type)方法会尝试从contexts map中获取对应的ApplicationContext,如果获取不到就证明当前FeignClient还未初始化,就会创建一个AnnotationConfigApplicationContext,放到contexts map里,然后会执行容context的初始化,Annotation类型的容器会执行注解扫描,可能会花费一定的时间,由于FeignClientFactoryBean创建的代理类时懒加载的,所以会造成当feigin接口第一次请求时会偏慢。但是当前切换到apache httpclient后这样,FeignClient接口就不会延迟加载,因为有外部依赖,@FeignClient
Bean接口需要依赖ApacheHttpClient Bean,就会启动时候初始化。