
Feign概述
Feign作为一个声明式的REST客户端,能让REST调用更加简洁。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。Feign会完全代理http请求,我们只需要像调用方法一样就可以完成服务请求及相关处理。Spring Cloud对Feign进行了封装,使其支持Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
使用Feign调用服务接口
添加项目依赖
<!--添加Feign依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--添加Eureka依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.0.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>1.4.0.RELEASE</version></dependency>
主程序入口
@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients(basePackages = "com.springlcoud.feign.feigndemo.client")public class FeigndemoApplication {public static void main(String[] args) {SpringApplication.run(FeigndemoApplication.class, args);}}
basePackages配置FeignClient包名。
Feign客户端
/*** @FeignClient(value=服务提供者应用名称)*/@FeignClient(value = "service-demo")public interface UserRemoteClient {@GetMapping("/userController/getUserList")String getUserListByServiceName();}
使用@FeignClient注解配置服务提供者,value值为服务提供者应用名。
使用@GetMapping配置服务提供者提供服务方法url。
Feign配置文件
#Feign应用端口server.port=9100#Feign应用名称spring.application.name=feign-demo#服务注册中心集群配置eureka.client.service-url.defaultZone=http://server1:8701/eureka/,http://server2:8702/eureka/
控制器
@RestControllerpublic class UserController {@Autowiredprivate UserRemoteClient userRemoteClient;@GetMapping("/getMessage")public String getMessage(){String resultMessage=userRemoteClient.getUserListByServiceName();System.out.println("调用结果——"+resultMessage);return resultMessage;}}
自定义Feign配置
日志配置
有时候我们碰到bug,如服务提供接口调用失败等,或者想查看接口调用性能,需要配置Feign日志,以此让Feign把操作日志进行输出。
Feign日志配置
@Configurationpublic class FeignLoggerConfiguration {@BeanLogger.Level feignLoggerLevel(){return Logger.Level.FULL;//完整请求信息}}
日志级别
public static enum Level {NONE,//不输出日志BASIC,//只输出请求方法的URL和响应的状态码以及接口执行的时间HEADERS,//BASIC和请求头信息输出FULL;//输出完整的请求信息private Level() {}}
Feign客户端
@FeignClient(value = "service-demo",configuration = FeignLoggerConfiguration.class)public interface UserRemoteClient {@GetMapping("/userController/getUserList")String getUserListByServiceName();}
@FeignClient value为服务提供者应用名,configuration为Feign日志配置类。
配置文件配置Feign日志级别
logging.level.com.springlcoud.feign.feigndemo.client.UserRemoteClient=DEBUG
配置方式为logging.level.Feign客户端完全类名=日志级别(枚举值)
契约配置
SpringCloud在Feign的基础上做了扩展,可以让Feign支持SpringMVC注解进行调用。想要在SpringCloud中使用Feign原生注解定义客户端,需要提供默认契约配置。
@Configurationpublic class FeignContractConfiguration {@Beanpublic Contract feignContract(){return new feign.Contract.Default();}}
进行了默认契约配置,Feign无法使用SpringMVC注解方式进行服务调用,需要使用Feign原生方式。
Basic认证配置
@Configurationpublic class FeignBasicAuthConfiguration {/*** 根据用户名和密码进行基础认证* @return*/@Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor(){return new BasicAuthRequestInterceptor(userName,passWord);}}
自定义认证
public class CustomizeFeignBasicAuthRequestInterceptor implements RequestInterceptor {/*** 业务逻辑* @param requestTemplate*/@Overridepublic void apply(RequestTemplate requestTemplate) {}}@Configurationpublic class CustomizeFeignConfiguration {@Beanpublic CustomizeFeignBasicAuthRequestInterceptor customizeFeignBasicAuthRequestInterceptor(){return new CustomizeFeignBasicAuthRequestInterceptor();}}
超时时间配置
/*** Feign超时时间配置*/@Configurationpublic class OptionsConfiguration {/*** 超时时间配置* @param connectTimeoutMillis:连接超时时间* @param readTimeoutMillis :读取超时时间* @return*/@Beanpublic Request.Options options(){return new Request.Options(connectTimeoutMillis,readTimeoutMillis);}}
重试配置
/*** Feign重试配置*/@Configurationpublic class FeignRetryerConfiguration {@Beanpublic Retryer getDefaultRetryer(){return new Retryer.Default();}@Beanpublic Retryer getCustomizeRetryer(){/*** @param period:当前请求时间间隔(单位毫秒)* @param maxPeriod:当前请求最大时间间隔(单位毫秒)* @param maxAttempts:最多请求次数(包含第一次)*/return new Retryer.Default(period,maxPeriod,maxAttempts);}}
客户端组件配置
Feign默认使用JDK原生URLConnection发送HTTP请求,我们可以使用别的组件替换URLConnection,比如HttpClient,OKHttp。
添加OKHttp依赖:
<!--使用okhttp--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId></dependency>
#feign使用okhttpfeign.httpclient.enabled=falsefeign.okhttp.enabled=true
GZIP压缩配置
开启压缩配置可以有效节约网络资源,提升接口性能,可以通过GZIP配置来压缩数据
#开启请求压缩feign.compression.request.enabled=true#开启响应压缩feign.compression.response.enabled=true#配置压缩的类型feign.compression.request.mime-types=text/xml,application/xml,application/json#配置压缩大小feign.compression.request.min-request-size=2048
配置发送请求组件不是OKHttp3时,压缩配置生效
@Configuration@EnableConfigurationProperties({FeignClientEncodingProperties.class})@ConditionalOnClass({Feign.class})@ConditionalOnBean({Client.class})@ConditionalOnProperty(value = {"feign.compression.response.enabled"},matchIfMissing = false)@ConditionalOnMissingBean(type = {"okhttp3.OkHttpClient"})@AutoConfigureAfter({FeignAutoConfiguration.class})public class FeignAcceptGzipEncodingAutoConfiguration {public FeignAcceptGzipEncodingAutoConfiguration() {}@Beanpublic FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {return new FeignAcceptGzipEncodingInterceptor(properties);}}
@ConditionalOnMissingBean注解表示不包含指定Bean时条件匹配(未启用OKHttp3时进行压缩配置)
编码器与解码器配置
Feign中提供了自定义的编码解码器设置,同时也提供了多种编码解码器实现,我们可以用不同的编码解码器来处理数据的传输。
/*** 自定义解码器*/public class CustomizeDecoder implements Decoder {/*** 解码方法* @param response* @param type* @return* @throws IOException* @throws DecodeException* @throws FeignException*/@Overridepublic Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {return null;}}
/*** 自定义编码器*/public class CustomizeEncoder implements Encoder {/*** 编码方法* @param o* @param type* @param requestTemplate* @throws EncodeException*/@Overridepublic void encode(Object o, Type type, RequestTemplate requestTemplate) throws EncodeException {}}
配置文件方式配置Feign
#修改Feign全局默认配置名称feign.client.default-config=feign-config#配置链接超时时间(单位毫秒)feign.client.config.feign-config.connect-timeout=5000#配置读取超时时间(单位毫秒)feign.client.config.feign-config.read-timeout=5000#配置编码器feign.client.config.feign-config.encoder=com.springlcoud.feign.feigndemo.code.CustomizeEncoder#配置解码器feign.client.config.feign-config.decoder=com.springlcoud.feign.feigndemo.code.CustomizeDecoder#配置契约feign.client.config.feign-config.contract=com.springlcoud.feign.feigndemo.configuration.FeignContractConfiguration#配置重试feign.client.config.feign-config.retryer=com.springlcoud.feign.feigndemo.configuration.FeignRetryerConfiguration
Feign构造多参数请求
@GetMapping("/checkLoginByRequestParam")public String checkLoginByRequestParam(@RequestParam String loginName,String loginPass){String resultMessage="";return resultMessage;}@GetMapping("/checkLoginByRequestParams")public String checkLoginByRequestParams(@RequestParam Map<String,Object> params){String resultMessage="";return resultMessage;}@PostMapping("/checkLoginByPostParams")public String checkLoginByPostParams(@RequestBody Entity entity){String resultMessage="";return resultMessage;}




